【发布时间】:2015-04-17 17:42:59
【问题描述】:
使用 VS2013,在以下示例中,尝试将函数传递给 worker 的构造函数时会出现两个不同的错误,但是具有相同原型的 lambda 函数是可以的。
我做错了什么,如何更改GetA函数的定义以允许它通过?
为了避免因误解类继承的工作原理而导致与听起来相似的问题混淆,我在此示例中有意避免了任何继承。
WorkerA 只能在其构造函数中接受Func<A>。
WorkerAorB 更灵活,可以接受Func<A> 或Func<B>。
WorkerAandB 是最有能力的,可以同时接受Func<A> 和Func<B>(或两者之一)。它最接近我的真实代码。
但是,当管理器中的代码尝试实例化工作人员时,WorkerA 按预期工作,但WorkerAorB 给出错误:
错误 CS0121:以下方法之间的调用不明确或 属性:'WorkerAorB.WorkerAorB(System.Func)' 和 'WorkerAorB.WorkerAorB(System.Func)'
WorkerAandB给了
错误 CS0407:“A ManagerA.GetA()”的返回类型错误
在每种情况下,编译器似乎无法确定在传递对实际函数的引用而不是 lambda 或现有 Func<A> 变量的引用时使用哪个重载,并且在 WorkerAandB 情况下它明确地选择了 WRONG 重载,并给出了有关传递函数的返回类型的错误。
class A { }
class B { }
class WorkerA
{
public WorkerA(Func<A> funcA) { }
}
class WorkerAorB
{
public WorkerAorB(Func<A> funcA) { }
public WorkerAorB(Func<B> funcB) { }
}
class WorkerAandB
{
public WorkerAandB(Func<A> funcA, Func<B> funcB = null) { }
public WorkerAandB(Func<B> funcB) { }
}
class ManagerA
{
A GetA() { return new A(); }
static A GetAstatic() { return new A(); }
Func<A> GetAfunc = GetAstatic;
ManagerA()
{
new WorkerA(() => new A()); // ok
new WorkerA(GetA); // ok
new WorkerA(GetAstatic); // ok
new WorkerAorB(() => new A()); // ok
new WorkerAorB(() => new B()); // ok
new WorkerAorB(GetA); // error CS0121
new WorkerAorB(GetAstatic); // error CS0121
new WorkerAorB(() => GetA()); // ok
new WorkerAorB(GetAfunc); // ok
new WorkerAandB(() => new A()); // ok
new WorkerAandB(GetA); // error CS0407
new WorkerAandB(GetAstatic); // error CS0407
new WorkerAandB(GetA, null); // ok
new WorkerAandB(GetAstatic, null); // ok
new WorkerAandB(GetAfunc); // ok
}
}
// class ManagerB or ManagerAandB left as an exercise to the reader!
能否以某种方式修改 GetA 或 GetAstatic 函数以帮助编译器识别要使用的正确重载,或者在此上下文中仅允许使用 lambda 和/或显式声明的委托?
更新:我在示例中省略了一些信息。在真实 问题,
A和B类实际上是相关的。class B : A { }此外,在进一步反映实际问题时,调用
public WorkerAandB(Func<B> funcB) { }喜欢
new WorkerAandB(GetB)实际上等价于
new WorkerAandB(GetB, GetB)所以对于真正的问题,我已经做了相当于删除 示例问题中的第二个构造函数,因为事实证明重载是多余的。
与此同时,我已经接受了实际上具有潜力的答案 问题的解决方案(尽管我忽略了一个明显的问题 在最初的问题中),即使它不是我最终使用的。
【问题讨论】:
-
让我们希望@EricLippert 会出现,或者有C#规范的人出现:)
-
可能与 Eric 和 Jon 的答案重复 stackoverflow.com/Questions/2057146/…。
-
我当然希望有人
casts对这个问题有所了解
标签: c# lambda overload-resolution member-functions