我的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”将对象转换为基类来解决该问题,但是找不到任何解决方案。
请告知,将派生对象列表传递给需要基类指向的对象列表的方法的正确方法是什么。
谢谢
如果A相对于其类型参数是协变的,则ATSomething<TDerived>
仅可分配给TSomething<TBase>
(TDerived
从中派生TBase
)。TSomething
类型在逻辑上是协变的先决条件之一是,它只返回其类型参数的实例,而不必接受它们。像只读的迭代器就是这种情况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());
}
如果编译器允许您执行此操作,则类型安全性已经破灭,因为aBase
不是IDerived
。
解决方法取决于您在做什么DoSmth
。如果只迭代bases
,则应该接受实际上是协变的可迭代接口,即IEnumerable<IBase>
:
public static void DoSmth(IEnumerable<IBase> bases) { ... }
如果您确实确实需要IList
接口支持的操作,那么除了将您现有的更改derivedObjs
为IList<IBase>
或使用Cast
和创建一个新列表外,它就无济于事了ToList
:
MyClass.DoSmth(derivedObjs.Cast<IBase>().ToList());
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句