Covariance and Contra-variance

转载 2012年03月31日 13:38:51
Previous to .NET 4, generic interfaces were invariant. .NET 4 adds an important extension for generic
interfaces and generic delegates with covariance and contra-variance. Covariance and contra-variance
are about the conversion of types with argument and return types. For example, can you pass a
Rectangle to a method that requests a Shape? Let’s get into examples to see the advantages of these
extensions.
With .NET, parameter types are covariant. Assume you have the classes Shape and Rectangle, and
Rectangle derives from the Shape base class. The Display() method is declared to accept an object of the
Shape type as its parameter:
public void Display(Shape o) { }
Now you can pass any object that derives from the Shape base class. Because Rectangle derives
from Shape, a Rectangle fulfills all the requirements of a Shape and the compiler accepts this

method call:

Rectangle r = new Rectangle { Width= 5, Height=2.5};

Display(r);


Return types of methods are contra - variant. When a method returns a Shape it is not possible to assign it to
a Rectangle because a Shape is not necessarily always a Rectangle . The opposite is possible. If a method
returns a Rectangle as the GetRectangle() method,
public Rectangle GetRectangle();
the result can be assigned to a Shape .
Shape s = GetRectangle();
Before version 4 of the .NET Framework, this behavior was not possible with generics. With C# 4, the
language is extended to support covariance and contra - variance with generic interfaces and generic
delegates. Let ’ s start by defi ning a Shape base class and a Rectangle class:


public class Shape
{
public double Width { get; set; }
public double Height { get; set; }
public override string ToString()
{
return String.Format("Width: {0}, Height: {1}", Width, Height);
}
}

public class Rectangle: Shape
{
}


Covariance with generic interfaces
A generic interface is covariant if the generic type is annotated with the out keyword. This also means that
type T is allowed only with return types. The interface IIndex is covariant with type T and returns this type
from a read - only indexer:
public interface IIndex < out T >
{
T this[int index] { get; }
int Count { get; }
}


The RectangleCollection.GetRectangles() method returns a RectangleCollection that implements
the IIndex<Rectangle> interface, so you can assign the return value to a variable rectangle of the
IIndex<Rectangle> type. Because the interface is covariant, it is also possible to assign the returned value
to a variable of IIndex<Shape>. Shape does not need anything more than a Rectangle has to offer. Using
the shapes variable, the indexer from the interface and the Count property are used within the for loop:
static void Main()
{
IIndex<Rectangle> rectangles = RectangleCollection.GetRectangles();
IIndex<Shape> shapes = rectangles;
for (int i = 0; i < shapes.Count; i++)
{
Console.WriteLine(shapes[i]);
}
}


Contra-Variance with generic interfaces
A generic interface is contra-variant if the generic type is annotated with the in keyword. This way the
interface is only allowed to use generic type T as input to its methods:

public interface IDisplay<in T>
{
void Show(T item);
}


The ShapeDisplay class implements IDisplay<Shape> and uses a Shape object as an input parameter:
public class ShapeDisplay: IDisplay<Shape>
{
public void Show(Shape s)
{
Console.WriteLine("{0} Width: {1}, Height: {2}", s.GetType().Name,
s.Width, s.Height);
}
}

Creating a new instance of ShapeDisplay returns IDisplay<Shape>, which is assigned to the
shapeDisplay variable. Because IDisplay<T> is contra-variant, it is possible to assign the result to
IDisplay<Rectangle> where Rectangle derives from Shape. This time the methods of the interface only
define the generic type as input, and Rectangle fulfills all the requirements of a Shape:
static void Main()
{
//...
IDisplay<Shape> shapeDisplay = new ShapeDisplay();
IDisplay<Rectangle> rectangleDisplay = shapeDisplay;
rectangleDisplay.Show(rectangles[0]);
}


相关文章推荐

期望 方差 协方差 协方差矩阵 (Expectation Variance Covariance)

在学习机器学习的算法时经常会碰到随机变量的数字特征,所以在这里做一个简单的总结。 1、         期望(Expectation) 离散: 其中,f(x)为随机变量x的概率函...

Region Covariance: A Fast Descriptor forDetection and Classification算法流程简介

Region Covariance: A Fast DescriptorforDetection and Classification算法流程简介 1.        首先计算图像的特征矩阵 其...

Covariance, Contravariance and Invariance

Have a look at this article for an explanation of Covariance and Contravariance. http://msdn.micros...

Region Covariance: A Fast Descriptor for Detection and Classification算法总结

传统的像素级特征比如颜色、梯度、滤波响应等等它们对光照变化和非刚性运动的描述不够鲁棒,而在像素级特征之上延伸出的直方图表述了一种无参的联合分布,然而随着特征数目的增加,联合分布的表达是呈指数增加的。另...

对协变和逆变的理解(Contravariance and Covariance)

本篇博客转载自https://www.zybuluo.com/zhanjindong/note/34147。 在学习OpenCV过程中遇到了一个错误VS提示了这样一个错误: IntelliSen...

【机器学习(李宏毅)】 三、Bias and Variance

本讲核心问题:Where does the error come from?Review: 更复杂的模型不一定在测试集上有更好的表现 误差由偏差“bias”导致 误差由方差“variance”导致 E...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)