ric*_*ent 5 c# generics covariance
如果标题没有意义,这是一个例子:
interface IEat { void Eat; }
class Cat : IEat { void Eat { nom(); } }
class Dog : IEat { void Eat { nom(); nom();nom(); } }
class Labrador : Dog { }
Run Code Online (Sandbox Code Playgroud)
我想创建一个像这样的扩展方法:
public static void FeedAll(this IEnumerable<out IEat> hungryAnimals) {
foreach(var animal in hungryAnimals) animal.Eat();
}
Run Code Online (Sandbox Code Playgroud)
所以我可以这样做:
listOfCats.FeedAll();
listOfLabs.FeedAll();
listOfMixedHungryAnimals.FeedAll();
Run Code Online (Sandbox Code Playgroud)
这可能吗?我哪里做错了?
这里真实的应用程序是"Dog"是我的应用程序中的一个主要基类,并且有许多子类,每个子类可能不时有IList,需要对它们执行组操作.必须将它们转换为在它们全部实现的接口List上调用扩展方法将是次优的.
编辑:
我稍微讨论了这个例子.我的实际代码正在使用IList,我希望可以使用基于计数和索引的操作.基于下面的答案,我想我将不得不为需要IList语义的方法寻找另一个方向.
IEnumerable已经是协变的,因此您的扩展方法可以接受 anIEnumerable<IEat>并且IEnumerable<Dog>实例将是有效的参数,使扩展方法适用于这些类型的变量。
如果接口的定义未指定通用参数是协变/逆变,那么扩展方法将无法执行任何操作来允许该参数是协变的。如果您使用的List是不变的 a,则您的扩展方法无法执行任何操作来允许使用协方差。