P.B*_*key 9 .net c# polymorphism covariance
.NET 4引入了协方差.我想这很有用.毕竟,MS经历了将其添加到C#语言的所有麻烦.但是,为什么协方差比良好的旧多态更有用呢?
我写这个例子来理解为什么我应该实现Covariance,但我仍然没有得到它.请赐教.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Sample
{
class Demo
{
public delegate void ContraAction<in T>(T a);
public interface IContainer<out T>
{
T GetItem();
void Do(ContraAction<T> action);
}
public class Container<T> : IContainer<T>
{
private T item;
public Container(T item)
{
this.item = item;
}
public T GetItem()
{
return item;
}
public void Do(ContraAction<T> action)
{
action(item);
}
}
public class Shape
{
public void Draw()
{
Console.WriteLine("Shape Drawn");
}
}
public class Circle:Shape
{
public void DrawCircle()
{
Console.WriteLine("Circle Drawn");
}
}
public static void Main()
{
Circle circle = new Circle();
IContainer<Shape> container = new Container<Circle>(circle);
container.Do(s => s.Draw());//calls shape
//Old school polymorphism...how is this not the same thing?
Shape shape = new Circle();
shape.Draw();
}
}
}
Run Code Online (Sandbox Code Playgroud)
JSB*_*ոգչ 10
考虑一个要求IContainer<Shape>
:
public void DrawShape(IContainer<Shape> container>) { /* ... */ }
Run Code Online (Sandbox Code Playgroud)
你有一个Container<Circle>
.如何将容器传递给DrawShape
API?没有协方差,类型Container<Circle>
不可转换为IContainer<Shape>
,要求您重新包装类型或提出其他一些解决方法.
在使用大量通用参数的API中,这不是一个罕见的问题.
协方差比多态性更冷,就像长耳熊比iceskates更冷:它们不是同一个东西.
协方差和逆变(以及不变性和......无所不在......任何人?)处理泛型可以继承的"方向".在你的例子中,你正在做同样的事情,但这不是一个有意义的例子.
举个例子,事实IEnumerable<T>
是out T
.这让我们做这样的事情:
public void PrintToString(IEnumerable<object> things)
{
foreach(var obj in things)
{
Console.WriteLine(obj.ToString());
}
}
public static void Main()
{
List<string> strings = new List<string>() { "one", "two", "three" };
List<MyClass> myClasses = new List<MyClass>();
// add elements to myClasses
PrintToString(strings);
PrintToString(myClasses);
}
Run Code Online (Sandbox Code Playgroud)
在C#的早期版本中,这将是不可能的,因为List<string>
工具IEnumerable
和IEnumerable<string>
,没有 IEnumerable<object>
.然而,因为IEnumerable<T>
就是out T
,我们知道,它现在转让或参数传递任何兼容的IEnumerable<Y>
地方T is Y
或T:Y
.
在某些情况下,通过使函数本身具有通用性并使用泛型类型推断,在许多情况下产生相同的语法,这种事情可以在以前的版本中解决.然而,这并没有解决更大的问题,绝不是100%的解决方法.
归档时间: |
|
查看次数: |
812 次 |
最近记录: |