泛型委托不能具有反函数返回类型

时间:2018-08-17 19:31:55

标签: c# generics delegates covariance variance

几天前,我开始阅读C#手册。到目前为止,除这一件事外,我已经很清楚地理解了大多数引入的概念:

delegate T TestDelegate<in T>();

这行代码甚至都没有编译,我知道这是因为返回类型不能互变,我只是不明白为什么不能这样。

2 个答案:

答案 0 :(得分:5)

西奥多罗斯的答案是正确的。我想考虑这个问题的一种方式是问自己“假设这是合法的;可能会出什么问题吗?”

delegate T D<in T>(); // Suppose this were legal.
class Animal {}
class Tiger : Animal {}
class Giraffe : Animal {} // Plainly all these are legal.
...
D<Animal> da = () => new Tiger(); // A tiger is an animal, so this must be legal.
D<Giraffe> dg = da; // This is legal because T is declared contravariant in D.
Giraffe g = dg(); // This is legal, because dg returns a giraffe.
// Except that it actually returns a tiger, and now we have a tiger in
// a variable of type giraffe.

除了第一个程序片段外,该程序片段中的每一行显然都是正确的。该程序类型不安全,因此必须是非法的。因此,我们必须得出结论,第一行必须是非法的,而且是非法的。

答案 1 :(得分:2)

如果声明类型变得更通用,则声明类型变得更通用,则泛型参数是相反的,反之亦然。换句话说,委托的一般性与类型参数的相反方向(相反)。

从.NET类层次结构中,我们知道stringobject的一种特殊类型。

但是TestDelegate<T>是承诺返回T的函数的类型。返回object的函数是否是承诺返回string的函数的特殊情况?还是返回string的函数是保证返回object的函数的特殊情况?

显然是后者,这就是T只能是协变变量的原因,这意味着其通用性与声明类型相同。 (或者是不变的,但我们不在这里。)