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)
?