I'm trying to create a method which returns a list of whichever type the user wants. To do this I'm using generics, which I'm not too familiar with so this question may be obvious. The problem is that this code doesn't work and throws the error message Cannot convert type Systems.Collections.Generic.List<CatalogueLibrary.Categories.Brand> to Systems.Collection.Generic.List<T>
private List<T> ConvertToList<T>(Category cat)
{
switch (cat)
{
case Category.Brands:
return (List<T>)collection.Brands.ToList<Brand>();
}
...
}
But if I use IList
instead, there are no errors.
private IList<T> ConvertToList<T>(Category cat)
{
switch (cat)
{
case Category.Brands:
return (IList<T>)collection.Brands.ToList<Brand>();
}
...
}
Why can I use IList but not List in this case? collection.Brands returns a BrandCollection
type from a third party library so I don't know how that's created. Could it be that BrandCollection
may derive from IList (just guessing that it does) and so it can be converted to it but not to a normal List?
Since there are no constraints on T
, it can only be converted to object
at compile time. Casts to interface types aren't checked by the compiler since there could theoretically be a new class created which implements IList<object>
and inherits List<Brand>
. However, the cast to List<T>
will fail since it is known that there cannot be a class created which inherits both List<object>
and List<Brand>
. However, in your case, you know what the type T
is through your switch
statement and wish to force the cast. To do this, cast through object
first as follows:
private List<T> ConvertToList<T>(Category cat)
{
switch (cat)
{
case Category.Brands:
return (List<T>)(object)collection.Brands.ToList<Brand>();
}
}
The bigger design problem here, though, is that generics are not the best choice when you have a discrete list of known types for T
. Generics are better when T
can either be anything, or be constrained to a base type or interface. Here, you'd be better off just writing a separate method for each branch of the switch statement:
private List<Brand> ConvertToBrandList()
{
return collection.Brands.ToList<Brand>();
}
Without this, you have very little type safety. What if someone calls your method with ConvertToList<int>(Category.Brands)
?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With