我的界面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”将对象转换为基类来解决,但找不到任何解决方案。
请告知,将派生对象列表传递给需要基类指向的对象列表的方法的正确方法是什么。
由于
答案 0 :(得分:0)
TSomething<TDerived>
仅可分配给TSomething<TBase>
(其中TDerived
来自TBase
),如果TSomething
为covariant则相对于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
或创建新的操作外,没有任何内容可用。使用ToList
和MyClass.DoSmth(derivedObjs.Cast<IBase>().ToList());
列出
{{1}}