Im new to C# however im running into an issue when trying to pass the TableOne
type class into a method and use within the method itself.
Class:
public class TableOne
{
public List<string> CaseID { get; set; }
public List<string> Owner { get; set; }
public List<string> Assignee { get; set; }
public List<string> Comments { get; set; }
}
Method:
public static string ComposeHtmlTable<T>(Type classType, IList<T> table)
{
List<classType> test = table.Cast<classType>().ToList();
Console.WriteLine(test[0].CaseID[0]); // trying to access data
return "test";
}
How the method is being called:
ComposeHtmlTable<TableOne>(typeof(TableOne), data.TableOne);
Error im receiving:
'classType' is a variable but is used like a type.
The reason why its imperative that the method uses the parameter type is because there might be multiple types i.e. TableTwo
or TableThree
that I might pass into that method.
Any ideas on how I can tackle this?
TIA
CodePudding user response:
The problem is in this line of code List<classType> test = table.Cast<classType>().ToList();
List<classType>
and Cast<classType>
is invalid syntax.
List<T>
is acceptable.
Type arguments in c# are sent separately to variables.
You've already supplied the type argument T to the generic method.
So use List<T>
and Cast<T>
instead.
Hence passing in classType as a variable is redundant.
Even if you needed to do a switch expression on the the type of elements supplied you can switch on typeof(T)
CodePudding user response:
As @Dai suggest, you could replace the classType
parameter by an generic type parameter:
static List<T1> ComposeHtmlTable<T1,T2>(IList<T2> table)
{
List<T1> test = table.Cast<T1>().ToList();
return test;
}
PS: I changed your method to return the new List, since I presume that's what you wanted to achieve...
And call it like:
ComposeHtmlTable<TableOne,TableOne>(data.TableOne);
If the two generic types will always be the same you can rteduce the method to:
static List<T> ComposeHtmlTable<T>(IList<T> table)
{
return (List<T>) table.Cast<T>().ToList();
}
and call it like:
ComposeHtmlTable<TableOne>(data.TableOne);
CodePudding user response:
Let's have a look at classType
and T
:
public static string ComposeHtmlTable<T>(Type classType, IList<T> table)
{
List<classType> test = table.Cast<classType>().ToList();
Console.WriteLine(test[0].CaseID[0]); // trying to access data
return "test";
}
Can they be some arbitrary types, say T == int
and classType == StringBuider
?
Definitely not. As I can see, both classType
and T
should be inherited from TableOne
.
Let's .net know it:
public static string ComposeHtmlTable<C, T>(IList<T> table)
where C : TableOne
where T : TableOne
{...}
Time to add some details:
- we don't want
IList<T> table
as an argument,IEnumerable<T> table
is enough (and we will be able to pass not only lists, by, say, arrays) - the method is declares as
public
, any input is possible; so we have to validate input arguments - what if
test
is empty (i.e. it doesn't have any items?). We can't obtaintest[0].CaseID[0]
in this case.
public static string ComposeHtmlTable<C, T>(IEnumerable<T> table)
where C : TableOne
where T : TableOne
{
if (table is null)
throw new ArgumentNullException(nameof(table));
List<C> test = table.Cast<C>().ToList();
if (test.Count > 0 && test[0] != null && test[0].CaseID.Count > 0)
Console.WriteLine(test[0].CaseID[0]); // trying to access data
else
Console.WriteLine("test is empty");
return "test";
}