我现在不同意 SeanVDH 的回答。他说:“从语言上讲,这在参数与返回的意义上似乎是合乎逻辑的——因此前进或后退的方向是关于进入或离开函数的”。
相反,我认为这是来自这里的答案:
协方差保留了赋值兼容性,而逆变则相反。协变是变宽的转换,逆变是变窄的转换。
当您实例化一个委托时,您可以为其分配一个具有比委托中指定的返回类型更多的
派生返回类型(协方差)的方法。您还可以分配一个方法,其参数类型的
派生程度低于委托中的参数类型(逆变)。强调添加
例子:
static object GetObject() { return null; }
static void SetObject(object obj) { }
static string GetString() { return ""; }
static void SetString(string str) { }
static void Main()
{
// Covariance. A delegate specifies a return type as object,
// but I can assign a method that returns a string.
Func<object> del = GetString;
// Contravariance. A delegate specifies a parameter type as string,
// but I can assign a method that takes an object.
Action<string> del2 = SetObject;
// But implicit conversion between generic delegates is not supported until C# 4.0.
Func<string> del3 = GetString;
Func<object> del4 = del3; // Compiler error here until C# 4.0.
}
这种认识是阅读 Eric Lippert 的文章、Jon Skeet 的书C# In Depth中快速通道代表章节的协变和逆变部分以及上面引用引文的链接的结果。