How do I convert a List<interface> to List<concrete>?
Solution 1
A List<MyInterface>
cannot be converted to a List<MyClass>
in general, because the first list might contain objects that implement MyInterface
but which aren't actually objects of type MyClass
.
However, since in your case you know how you constructed the list and can be sure that it contains only MyClass
objects, you can do this using Linq:
return list.ConvertAll(o => (MyClass)o);
Solution 2
But a List<MyInterface>
is emphatically not a List<MyClass>
.
Think:
interface IAnimal { }
class Cat : IAnimal { }
class Dog : IAnimal { }
var list = new List<IAnimal> { new Cat(), new Dog() };
Then
var cats = (List<Cat>)list;
Absurd!
Also,
var cats = list.Cast<Cat>();
Absurd!
Further
var cats = list.ConvertAll(x => (Cat)x);
Absurd!
Instead, you could say
var cats = list.OfType<Cat>();
Solution 3
You could use Cast<>
extension method:
return list.Cast<MyClass>();
Related videos on Youtube
acermate433s
Updated on October 01, 2020Comments
-
acermate433s over 3 years
I have an interface defined as:
public interface MyInterface { object foo { get; set; }; }
and a class that implements that interface:
public class MyClass : MyInterface { object foo { get; set; } }
I then create a function that returns a ICollection like so:
public ICollection<MyClass> Classes() { List<MyClass> value; List<MyInterface> list = new List<MyInterface>( new MyInterface[] { new MyClass { ID = 1 }, new MyClass { ID = 1 }, new MyClass { ID = 1 } }); value = new List<MyClass>((IEnumerable<MyClass>) list); return value; }
It would compile but would throw a
Unable to cast object of type 'System.Collections.Generic.List
1[MyInterface]' to type 'System.Collections.Generic.IEnumerable
1[MyClass]'.exception. What am I doing wrong?
-
Ritch Melton about 13 yearsThis will work in .Net 2.0+ and not just LINQ as System.Collections.Generic.List<> supports ConvertAll<T>() directly.
-
JSBձոգչ about 13 yearsThanks, @Ritch. I thought that
ConvertAll
was a Linq method, but I hadn't bothered to check. -
Paolo Moretti about 13 yearsActually, if you are sure that your list contains only
MyClass
objects, you should useEnumerable.Cast<TResult>
Method, and you will get anInvalidCastException
if an element in the sequence cannot be cast toMyClass
. -
acermate433s about 13 yearsI see. I was confused because you can cast an interface to its concrete class. Thanks.
-
AkshayM almost 11 years@PaoloMoretti: Thanks - your method saved a lot of effort. I am using telerik wpf components and in the RadDataFilter the return value is a list of interfaces and I have to do a long foreach with typecasting and string match switches and if else. Now I can use linq. :)
-
aloisdg almost 6 yearsCan you add some details?