【问题标题】:What does the 'in' mean in public delegate int Comparison<in T>公共委托 int 比较中的“in”是什么意思<in T>
【发布时间】:2012-05-17 19:46:48
【问题描述】:

msdn 文档 (http://msdn.microsoft.com/en-us/library/tfakywbh.aspx) 报告了比较委托的语法,其中包含关键字“in”。

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

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

【问题讨论】:

    标签: .net generics delegates comparison


    【解决方案1】:

    in 表示泛型参数是逆变的。这意味着,在这种情况下,您可以将 Comparison&lt;Base&gt; 分配给 Comparison&lt;Derived&gt;

    您可以这样做,因为Comparison&lt;Derived&gt; 变量可以接受采用Base 类型参数的方法。当您调用Comparison&lt;Derived&gt; 时,您需要将Derived 变量传递给接受Base 参数的方法,这些变量恰好是有效参数。这意味着将Comparison&lt;Base&gt; 分配给Comparison&lt;Derived&gt; 是有意义的。

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

    记住哪个是哪个的方便方法:

    in 应该只用于只传入的类型。out 只应该用于只传出的类型。

    在这里阅读更多:

    in (Generic Modifier) (C# Reference)

    Covariance and Contravariance (C# and Visual Basic)

    【讨论】:

      【解决方案2】:

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

      它将参数指定为contravariant

      【讨论】:

        【解决方案3】:

        这个委托是逆变的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

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

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

        方差不是一个简单的话题,我无法将我的解释与 Eric Lippert 的 series of blog articles 进行比较。虽然它是从 2007 年开始的,他在那里用将来时谈到了 .NET4 C#,但它仍然是一本非常好的读物。

        【讨论】:

          【解决方案4】:

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

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

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2020-02-23
            • 2016-10-29
            • 2018-04-17
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2016-03-09
            相关资源
            最近更新 更多