协变和逆变混淆

3
我对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 [...],但我不确定具体原因。请问正确的解决方法是什么?

在我的实际情况中,我使用了一个基础接口来代替传递具体实例的对象。

谢谢!


我已经编辑了您的帖子,包括您提供的异常消息。请重新编辑它,用真实的消息填充 [...] 占位符。 - André Chalella
2个回答

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");
}

我喜欢Action<T>文档中对类型参数T的描述:“此类型参数是逆变的。也就是说,您可以使用指定的类型或任何派生程度更低的类型。” - DavidRR

3

ActionFunc在它们的参数类型上是逆变的 - 这意味着只有当UT的子类型时,才能将Action<T>分配给Action<U>。在您的情况下,objectstring的超类型,因此该赋值是无效的。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接