协变和逆变混淆
Covariance and Contravariance Confusion
我对 contravariant/covariance 如何使用 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: The best overloaded method match for [...] has some invalid arguments
我不太清楚为什么。另外,正确的方法是什么?
在我的真实场景中,我使用了一个基本接口,而不是在具体实例中传递对象。
谢谢!
Action
s 和 Func
s 在它们的参数类型上是逆变的——这意味着如果 U
是 T
的子类型。在您的情况下,object
是 string
的超类型,因此赋值无效。
Action<in T>
是 逆变,这意味着您可以将 "bigger" 类型传递给该方法。因为 string
比 object
更小(更具体或派生),所以会出现编译时错误。如果您反转您的示例,并创建一个 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");
}
我对 contravariant/covariance 如何使用 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: The best overloaded method match for [...] has some invalid arguments
我不太清楚为什么。另外,正确的方法是什么?
在我的真实场景中,我使用了一个基本接口,而不是在具体实例中传递对象。
谢谢!
Action
s 和 Func
s 在它们的参数类型上是逆变的——这意味着如果 U
是 T
的子类型。在您的情况下,object
是 string
的超类型,因此赋值无效。
Action<in T>
是 逆变,这意味着您可以将 "bigger" 类型传递给该方法。因为 string
比 object
更小(更具体或派生),所以会出现编译时错误。如果您反转您的示例,并创建一个 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");
}