Ambiguous call on an Action<T> where T inherits 2 interfaces having the same method signature

…衆ロ難τιáo~ 提交于 2019-12-25 04:59:20

问题


I have the following code:

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

interface Parent1
{
    void Foo();
}

interface Parent2
{
    void Foo();
}

interface Child : Parent1, Parent2
{

}

However, the compiler tells me that I have an ambiguous call on aFoo.

I tried to do Action<Child> aFoo = (A a) => a.Foo(); but it tells me that I cannot convert lambda expression to delegate type System.Action<Child>

How do I resolve the error of ambiguity?


回答1:


By casting the value of a inside the body of the lambda:

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

Your attempted solution did not work because it did something else entirely: it tried to fit a lambda expression taking a Parent1 into a delegate taking a Child. This is not possible, even though it is possible to fit a delegate taking a Parent1 into a delegate taking a Child:

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

This latter usage is viable because Action<T> is contravariant on the type T.




回答2:


Action<T> is not covariant in its type parameter T, it is contravariant. That means Action<object> can be converted to Action<string>, but not the other way around.

Generally put, Action<T> is a subtype of (read: can be assigned to) Action<U>, only if U is a subtype of T.

In your case, Child is a subclass of Parent, which means Action<Parent> is a subclass of Action<Child>, allowing you to do this:

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

But not:

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

That being said, try casting the lambda parameter instead:

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


来源:https://stackoverflow.com/questions/19931702/ambiguous-call-on-an-actiont-where-t-inherits-2-interfaces-having-the-same-met

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!