Cast List<T> to List<Interface>

Cast List T to List Interface

You can't cast it (preserving reference identity) - that would be unsafe. For example:

public interface IFruit {}

public class Apple : IFruit {}
public class Banana : IFruit {}

...

List<Apple> apples = new List<Apple>();
List<IFruit> fruit = apples; // Fortunately not allowed
fruit.Add(new Banana());

// Eek - it's a banana!
Apple apple = apples[0];

Now you can convert a List<Apple> to an IEnumerable<IFruit> in .NET 4 / C# 4 due to covariance, but if you want a List<IFruit> you'd have to create a new list. For example:

// In .NET 4, using the covariance of IEnumerable<T>
List<IFruit> fruit = apples.ToList<IFruit>();

// In .NET 3.5
List<IFruit> fruit = apples.Cast<IFruit>().ToList();

But this is not the same as casting the original list - because now there are two separate lists. This is safe, but you need to understand that changes made to one list won't be seen in the other list. (Modifications to the objects that the lists refer to will be seen, of course.)

How do i convert a List Interface to List Class in c#

You have to create a new list with casted items:

var readers = Ireaders.Cast<ReaderInfo>().ToList();

Or, if there is a possibility to have incompatible IReaderInfo entries and you only want the actual ReaderInfo objects in the result:

var readers = Ireaders.OfType<ReaderInfo>().ToList();

Cast list of interface to list of objects

If you have a List<IThisInterface>, then you cannot cast that list object to List<ThisClass>. Even if all the items inside of the list are ThisClass objects, the list is still a list of IThisInterface objects.

What you need to do is create a new List<ThisClass> list and then populate that with all the items of the original list but cast those to ThisClass first.

Fortunately, that is exactly what the LINQ method Enumerable.Cast<T> does:

List<IThisInterface> list = GetData();

// cast the list to a `ThisClass` list
List<ThisClass> newList = list.Cast<ThisClass>().ToList();

Convert List of objects to List of interfaces

In C# 3.0 + .Net 3.5 and up you can fix this by doing the following

List<ISomeInterface> interfaceList = new List<ISomeInterface>(list.Cast<ISomeInterface>());

The reason why this doesn't work is that the constructor for List<ISomeInterface> in this case takes an IEnumerable<ISomeInterface>. The type of the list variable though is only convertible to IEnumerable<objectA>. Even though objectA may be convertible to ISomeInterface the type IEnumerable<objectA> is not convertible to IEnumerable<ISomeInterface>.

This changes though in C# 4.0 which adds Co and Contravariance support to the language and allows for such conversions.

Casting List of objects to a IList with the interface of the object

As per the documentation:

The as operator explicitly converts the result of an expression to a
given reference or nullable value type. If the conversion is not
possible, the as operator returns null.

In general, generic types don't allow variance of its arguments, meaning you cannot cast to a different type. This is why implements is null and it fails when trying to perform the foreach.

To achieve your intention, you'll have to cast each independent item to IInterfaceInstance, not the whole list.

cast from List MyClass to List Interface

Use an upper bound of Interface for the type: <? extends Interface>.

Here's come compilable code that uses classes from the JDK to illustrate:

public static void myMethod(List<? extends Comparable> struttura) {}

public static void main(String[] args) {
List<Integer> lista = null;
myMethod(lista); // compiles OK
}

How can I convert a List T to a List I Where T implements Interface I?

One option is to use Linq IEnumerable<TResult> Cast<TResult>(this IEnumerable source). It casts the elements of our first collection to the type you want.

https://docs.microsoft.com/en-us/dotnet/api/system.linq.enumerable.cast?view=netframework-4.7.2

List<I> myListOfI;
List<T> myListOfT = myListOfI.Cast<T>().ToList();

In C#, why is this conversion from list of objects to list of interfaces throwing an exception?

Try it the following way:

IEnumerable<List<IMyInterface>> myInterfaceGroups = myObjGroups
.Select(l => l.Select(o => (IMyInterface)o).ToList());

Or if you prefer using the Cast<T>() extension method:

IEnumerable<List<IMyInterface>> myInterfaceGroups = myObjGroups
.Select(l => l.Cast<IMyInterface>().ToList());

EDIT: A bit of explanation

To better understand why did you get the InvalidCastException exception, let's try to decompose your original expression:

IEnumerable<List<IMyInterface>> myInterfaceGroups = 
new List<List<IMyInterface>>(myObjGroups.Cast<List<IMyInterface>>());

This is equivalent to:

IEnumerable<List<IMyInterface>> myObjGroupsAsInterfaceList = myObjGroups
.Cast<List<IMyInterface>>()
.ToList();

IEnumerable<List<IMyInterface>> myInterfaceGroups = new List<List<IMyInterface>>(myObjGroupsAsInterfaceList);

The Cast<T>() extension method just iterates through the items and tries to cast each item to type T. We could replace the functionality of Cast<T>() extension method combined with ToList<T>() with the following snippet:

List<List<IMyInterface>> myObjGroupsAsInterfaceList = new List<List<IMyInterface>>();
foreach (List<MyObj> myObjGroup in myObjGroups)
{
List<IMyInterface> myObjGroupAsInterface = myObjGroup; // Compile error!
myObjGroupsAsInterfaceList.Add(myObjGroupAsInterface);
}

So the root problem is that you cannot assign a List<MyObj> object to a variable of type List<IMyInterface>.

To find more explanation on why the above is not possible, take a look on the following question: C# variance problem: Assigning List<Derived> as List<Base>

How to convert a generic List T to an Interface based List T

Instead of casting like that, try:

allShapes = cubes.Cast<Shape>().ToList();

You need .NET 3.5 for this. I believe the Cast extension method can be found in System.Linq.

Cast interface list to implementation list or vice-versa

Just because A derives from B, doesn't necessarily mean X<A> derives from X<B>.

In fact, List<T> is invariant in its generic type paramater T. This means List<string> isn't a subtype nor a supertype of List<object>, even though string derives from object.

Imagine if your list of interfaces contained instances of type SomeOtherImplementation. How would the cast work?

Instead, you should create a new list and cast each item in your list of interfaces to the concrete type.

List<SomeImplementation> lstOfImplementation =
lstOfInterfaces.Cast<SomeImplementation>()
.ToList();

If you're not sure whether all instances are of type SomeImplementation, you can filter out those who aren't, using OfType<T>.

List<SomeImplementation> lstOfImplementation =
lstOfInterfaces.OfType<SomeImplementation>()
.ToList();

Read also:

  • Covariance and Contravariance
  • Covariance and Contravariance FAQ


Related Topics



Leave a reply



Submit