【问题标题】:delegate contravariance (parameter compatibility)委托逆变(参数兼容性)
【发布时间】:2014-09-16 10:23:04
【问题描述】:

我正在查看C# 5 in a Nutshell 文本,关于委托参数兼容性部分。它说

当您调用一个方法时,您可以提供比该方法的参数具有更多特定类型的参数。这是普通的多态行为。出于完全相同的原因,委托可以具有比其方法目标更具体的参数类型。这称为逆变

这一段直到最后一句才有意义。为什么是逆变,即这里的什么投影是逆变的?

随附的示例如下。

delegate void StringAction (string s);

class Test
{
    static void Main()
    {
        StringAction sa = new StringAction (ActOnObject);
        sa ("hello");
    }

    static void ActOnObject (object o)
    {
        Console.WriteLine (o); // hello
    }
}

【问题讨论】:

    标签: c# c#-5.0


    【解决方案1】:

    object(函数ActionObject的参数)到为委托声明的类型(string)的投影是逆变的。

    这是允许的,因为通过向它传递一个字符串(由于委托签名,您必须这样做),您可以保证您将拥有一个 object(分配的函数采用),所以一切都很好而且安全。

    您知道,在这种情况下,“普通多态性”实际上称为协方差

    请参阅MSDN 了解更多详情。

    【讨论】:

    • 我很困惑,因为当您使用string 参数调用StringAction 时,该参数在到达目标方法时会向上转换为object。所以我们要从stringobject,而不是相反。能详细点吗?
    • @async 你说得对。在这种情况下,它是逆变的,主要是因为它在参数上,不允许协变(特别是在接口上)。它在界面上的方向也更加明显。 msdn.microsoft.com/en-us/library/ms173174.aspx 有另一个与您发布的非常相似的示例。
    【解决方案2】:

    函数类型在参数类型中是逆变的。在您的示例中,类型

    delegate void ObjectAction(object o);
    

    是一个子类型

    delegate void StringAction(string s);
    

    因为ObjectAction 可以在任何使用StringAction 的地方使用,因为如果调用者传入string 参数,则该参数也必须是object 类型。

    objectstring 的超类型,但ObjectActionStringAction 的子类型;子类型的方向相反。这就是为什么它被称为逆变。因为函数子类型的变化与参数子类型的变化方向相反。

    【讨论】:

      猜你喜欢
      • 2013-09-17
      • 1970-01-01
      • 1970-01-01
      • 2014-12-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-24
      相关资源
      最近更新 更多