对Action <t>的不明确调用,其中T继承了具有相同方法签名的2个接口</t>

时间:2013-11-12 14:22:26

标签: c# interface delegates expression-trees multiple-inheritance

我有以下代码:

public class MyClass
{
    public void MyMethod()
    {
        Action<Child> aFoo = a => a.Foo();
    }
}

interface Parent1
{
    void Foo();
}

interface Parent2
{
    void Foo();
}

interface Child : Parent1, Parent2
{

}

然而,编译器告诉我,aFoo上的呼叫模糊不清。

我尝试Action<Child> aFoo = (A a) => a.Foo();,但它告诉我,我无法将lambda表达式转换为委托类型System.Action<Child>

如何解决歧义错误?

2 个答案:

答案 0 :(得分:4)

通过在lambda的主体内部转换a的值:

Action<Child> aFoo = a => ((Parent1)a).Foo();

您尝试的解决方案无法正常运行,因为它完全做了其他事情:它尝试使用 lambda表达式Parent1带入委托中取一个{ {1}}。这是不可能的,即使 可能适合委托Child带入代理人Parent1

Child

后一种用法是可行的,因为Action<Child> aFoo = (Action<Parent1>)(a => a.Foo()); 在类型T上是逆变的。

答案 1 :(得分:2)

Action<T>在其类型参数T中不是协变的,它是逆变的。 这意味着Action<object>可以转换为Action<string>,但不能相反。

通常情况下,Action<T>是{read:可以分配给Action<U>的子类型,仅当UT的子类型时才会这样。

在您的情况下,ChildParent的子类,这意味着Action<Parent>Action<Child>的子类,允许您这样做:

Action<Child> a = new Action<Parent> (... );

但不是:

Action<Parent> a = new Action<Child>( ... );

话虽如此,请尝试转换lambda参数:

Action<C> aFoo = a => ((A)a).Foo();