与以前不同的是,这一次,地点并不重要.
位置does很重要!它完美地汇编了以下内容:
public interface ICovariant<out T>
{
public void AcceptAction(Action<T> action);
}
Action
中的逆变量类型参数所做的是,它使其相应的类型参数具有您放置它的位置的opposite位置-如果它最初在输入位置,它现在在输出位置,如果它最初在输出位置,它现在在输入位置.
"Contra-"的意思是"相反的",所以很容易记住这种行为:d尽管这种特殊的行为可能不是"反变异"这个名字的由来.Eric Lippert's answer here解释了它为什么叫这个名字.
因此,这也进行了编译(T
的位置被"翻转"了两次,因此它回到了输出位置):
public Action<Action<T>> ReturnsNestedAction();
如果你只是想一想你实际上是如何callReturnAction
的,你应该能够直观地说服自己,确实,T
in ReturnAction
is处于输入位置:
Action<T> action = someICovariant.ReturnAction();
action(someT); // I am *inputting* an instance of T here!
同样,您可以对AcceptAction
执行相同的操作,并看到T
确实位于那里的输出位置:
someICovariant.AcceptAction(t => {
Console.WriteLine(t);
});
/*
Imagine the implementation of AcceptAction invoking its parameter at some point.
That is analogous to AcceptAction *returning* some instance of T and we print it out
The difference being that instead of "return someT;",
AcceptAction would do "action(someT);", but the fact it is producing an instance of T
doesn't change
*/
如果您对如何在技术术语中指定这一点感兴趣,您可以阅读this section of the language specification.
另请参阅这related question条关于声明逆变量类型参数时的类似"翻转位置"行为.