为什么Func和Func有歧义?这让我很沮丧,所以我想我会在这里问,希望C#专家能向我解释一下。为什么此代码会产生错误?类程序{staticvoidMain(string[]args){Foo(X);//错误在这一行}staticStringX(){return"Test";}staticvoidFoo(Funcx){}staticvoidFoo(Funcx){}}有问题的错误:错误1??以下方法或属性之间的调用不明确:'ConsoleApplication1.Program.Foo(System.Func)'和'ConsoleApplication1.Program.Foo(System.Func)'C:UsersmabsterAppDataLocalTemporaryProjectsConsoleApplication1Program.cs1213ConsoleApplication1我使用什么类型并不重要——如果你替换“字符串”在该代码中使用“int”声明,你会得到相同的类型错误。这就像编译器无法区分Func和Func之间的区别。有人可以阐明这一点吗?好的,这是交易。短版:长版:我们有一个重载解决问题。重载决议非常明确。第一步:确定候选集。这很简单。候选人是Foo(Func>)和Foo(Func)。第2步:确定候选集中的哪些成员是适用的。适用成员的每个参数都可转换为每个参数类型。Foo(Func>)适用吗?那么,X是否转换为Func?我们参考规范的第6.6节。这部分规范就是我们语言设计者所说的“很奇怪”。基本上,它表示可以存在转换,但使用该转换是错误的。(我们有这种奇怪情况的充分理由,主要是为了避免未来的变化和避免“先有鸡还是先有蛋”的情况,但在你的情况下我们的行为有点不幸。)基本上,这里的规则是,如果调用上的重载解析X()形式的成功,从X转换为不带参数的委托类型。显然这样的调用会成功,所以有一个转换。使用该转换实际上是错误的,因为返回类型不匹配,但重载决议总是忽略返回类型。所以,从X到Func存在,所以这个重载是一个合适的候选者。显然,出于同样的原因,另一个重载也是合适的候选者。第三步:我们现在有两个适用的候选人。哪个更好”?“更好”是具有更具体类型的那个。如果你有两个适用的候选人,M(动物)和M(长颈鹿),我们选择长颈鹿版本,因为长颈鹿比动物更具体。我们知道长颈鹿更具体,因为每只长颈鹿都是动物,但并非每只动物都是长颈鹿。但在你的情况下,两种类型都不比另一种更具体。两种Func类型之间没有转换......所以两者都不是更好,所以重载解析报告错误。然后C#4编译器有一个错误,它的错误恢复模式无论如何都会选择一个候选者,并报告另一个错误。我不知道为什么会这样。基本上它是说错误恢复就是选择IEnumerable重载,然后注意到方法组转换产生了不可持续的结果;即字符串与IEnumerable不兼容。整个情况相当不幸;更好的是,没有方法组到委托的转换。(或者,产生错误的转换总是比不产生错误的转换更糟糕。)但是,我们现在仍然坚持它。一个有趣的事实:lambda的转换规则会考虑返回类型。如果你说Foo(()=>X())那么我们就做对了。lambda和方法组具有不同的可转换规则这一事实相当不幸。总而言之,在这种情况下,编译器实际上是规范的正确实现,而这种特殊情况是某些可能不幸的规范选择的意外结果。您的代码需要两次“魔法”,一次是从命名方法组转换为委托,一次是执行重载决策。虽然您只有一个名为X的方法,但编译器规则是为存在多个方法的情况而构建的。此外,由于委托不必完全匹配方法签名,因此进一步增加了复杂性。最重要的是,任何给定的方法都可以转换为无限数量的具有相同签名的不同委托类型。你的具体情况看起来很简单,但一般情况下很难,所以语言不允许。如果您手工完成部分工作,您将解决问题。例如Funcd=X;食物);应该编译就好了。以上就是C#学习教程:为什么Func和Func有歧义?如果所有分享的内容对你有用,需要进一步了解C#学习教程,希望大家多多关注。本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处: