【发布时间】:2011-05-25 18:11:16
【问题描述】:
我们有一个来自另一个项目的 .NET 程序集,其中一个从 Reflector 生成的文件中包含一个方法的 ..sn-p。
现在 VS 2010 c# 编译器会抛出各种编译错误 $$ 意外。大括号等。
在 ILDASM 中,我看到了这个方法以及许多其他提到的方法,但在生成的代码中,我发现只有其中一种由编译器生成的方法进入。
如何编译?
【问题讨论】:
标签: c# .net-reflector
我们有一个来自另一个项目的 .NET 程序集,其中一个从 Reflector 生成的文件中包含一个方法的 ..sn-p。
现在 VS 2010 c# 编译器会抛出各种编译错误 $$ 意外。大括号等。
在 ILDASM 中,我看到了这个方法以及许多其他提到的方法,但在生成的代码中,我发现只有其中一种由编译器生成的方法进入。
如何编译?
【问题讨论】:
标签: c# .net-reflector
这些通常由static readonly 数组创建。你不会编译它们。此外,Reflector 在重新创建除琐碎代码之外的任何内容时都存在明显问题。
我建议你获取原始源代码。
【讨论】:
if (new[] { 16, 32, 42, 64, 314, 1337 }.Contains(something)) { ... }。
那些是由编译器自动生成的,我相信像 lambda 表达式对象(您不提供任何名称)之类的东西。我相信它们是无效的名称,正是因为编译器希望确保与您自己的代码没有任何冲突;你只需要在重新编译之前重命名它们。
【讨论】:
<PrivateImplementationDetails>{GUID}.method$$****,你用一个有效的标识符替换它。
在我看到的所有情况下,它都与数组初始化器有关。如果您查看其中创建的类型,您会注意到编译器刚刚为您初始化的每个大小数组创建了一个不同的结构。编译器这样做是为了减少 IL 大小,加快数组元素的内存分配,并使数组元素按顺序一起存储在内存中。在不深入杂草的情况下,我只想提一下,这样做意味着任何大小的数组初始化都发生在已知且恒定数量的 IL 指令中。我不记得我在 ILDasm 中的挖掘,但我认为是 4 个。一次分配一个意味着每个元素有 4 个指令。
现在谈谈您的具体问题。一旦您意识到您只是在处理需要重命名的值类型实例,这并不是那么糟糕。在反射器中的一些搜索应该揭示使用编译器生成的对象的实例。原始声明和初始化将在源代码中保持不变。尽管对该对象进行全局重命名,但这就是您需要遵循的全部内容。选择您想要的任何名称并替换编译器生成的名称。我在下面放了一些其他代码来说明这一点。对于需要初始化的字典,它会优化并为每个字典创建一个名为 f_switch$mapn 的新实例,其中 n 再次是一个计数器。
对于自动生成支持字段的任何属性,您还将处理类似的废话。不过同样的修复。创建您自己的支持字段并使用它。
[CompilerGenerated]
internal class <PrivateImplementationDetails>
{
// Fields
internal static $ArrayType$4 $$field-0; // data size: 4 bytes
internal static $ArrayType$4 $$field-1; // data size: 4 bytes
internal static $ArrayType$4 $$field-2; // data size: 4 bytes
internal static $ArrayType$4 $$field-3; // data size: 4 bytes
internal static $ArrayType$44 $$field-4; // data size: 44 bytes
internal static $ArrayType$4 $$field-5; // data size: 4 bytes
// Nested Types
[StructLayout(LayoutKind.Explicit, Size=4, Pack=1)]
private struct $ArrayType$4
{
}
[StructLayout(LayoutKind.Explicit, Size=0x2c, Pack=1)]
private struct $ArrayType$44
{
}
}
static GATWavHelper()
{
riffBytes = new byte[] { 0x52, 0x49, 70, 70 };
waveBytes = new byte[] { 0x57, 0x41, 0x56, 0x45 };
fmtBytes = new byte[] { 0x66, 0x6d, 0x74, 0x20 };
dataBytes = new byte[] { 100, 0x61, 0x74, 0x61 };
headerSize = 0x2c;
floatToInt16RescaleFactor = 0x7fff;
__canonicalHeader = new byte[] {
0x52, 0x49, 70, 70, 0, 0, 0, 0, 0x57, 0x41, 0x56, 0x45, 0x66, 0x6d, 0x74, 0x20,
0, 0, 0, 0x10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 100, 0x61, 0x74, 0x61, 0, 0, 0, 0
};
}
// Fields
[CompilerGenerated]
private static Dictionary<string, int> <>f__switch$map0;
.
.
.
if (<>f__switch$map0 == null)
{
Dictionary<string, int> dictionary = new Dictionary<string, int>(3);
dictionary.Add("false", 0);
dictionary.Add("true", 1);
dictionary.Add("null", 2);
<>f__switch$map0 = dictionary;
}
if (<>f__switch$map0.TryGetValue(nextWord, out num))
{
switch (num)
.
.
.
【讨论】:
从视图菜单中选择选项。
验证优化选择。由于您使用的是最新版本的 VS,因此应指定针对 .Net 4.0 或至少 3.5 进行优化以获得对 lambdas 的支持。
【讨论】: