1

msdn 文档 ( http://msdn.microsoft.com/en-us/library/tfakywbh.aspx ) 报告了比较德尔门的语法,看起来像关键字“in”。

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

“in”有什么实际意义吗?那里可能会出现其他关键字吗?

4

4 回答 4

5

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(通用修饰符)(C# 参考)

协变和逆变(C# 和 Visual Basic)

于 2012-05-17T19:50:14.457 回答
2

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

它将参数指定为逆变器

于 2012-05-17T19:51:11.633 回答
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预期提供 (input) 的委托指针应该是合法的TextBox。毕竟TextBox适合Control。_

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

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

方差不是一个简单的主题,我无法将我的解释与 Eric Lippert 的系列博客文章进行比较。尽管它是从 2007 年开始的,并且他在那里谈到了将来时的 .NET4 C#,但它仍然是一本非常好的读物。

于 2012-05-17T22:05:14.510 回答
0

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

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

于 2012-05-17T23:11:47.353 回答