'委托'System.Action'不需要0个参数。' 这是一个C#编译器错误(lambdas +两个项目)?
考虑下面的代码。 看起来像完全有效的C#代码吧?
//Project B using System; public delegate void ActionSurrogate(Action addEvent); //public delegate void ActionSurrogate2(); // Using ActionSurrogate2 instead of System.Action results in the same error // Using a dummy parameter (Action<double, int>) results in the same error // Project A public static class Class1 { public static void ThisWontCompile() { ActionSurrogate b = (a) => { a(); // Error given here }; } }
我得到一个编译器错误'委托'行动'不接受0参数。 在指定的位置使用(Microsoft)C#4.0编译器。 请注意,您必须在不同的项目中声明ActionSurrogate以显示此错误。
它变得更有趣:
// Project A, File 1 public static class Class1 { public static void ThisWontCompile() { ActionSurrogate b = (a) => { a(); /* Error given here */ }; ActionSurrogate c = (a) => { a(); /* Error given here too */ }; Action d = () => { }; ActionSurrogate c = (a) => { a(); /* No error is given here */ }; } }
我偶然发现了一个C#编译器错误吗?
请注意,这是一个非常喜欢使用lambdas的人很多恼人的错误,正在尝试创build一个数据结构库以供将来使用…(me)
编辑:删除了错误的情况。
我复制并剥离了我的原始项目到最低限度,以实现这一目标。 这实际上是我的新项目中的所有代码。
这可能是types排除的一个问题,编译器推断a
Action<T>
而不是Action
(它可能认为是ActionSurrogate
,它将适合Action<Action>>
签名)。 尝试指定明确的types:
ActionSurrogate b = (Action a) => { a(); };
如果情况并非如此 – 可能会检查您的项目中是否有任何自定义的Action
代表接受一个参数。
最终更新:
这个错误已经在C#5中修复了。再次为这个不便之处再次道歉,谢谢你的报告。
原始分析:
我可以重现与命令行编译器的问题。 它看起来像一个错误。 这可能是我的错; 对于那个很抱歉。 (我写了所有的lambda-to-delegate转换检查代码。)
我现在正在咖啡店里,而且我没有从这里访问编译器源代码。 我会尽量find一些时间在明天的debugging版本中重现这个问题,看看能不能解决这个问题。 如果我找不到时间,我会在圣诞节之后不在办公室。
你的观察,引入一个variablestypes的行动导致问题消失是非常有趣的。 编译器为了性能原因和语言规范所要求的分析而维护许多高速caching。 特别是Lambda和局部variables有很多复杂的caching逻辑。 我愿意下注多达一美元,一些caching被初始化或填充错误,并且使用本地variables填充caching中的正确值。
感谢您的报告!
更新:我现在在公共汽车上,它只是对我来说; 我想我确切地知道什么是错的。 编译器是懒惰的 ,特别是在处理来自元数据的types时。 原因是在引用的程序集中可能有成千上万个types,并且不需要加载关于它们的所有信息。 你可能使用的远远不到其中的1%,所以我们不要浪费大量时间和内存来加载你永远不会使用的东西。 事实上,懒惰比这更深。 一个types可以通过几个“阶段”才可以使用。 首先它的名字是已知的,然后是它的基types,然后是它的基types层次结构是否是有根据的(非循环等),然后是它的types参数约束,然后是它的成员,然后成员是否有充分的根据相同的签名,等等)。我敢打赌,转换逻辑没有调用“确保所有委托参数的types有其成员已知”的方法,在它检查委托的签名之前调用兼容性。 但是,使本地variables的代码可能做到这一点。 我认为,在转换检查期间,就编译器而言,Actiontypes可能甚至没有调用方法。
我们马上就会知道
更新:我的精神力量今天早晨强大。 如果重载决策尝试确定是否存在采用零参数的委托types的“调用”方法,则会find可供select的零调用方法 。 在重载parsing之前,我们应该确保委托types元数据已经完全加载。 这已经被忽视了多久, 它在C#3.0中重现。 当然,C#2.0中并没有重新生成,因为没有lambdaexpression式。 C#2.0中的匿名方法要求你显式地声明types,这会创build一个本地的,我们知道加载元数据。 但我可以想象,错误的根源 – 重载parsing不会强制为调用加载元数据 – 可以回到C#1.0。
无论如何,迷人的错误,感谢报告。 显然你有一个解决方法。 我将从此处跟踪QA,我们将尝试修复C#5(我们已经错过了Service Pack 1的窗口,这个窗口已经在testing版了 。)
public static void ThisWontCompile() { ActionSurrogate b = (Action a) => { a(); }; }
这将编译。 一些小故障与编译器无法find没有参数的操作委托。 这就是为什么你得到错误。
public delegate void Action(); public delegate void Action<T>(); public delegate void Action<T1,T2>(); public delegate void Action<T1,T2,T3>(); public delegate void Action<T1,T2,T3,T4>();
- 编译错误 – 在共享主机上编译git时找不到msgfmt命令
- generics方法上的多个通配符使Java编译器(和我!)非常困惑
- getSupportFragmentManager()。getFragments()显示编译时错误
- 编译错误:“初始化元素不是编译时常量”
- 无法加载文件或程序集…参数不正确
- 架构i386的未定义符号:_OBJC_CLASS _ $ _ SKPSMTPMessage“,引用来自:错误
- Swift类错误:属性未在super.init调用初始化
- 问题sorting使用成员函数作为比较
- 错误:执行任务失败:app:transformClassesWithJarMergingForDebug'