Gra*_*ith 42 .net c# invariants covariance contravariance
有人能为我提供简单的C#例子,包括协方差,逆变,不变性和反不变性(如果存在这种情况).
到目前为止我见过的所有样品都只是投入一些物体System.Object
.
Eri*_*ert 89
有人能为我提供简单的C#例子,包括协方差,逆变,不变性和反不变性(如果存在这种情况).
我不知道"反不变"是什么意思.其余的很容易.
这是协方差的一个例子:
void FeedTheAnimals(IEnumerable<Animal> animals)
{
foreach(Animal animal in animals)
animal.Feed();
}
...
List<Giraffe> giraffes = ...;
FeedTheAnimals(giraffes);
Run Code Online (Sandbox Code Playgroud)
该IEnumerable<T>
接口是协变.事实上,长颈鹿可以转换为动物意味着IEnumerable<Giraffe>
可转换为IEnumerable<Animal>
.由于List<Giraffe>
工具IEnumerable<Giraffe>
此代码成功地C#4; 它会在C#3中失败,因为协方差IEnumerable<T>
在C#3中不起作用.
这应该是有道理的.一系列长颈鹿可被视为动物序列.
以下是逆变的一个例子:
void DoSomethingToAFrog(Action<Frog> action, Frog frog)
{
action(frog);
}
...
Action<Animal> feed = animal=>{animal.Feed();}
DoSomethingToAFrog(feed, new Frog());
Run Code Online (Sandbox Code Playgroud)
该Action<T>
委托是逆变的.Frog可转换为Animal的事实意味着Action<Animal>
可转换为Action<Frog>
.注意这种关系是如何与协变方向相反的方向 ; 这就是为什么它是"对抗"的变种.由于可转换性,此代码成功; 它会在C#3中失败.
这应该是有道理的.动作可以采取任何动物; 我们需要一个可以接受任何青蛙的动作,并且可以采取任何动物的动作当然也可以采取任何青蛙.
不变性的一个例子:
void ReadAndWrite(IList<Mammal> mammals)
{
Mammal mammal = mammals[0];
mammals[0] = new Tiger();
}
Run Code Online (Sandbox Code Playgroud)
我们可以传递IList<Giraffe>
给这件事吗?不,因为有人打算把老虎写进去,老虎不能列入长颈鹿名单.我们可以IList<Animal>
传入这个东西吗?不,因为我们将从中读取一个哺乳动物,动物列表中可能包含一个青蛙. IList<T>
是不变的.它只能用于它实际的用途.
有关此功能设计的其他一些想法,请参阅我的系列文章,了解我们如何设计和构建它.
http://blogs.msdn.com/b/ericlippert/archive/tags/covariance+and+contravariance/
归档时间: |
|
查看次数: |
11309 次 |
最近记录: |