问题
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