简体   繁体   English

如何转换列表<interface>列出<concrete> ?

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

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:然后我创建一个函数,它返回一个 ICollection,如下所示:

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]'.无法将“System.Collections.Generic.List 1[MyInterface]' to type 'System.Collections.Generic.IEnumerable对象1[MyInterface]' to type 'System.Collections.Generic.IEnumerable 1[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 . A List<MyInterface>通常不能转换为List<MyClass> ,因为第一个列表可能包含实现MyInterface但实际上不是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:但是,由于在您的情况下,您知道如何构造列表并且可以确定它仅包含MyClass对象,因此您可以使用 Linq 执行此操作:

return list.ConvertAll(o => (MyClass)o);

But a List<MyInterface> is emphatically not a List<MyClass> .但是List<MyInterface>显然不是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>();

您可以使用Cast<>扩展方法:

return list.Cast<MyClass>();

我发现 Automapper 对于将接口转换为具体类非常有用。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM