协方差和逆变混淆

时间:2015-05-27 14:54:35

标签: c# .net covariance contravariance

我对逆变/协方差如何与C#一起工作感到困惑。我有以下伪代码

public static void Main()
{
    Action<string> action = e => Console.WriteLine(e);
    Execute(action);
}

private static void Execute(Action<object> action)
{
    action("hello world");
}

抛出

  

CS1502:[...]的最佳重载方法匹配有一些无效的参数

我不确定为什么。还有,这样做的正确方法是什么?

在我的真实场景中,我有一个基本接口,而不是在具体实例中传递对象。

谢谢!

2 个答案:

答案 0 :(得分:5)

Action<in T>逆变,这意味着您可以将“更大”类型传递给方法。因为stringobject更小(更具体或派生),所以会出现编译时错误。如果您颠倒了示例,并创建了Action<object>而不是Action<string>,那么您的方法将会编译:

public static void Main()
{
    Action<object> action = e => Console.WriteLine(e);
    Execute(action);
}

private static void Execute(Action<string> action)
{
    action("hello world");
}

答案 1 :(得分:3)

ActionFunc在参数类型中是逆变的 - 这意味着如果Action<T>Action<U>,您只能将U分配给T object的子类型。在您的情况下,string[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] internal static global::System.Resources.ResourceManager ResourceManager { get { if (object.ReferenceEquals(resourceMan, null)) { global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("XYZAssembly.Properties.Resources", typeof(Resources).Assembly); resourceMan = temp; } return resourceMan; } } 的超类型,因此分配无效。