代码文件中的{GUID}.method$$****。无法编译!
我们有一个来自另一个项目的 .NET 程序集,其中 Reflector 生成的文件之一具有 .. 方法片段。
现在 VS 2010 c# 编译器会抛出各种编译错误 $$ 意外。 在 ILDASM 中,我看到了这个方法以及
提到的许多其他方法,但在生成的代码中,我发现只有这些编译器生成的方法中的 1 个进来。
如何进行编译?
We have a .NET assembly from another project where in one of the generated files from Reflector has .. snippet for a method.
Now VS 2010 c# compiler throws all sorts of compile errors $$ unexpected. close braces etc.
In ILDASM i see this method along with many others mentioned, but in generated code i find only 1 of these compiler-cgenerated methods coming in.
How to go about compiling ?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
这些通常由静态只读数组创建。你不会编译它们。此外,Reflector 在重新创建除琐碎代码之外的任何内容时都存在明显的错误。
我建议你获取原始源代码。
These are normally created by
static readonly
arrays. You will not be compiling them. Also Reflector is notably buggy recreating anything but trivial code.I suggest you get the original source code.
我相信这些是由编译器自动生成的,例如 lambda 表达式对象(您不提供任何名称)。我相信它们是无效的名称,因为编译器希望确保与您自己的代码不存在任何冲突;您只需要在重新编译之前重命名它们即可。
Those are automatically generated by the compiler, I believe for things like lambda expression objects (for which you don't provide any name). I believe they're invalid names precisely because the compiler wants to make sure there isn't any conflict with your own code; you're just going to have to rename them before re-compiling.
在我所见过的所有情况下,这都与数组初始值设定项有关。如果您查看创建的类型,您会注意到编译器刚刚为您初始化的每个大小的数组创建了一个不同的结构。编译器这样做是为了减少 IL 大小、加快数组元素的内存分配速度并保持数组元素按顺序存储在内存中。在不深入讨论的情况下,我只是提到,这样做意味着任何大小的数组初始化都发生在已知且恒定数量的 IL 指令中。我不记得我在 ILDasm 中的挖掘情况,但我认为它是 4。一次分配一个意味着每个元素 4 条指令。
现在谈谈你的具体问题。一旦您意识到您只是在处理需要重命名的值类型实例,这并没有那么糟糕。在反射器中进行一些搜索应该会揭示使用编译器生成的对象的实例。原始声明和初始化在源代码中将保持不变。这就是您需要遵循的全部内容,即对该对象进行全局重命名。选择您想要的任何名称并替换编译器生成的名称。我在下面放置了一些其他代码来说明这一点。对于需要初始化的字典,它会优化并为每个字典创建一个名为 <>f_switch$mapn 的新实例,其中 n 又是一个计数器。
对于自动生成的支持字段的任何属性,您还将处理类似的废话。不过同样的修复。创建您自己的支持字段并使用它。
In all the cases I have seen this it has to do with Array initializers. If you look at the types created in you'll notice that the compiler has just created a different struct for each size array you have initialized. The compiler does this to reduce IL size, speed memory allocation for the array elements and to keep the array elements stored in memory together and in order. Without getting to deep in the weeds I'll just mention that doing it this way means any size array initialization happens in a known and constant number of IL instructions. I can't remember from my digging in ILDasm but I think it was 4. Assigning one at a time means 4 instructions per element.
Now to your specific problem. It's not that bad once you realize you're just dealing with value type instances that need to be renamed. Some searching in reflector should reveal the instances where the compiler generated objects are used. The original declaration and initialization will be intact in source. That's all you need to follow though with a global rename for that object. Pick any name you want and replace the compiler's generated name. I put some other code below that illustrates this. For Dictionaries that need initialization as well it optimizes and creates a new instance for each Dictionary called <>f_switch$mapn where n is a counter again.
You'll also deal with similar nonsense for any properties the backing fields were autogenerated for. Same fix though. Create your own backing field and use it.
从视图菜单中选择选项。
验证优化选择。由于您使用的是最新版本的 VS,因此您应该指定针对 .Net 4.0 或至少 3.5 进行优化以获得对 lambda 的支持。
From the view menu, select options.
Verify the Optimization selection. Since you are using the latest version of VS, you should specify to optimize for .Net 4.0 or at least 3.5 to get support for lambdas.