Convert List of objects to List of interfaces
Asked Answered
P

3

21

if i have objectA that implements ISomeInterface

why can't i do this:

List<objectA> list = (some list of objectAs . . .)

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

why can't i stick in list into the interfaceList constructor ? Is there any workaround?

Paediatrician answered 4/1, 2010 at 5:42 Comment(0)
T
36

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.

Tachycardia answered 4/1, 2010 at 5:48 Comment(2)
@itowlson, this is what the user is doing in the sample. They didn't specify the Add behavior was a part of the desired solution.Tachycardia
You mean .NET 3.5, not C# 3.5.Hysterogenic
V
10

Easiest & shorter way is:

var interfaceList = list.Cast<ISomeInterface>().ToList()

OR

List<ISomeInterface> interfaceList = list.Cast<ISomeInterface>().ToList()

Both above sample codes are equal and you can use each one you want...

Vicenta answered 31/7, 2015 at 10:41 Comment(2)
The right side with use of ToList() is good idea! But note that using var you hide the real type of the variable and it's not good practice to do this. List<ISomeInterface> interfaceList = list.Cast<ISomeInterface>().ToList(); so i went to use this form as clearest, shortest versionNobleminded
@KovácsEde, according to the point that you mentioned, i added second format of my way to this answer, but both of them are equal. When we use var, in fact we are writing our codes in a shorter format and always we can recognize type of the variable by looking at the right side of =. On the other hand even when we use var, the C# compiler is cleaver enough to recognize the real type of the variable. So if you want shorter syntax use var and recognize the variable type from codes in the right side of = else you can use second format.Vicenta
D
1

This is dealt with in C# 4.0, you cannot do this in C# 3.5 directly. You can create a new list from this list however and use an extension operator or foreach to do it cleanly, albeit slower than a cast to the type which will be provided by covariance contravariance (always get these wrong) in C# 4.

Disavow answered 4/1, 2010 at 5:47 Comment(6)
See my comment to Jared - there's no such thing as C# 3.5.Hysterogenic
Arg, reminds me of the beauracrat in Futurama. Although that said Linq WAS a language change, and was not introduced till C# 3.5, so C# was 2.0 until it was given the linq extensions, WCF was simply a framework upgrade in 3.0.Disavow
@JonSkeet There is now, for 'bout 10 years.Cresting
@Bitterblue: No, there really isn't. There's .NET 3.5, but there's no such thing as C# 3.5. If you can give an example of a feature you think was introduced in C# 3.5, I'll show you the actual version it was introduced.Hysterogenic
I note I hadn't responded to @Disavow before though... LINQ was introduced in C# 3, which was shipped with .NET 3.5. Download the C# 3.0 spec to see that for yourself. I don't think it's particularly bureaucratic to want to distinguish between framework and language version numbers - it helps to make for clearer communication IMO.Hysterogenic
@JonSkeet It was a joke. I know I shouldn't go off-topic and blah. But hey, SO was almost never friendly to me so whatever!Cresting

© 2022 - 2024 — McMap. All rights reserved.