msdn 文档 ( http://msdn.microsoft.com/en-us/library/tfakywbh.aspx ) 报告了比较德尔门的语法,看起来像关键字“in”。
public delegate int Comparison<in T>(
T x,
T y
)
“in”有什么实际意义吗?那里可能会出现其他关键字吗?
msdn 文档 ( http://msdn.microsoft.com/en-us/library/tfakywbh.aspx ) 报告了比较德尔门的语法,看起来像关键字“in”。
public delegate int Comparison<in T>(
T x,
T y
)
“in”有什么实际意义吗?那里可能会出现其他关键字吗?
in
表示泛型参数是逆变的。这意味着,在这种情况下,您可以将 a 分配Comparison<Base>
给 a Comparison<Derived>
。
您可以这样做,因为Comparison<Derived>
变量可以接受采用Base
类型参数的方法。当您调用 aComparison<Derived>
时,您需要将Derived
变量传递给接受参数的方法,这些变量恰好是有效Base
参数。这意味着将 a 分配给 a 是有意义Comparison<Base>
的Comparison<Derived>
。
的反义词in
是(自然)out
。这意味着参数是协变的,并且可以将泛型分配给Derived
泛型Base
。例如,这将用于指定委托的返回类型。
一种方便的方法来记住哪个是哪个:
in
应该只用于只传入的类型。out
只应该用于只传出的类型。
在这里阅读更多:
此委托是逆变的,in
关键字表示T
仅用作输入类型。逆变的意思是定义了这个委托类型:
public delegate int Comparison<in T>(T x, T y);
你可以这样做:
Comparison<Control> comp1 = (a, b) => (a.Width*a.Height - b.Width*b.Height);
Comparison<TextBox> comp2 = comp1;
如果没有in
关键字,它会抱怨第二行说它不能将一种类型转换为另一种类型。但是因为我们知道它T
仅用于输入,所以将处理的委托分配给Control
预期提供 (input) 的委托指针应该是合法的TextBox
。毕竟TextBox
会适合Control
。_
另一方面存在协方差。它还依赖于适合其他类型的类型,但这次是为了结果(在这种情况下是委托的结果)。
统称为方差的协变和逆变不仅适用于泛型委托,也适用于泛型类和接口。Variance 也适用于非泛型委托和数组,但以隐式方式,因此不需要特殊关键字 - 它可以正常工作。
方差不是一个简单的主题,我无法将我的解释与 Eric Lippert 的系列博客文章进行比较。尽管它是从 2007 年开始的,并且他在那里谈到了将来时的 .NET4 C#,但它仍然是一本非常好的读物。
将“in”声明应用于类型参数意味着编译器将允许一个例程,该例程期望一个接受派生类型对象的委托,如果给定一个接受基类型对象的委托,它将很高兴。例如,从编译时的角度来看,如果给定一个可以处理所有 Animals 的委托,一个期望委托处理 Zebras 的例程将非常高兴。
然而,需要注意的重要一点是,由于不幸的实现方式MulticastDelegate
,Delegate.Combine
尝试将协变委托与任何Delegate.Combine
可能导致运行时崩溃的代码一起使用,因为Delegate.Combine
需要两个完全相同类型的委托. 如果有一个通用方法来组合不同类型的委托,那就太好了(方法本身必须被赋予一个可以被两个委托都满足的类型),尽管这种组合的产品不能是MulticastDelegate
(因为实例该类的仅保存一种委托类型的类型信息)。然而,到目前为止,还没有这样的方法。