开发者

How do I convert a List<interface> to List<concrete>?

开发者 https://www.devze.com 2023-03-06 01:33 出处:网络
I have an interface defined as: public interface MyInterface { object foo { get; set; }; } and a class that implements that interface:

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<MyInter开发者_如何学编程face>(
        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.List1[MyInterface]' to type 'System.Collections.Generic.IEnumerable1[MyClass]'.

exception. What am I doing wrong?


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


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>();


You could use Cast<> extension method:

return list.Cast<MyClass>();


I find Automapper very useful for converting interfaces to concrete classes.


It is possible and that's where the generics shine! Here is a simple example:

public interface ICountable
{
     int Count { get; set; }
}

public class PopularName : ICountable
{
    public string Name { get; set; }
    public int Count { get; set; }
}

public class PopularSize : ICountable
{
     public int Size { get; set; }
     public int Count { get; set; }
}

And now you need to declare your method (or your class) generic like this:

public bool HasAnyValue<T>(List<T> countableModel) where T : ICountable
{
    return countableModel.Count > 0;
}
0

精彩评论

暂无评论...
验证码 换一张
取 消