我有以下代码:
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>
如何解决歧义错误?
答案 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>
的子类型,仅当U
是T
的子类型时才会这样。
在您的情况下,Child
是Parent
的子类,这意味着Action<Parent>
是Action<Child>
的子类,允许您这样做:
Action<Child> a = new Action<Parent> (... );
但不是:
Action<Parent> a = new Action<Child>( ... );
话虽如此,请尝试转换lambda参数:
Action<C> aFoo = a => ((A)a).Foo();