去哪里查看 ildasm 中的 System.Collections.Generic IL 代码?
Where to go to view System.Collections.Generic IL code in ildasm?
这个 激起了我的好奇心,我开始寻找 List.Clear() 的实现。当我 运行 ildasm
在 System.Collections.dll
上这样时:
cd c:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETCore\v4.5
"C:\Program Files (x86)\Microsoft SDKs\Windows\v8.1A\bin\NETFX 4.5.1 Tools\ildasm.exe" System.Collections.dll
并查看了 System.Collections.Generic.List`1::Clear : void()
,这是我发现的:
.method public hidebysig newslot virtual final
instance void Clear() cil managed
{
// Code size 1 (0x1)
.maxstack 8
IL_0000: ret
} // end of method List`1::Clear
这不是我要找的。
我知道某些 .NET dll 是一种间接级别,因此可以定向到不同版本的框架。如果是这种情况,我如何找出实际代码在哪里?或者,如果还有其他事情发生,请提供有关如何使用 ildasm
完成此类任务的提示。我更擅长使用 ildasm
查看我自己的东西,但我没有使用它来检查框架代码的经验。
更新
在正确的方向上使用 Hans 的指针,我最终做了以下事情:
cd C:\Windows\Microsoft.NET\assembly\GAC_32\mscorlib\v4.0_4.0.0.0__b77a5c561934e089
"C:\Program Files (x86)\Microsoft SDKs\Windows\v8.1A\bin\NETFX 4.5.1 Tools\ildasm.exe" mscorlib.dll
这让我想到了 System.Collections.Generic.List`1::Clear : void()
上的 Clear() 方法:
.method public hidebysig newslot virtual final
instance void Clear() cil managed
{
.custom instance void __DynamicallyInvokableAttribute::.ctor() = ( 01 00 00 00 )
// Code size 49 (0x31)
.maxstack 8
IL_0000: ldarg.0
IL_0001: ldfld int32 class System.Collections.Generic.List`1<!T>::_size
IL_0006: ldc.i4.0
IL_0007: ble.s IL_0022
IL_0009: ldarg.0
IL_000a: ldfld !0[] class System.Collections.Generic.List`1<!T>::_items
IL_000f: ldc.i4.0
IL_0010: ldarg.0
IL_0011: ldfld int32 class System.Collections.Generic.List`1<!T>::_size
IL_0016: call void System.Array::Clear(class System.Array,
int32,
int32)
IL_001b: ldarg.0
IL_001c: ldc.i4.0
IL_001d: stfld int32 class System.Collections.Generic.List`1<!T>::_size
IL_0022: ldarg.0
IL_0023: dup
IL_0024: ldfld int32 class System.Collections.Generic.List`1<!T>::_version
IL_0029: ldc.i4.1
IL_002a: add
IL_002b: stfld int32 class System.Collections.Generic.List`1<!T>::_version
IL_0030: ret
} // end of method List`1::Clear
所以这让我看到了 System.Array::Clear()
,它给了我:
.method public hidebysig static void Clear(class System.Array 'array',
int32 index,
int32 length) cil managed internalcall
{
.custom instance void System.Security.SecuritySafeCriticalAttribute::.ctor() = ( 01 00 00 00 )
.custom instance void System.Runtime.ConstrainedExecution.ReliabilityContractAttribute::.ctor(valuetype System.Runtime.ConstrainedExecution.Consistency,
valuetype System.Runtime.ConstrainedExecution.Cer) = ( 01 00 03 00 00 00 02 00 00 00 00 00 )
.custom instance void __DynamicallyInvokableAttribute::.ctor() = ( 01 00 00 00 )
} // end of method Array::Clear
这又是一个死胡同,但至少我现在知道去哪里获取此类信息了。
.NET 4+ 中的引用程序集是特殊的,它们只包含元数据并且所有 IL 主体都被剥离。允许它们用于与 Windows 桌面截然不同的目标平台并支持 PCL 非常重要。它们中的实际代码根本不重要,编译器只使用元数据。
还要记住参考程序集和运行时程序集之间的不匹配,许多参考程序集仅包含 [TypeForwardedTo] 以针对平台提供的特定运行时程序集。
如果您想查看代码,则需要查看实际的运行时程序集。它们很容易在桌面上找到,您可以直接导航到 c:\windows\microsoft.net\assembly。我用一台旧机器来复制 .NET 4.0 版本。 Silverlight 也很简单,只需导航到其安装目录即可。您可以通过打开 .vhd 文件从模拟器中获取 Phone 个。可能也适用于 WindowsRT,从未尝试过。忘掉 XBox。
可能有很多方法可以做到这一点,所以这只是我的方法,因为我碰巧有 LinqPad and Reflector.
的副本
我会打开 LinqPad 并编写一个小脚本
var x = new List<String>();
x.Clear();
然后将鼠标移动到Clear()
上并按Shift-F1,这将在正确的位置打开反射器并反编译Clear()。这使我不必尝试找出哪个 dll 包含实际代码。
您可能可以使用免费的反编译器(例如 ILspy 或 DotPeek)来做类似的事情,但它们不会挂接到 LinqPad,因此您需要弄清楚要打开哪个 dll。
这个 ildasm
在 System.Collections.dll
上这样时:
cd c:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETCore\v4.5
"C:\Program Files (x86)\Microsoft SDKs\Windows\v8.1A\bin\NETFX 4.5.1 Tools\ildasm.exe" System.Collections.dll
并查看了 System.Collections.Generic.List`1::Clear : void()
,这是我发现的:
.method public hidebysig newslot virtual final
instance void Clear() cil managed
{
// Code size 1 (0x1)
.maxstack 8
IL_0000: ret
} // end of method List`1::Clear
这不是我要找的。
我知道某些 .NET dll 是一种间接级别,因此可以定向到不同版本的框架。如果是这种情况,我如何找出实际代码在哪里?或者,如果还有其他事情发生,请提供有关如何使用 ildasm
完成此类任务的提示。我更擅长使用 ildasm
查看我自己的东西,但我没有使用它来检查框架代码的经验。
更新
在正确的方向上使用 Hans 的指针,我最终做了以下事情:
cd C:\Windows\Microsoft.NET\assembly\GAC_32\mscorlib\v4.0_4.0.0.0__b77a5c561934e089
"C:\Program Files (x86)\Microsoft SDKs\Windows\v8.1A\bin\NETFX 4.5.1 Tools\ildasm.exe" mscorlib.dll
这让我想到了 System.Collections.Generic.List`1::Clear : void()
上的 Clear() 方法:
.method public hidebysig newslot virtual final
instance void Clear() cil managed
{
.custom instance void __DynamicallyInvokableAttribute::.ctor() = ( 01 00 00 00 )
// Code size 49 (0x31)
.maxstack 8
IL_0000: ldarg.0
IL_0001: ldfld int32 class System.Collections.Generic.List`1<!T>::_size
IL_0006: ldc.i4.0
IL_0007: ble.s IL_0022
IL_0009: ldarg.0
IL_000a: ldfld !0[] class System.Collections.Generic.List`1<!T>::_items
IL_000f: ldc.i4.0
IL_0010: ldarg.0
IL_0011: ldfld int32 class System.Collections.Generic.List`1<!T>::_size
IL_0016: call void System.Array::Clear(class System.Array,
int32,
int32)
IL_001b: ldarg.0
IL_001c: ldc.i4.0
IL_001d: stfld int32 class System.Collections.Generic.List`1<!T>::_size
IL_0022: ldarg.0
IL_0023: dup
IL_0024: ldfld int32 class System.Collections.Generic.List`1<!T>::_version
IL_0029: ldc.i4.1
IL_002a: add
IL_002b: stfld int32 class System.Collections.Generic.List`1<!T>::_version
IL_0030: ret
} // end of method List`1::Clear
所以这让我看到了 System.Array::Clear()
,它给了我:
.method public hidebysig static void Clear(class System.Array 'array',
int32 index,
int32 length) cil managed internalcall
{
.custom instance void System.Security.SecuritySafeCriticalAttribute::.ctor() = ( 01 00 00 00 )
.custom instance void System.Runtime.ConstrainedExecution.ReliabilityContractAttribute::.ctor(valuetype System.Runtime.ConstrainedExecution.Consistency,
valuetype System.Runtime.ConstrainedExecution.Cer) = ( 01 00 03 00 00 00 02 00 00 00 00 00 )
.custom instance void __DynamicallyInvokableAttribute::.ctor() = ( 01 00 00 00 )
} // end of method Array::Clear
这又是一个死胡同,但至少我现在知道去哪里获取此类信息了。
.NET 4+ 中的引用程序集是特殊的,它们只包含元数据并且所有 IL 主体都被剥离。允许它们用于与 Windows 桌面截然不同的目标平台并支持 PCL 非常重要。它们中的实际代码根本不重要,编译器只使用元数据。
还要记住参考程序集和运行时程序集之间的不匹配,许多参考程序集仅包含 [TypeForwardedTo] 以针对平台提供的特定运行时程序集。
如果您想查看代码,则需要查看实际的运行时程序集。它们很容易在桌面上找到,您可以直接导航到 c:\windows\microsoft.net\assembly。我用一台旧机器来复制 .NET 4.0 版本。 Silverlight 也很简单,只需导航到其安装目录即可。您可以通过打开 .vhd 文件从模拟器中获取 Phone 个。可能也适用于 WindowsRT,从未尝试过。忘掉 XBox。
可能有很多方法可以做到这一点,所以这只是我的方法,因为我碰巧有 LinqPad and Reflector.
的副本我会打开 LinqPad 并编写一个小脚本
var x = new List<String>();
x.Clear();
然后将鼠标移动到Clear()
上并按Shift-F1,这将在正确的位置打开反射器并反编译Clear()。这使我不必尝试找出哪个 dll 包含实际代码。
您可能可以使用免费的反编译器(例如 ILspy 或 DotPeek)来做类似的事情,但它们不会挂接到 LinqPad,因此您需要弄清楚要打开哪个 dll。