不能通过基接口使用类列表

时间:2015-05-17 00:54:29

标签: c# .net linq polymorphism

我的界面IDerived继承自IBase:

public IDerived : IBase { ... }

我有需要IList的方法:

public MyClass
{
    public static void DoSmth(IList<IBase> bases)
    { ... }
}

但是尝试传递派生对象列表:

IList<IDerived> derivedObjs = ...;
MyClass.DoSmth(derivedObjs);

导致错误:

Argument type 'System.Collections.Generic.IList<IDerived> is not assignable to parameter type 'System.Collections.Generic.IList<IBase>'

我可以像这样实现“愚蠢”:

MyClass.DoSmth(derivedObjs.Select(d=>d as IBase).ToList());

但这听起来......不专业。

我记得几年前我正在与类似的问题作斗争,并且应该通过允许“DoSmth”或“MyClass”将对象转换为基类来解决,但找不到任何解决方案。

请告知,将派生对象列表传递给需要基类指向的对象列表的方法的正确方法是什么。

由于

1 个答案:

答案 0 :(得分:0)

TSomething<TDerived>仅可分配给TSomething<TBase>(其中TDerived来自TBase),如果TSomethingcovariant则相对于IEnumerable<T>它的类型参数。

类型具有逻辑协变性的前提条件之一是它只返回其类型参数的实例,而不必接受它们。对于IList<T>之类的只读迭代,情况就是这种情况,但是Add的情况是,它必须接受class Base: IBase { } class Derived: IDerived { } ... MyClass.DoSmth(new List<IDerived>()); ... public static void DoSmth(IList<IBase> bases) { bases.Add(new Base()); } 等方法中类型参数类型的引用。 {1}}。

例如,考虑以下情况:

Base

如果编译器允许您这样做,那么您已经破坏了类型安全性,因为IDerived不是DoSmth

此处的修复程序取决于您在bases中执行的操作。如果您只是在IEnumerable<IBase>上进行迭代,则应接受实际 协变的可迭代接口,即public static void DoSmth(IEnumerable<IBase> bases) { ... }

IList

如果您确实需要derivedObjs界面支持的操作,那么除了将现有的IList<IBase>更改为Cast或创建新的操作外,没有任何内容可用。使用ToListMyClass.DoSmth(derivedObjs.Cast<IBase>().ToList()); 列出

{{1}}
相关问题