I've looked at lots of stackoverflow Q&As about ToList and generic constraints, but I haven't found one that explains the "Syntax Error" in the final return below. Why do I have to explicitly Select
and cast
the elements ("B")?
public interface I1
{
}
public class C2 : I1
{
public static List<I1> DowncastListA( List<C2> list )
{
// "A": A concrete class works.
return list == null ? null : list.ToList<I1>();
}
public static List<I1> DowncastListB<T2>( List<T2> list ) where T2 : I1
{
// "B": WORKS, if explicitly Select and Cast each element.
return list == null ? null : list.Select( a => (I1)a ).ToList();
}
public static List<I1> DowncastListC<T2>( List<T2> list ) where T2 : I1
{
// "C": Syntax Error: 'List<T2>' does not contain a definition for 'ToList' and the best extension method overload 'ParallelEnumerable.ToList<I1>(ParallelQuery<I1>)' requires a receiver of type 'ParallelQuery<I1>'
return list == null ? null : list.ToList<I1>();
}
}
Some related Qs:
https://stackoverflow.com/a/1541173/199364
How to Cast List<T> To List<ClassName>
The extension method
IEnumerable<T>.ToList<T>()
doesn't allow to specify a target type.T
is the type of the sourceIEnumerable
(which is implicitly known from the source collection).Instead you can use this:
I.e. you first cast each element (resulting in an
IEnumerable<I1>
), then create a list from that.BTW: you could even make that an extension method to simplify its usage:
As suggested by @AluanHaddad
Note the added constraint
T2 : class
.That answer doesn't require any casting of
list
, becauseIReadOnlyList<T>
is covariant, and list already has members that implement I1. (Could alternatively make the return typeIEnumerable<I1>
, but I needed indexing, so chose to expose a higher interface.)Or as an alternative, if wish to expose the full
List
functionality:Note the added constraint
T2 : class
. This gives enough information forIEnumerable<T2>
(whichList<T2>
implements) to find the implementation of ToList<>`.Now that this works, here is second version above, using C# 6 null conditional: