公共委托中的'in'是什么意思int比较<in t =“”> </in>

时间:2012-05-17 19:46:49

标签: .net generics delegates comparison

msdn docs(http://msdn.microsoft.com/en-us/library/tfakywbh.aspx)使用类似关键字“in”的内容报告Comparison delgate的语法。

public delegate int Comparison<in T>(
    T x,
    T y
)

'in'是否有任何实际意义?是否还有其他可能出现的关键字?

4 个答案:

答案 0 :(得分:5)

in表示通用参数是逆变的。在这种情况下,这意味着您可以将Comparison<Base>分配给Comparison<Derived>

您可以执行此操作,因为Comparison<Derived>变量可以接受采用Base类型参数的方法。当您调用Comparison<Derived>时,您需要将Derived个变量(恰好是有效参数)传递给接受Base参数的方法。这意味着将Comparison<Base>分配给Comparison<Derived>

是有意义的

in的反面是(自然地)out。这意味着参数是协变的,并且可以将Derived泛型分配给Base泛型。例如,这将用于指定委托的返回类型。

一种方便的方法,记住哪个是:

in只应用于仅传入的类型。out应仅用于仅传递的类型。

在这里阅读更多内容:

in (Generic Modifier) (C# Reference)

Covariance and Contravariance (C# and Visual Basic)

答案 1 :(得分:2)

如果您熟悉docs,为什么不使用它们?

它将参数指定为contravariant

答案 2 :(得分:1)

此委托是逆变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的委托分配给预期提供(输入)TextBox的委托指针应该是合法的。毕竟TextBox 适合进入Control

另一方面,协方差。它还依赖于拟合类型到其他类型,但这次是结果(在这种情况下是委托的结果)。

统称为方差的协方差和逆变法不仅适用于泛型委托,也适用于泛型类和接口。方差也适用于非泛型委托和数组,但是以隐式方式,因此不需要特殊的关键字 - 它只是起作用。

方差不是一个容易的主题,我无法将我的解释与Eric Lippert的series of blog articles进行比较。虽然它是从2007年开始的,但他在未来时会谈到.NET4 C#,它仍然是一个非常好的阅读。

答案 3 :(得分:0)

将“in”声明应用于type参数意味着编译器将允许一个例程,如果给定一个接受基类型对象的委托,那么期望派生类型对象的委托会很高兴。例如,如果给定一个可以处理所有动物的委托,那么从编译时的角度来看,期望委托处理Zebras的例程将非常高兴。

然而,需要注意的一件重要事情是,由于实现MulticastDelegateDelegate.Combine的不幸方式,尝试将协变代理与任何将尝试Delegate.Combine的代码一起使用导致运行时崩溃,因为Delegate.Combine需要两个完全相同类型的委托。如果有一个泛型方法来组合不同类型的委托会很好(方法本身必须给出一个可以被两个委托都满足的类型),尽管这种组合的产品不能是{{1 (因为该类的实例只保存一个委托类型的类型信息)。然而,到目前为止,还没有这样的方法。