上的动作暧昧通话 其中T继承具有相同方法签名2个接口(Ambiguous call on an

2019-10-29 20:27发布

我有以下代码:

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>

如何解决歧义的错误?

Answer 1:

通过铸造价值a拉姆达的身体里面:

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

你尝试的解决方案没有奏效,因为它没有别的东西完全:它试图以适应lambda表达式采取Parent1代表采取了Child 。 这是不可能的,即使可能适合委托采取Parent1为代表服用Child

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

因为这后一种用法是可行的Action<T>上的类型T.逆变



Answer 2:

Action<T>并不将其类型参数协变T ,它是逆变。 这意味着Action<object>可以被转换为Action<string>周围,而不是其他方式。

通常地说, Action<T>是(读:可以分配到)的一个亚型Action<U>仅当U是的子类型T

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

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

但不是:

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

话虽这么说,尝试铸造拉姆达参数,而不是:

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


文章来源: Ambiguous call on an Action where T inherits 2 interfaces having the same method signature