我被这个问题激起了好奇心,我去寻找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
Run Code Online (Sandbox Code Playgroud)
看着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
Run Code Online (Sandbox Code Playgroud)
那不是我想要的.
我知道有些.NET dll是间接层,因此可以指向不同版本的框架.如果是这种情况,我该如何确定实际代码的位置?或者,如果还有其他事情发生,那么有关如何使用ildasm此类任务的提示表示赞赏.我更有能力ildasm使用它来查看我自己的东西,但是没有经验使用它来检查框架代码.
更新
在正确的方向上使用汉斯指针我最终做了以下事情:
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
Run Code Online (Sandbox Code Playgroud)
这导致我对Clear()方法的以下内容System.Collections.Generic.List`1::Clear : void():
.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
Run Code Online (Sandbox Code Playgroud)
这让我看看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
Run Code Online (Sandbox Code Playgroud)
这是另一个死胡同,但至少我现在知道去哪里寻找这种信息.
.NET 4+中的引用程序集是特殊的,它们只包含元数据,并且所有IL主体都被剥离.让它们用于与Windows桌面非常不同的平台并支持PCL非常重要.它们中的实际代码根本不重要,编译器只使用元数据.
还要记住引用程序集和运行时程序集之间的不匹配,许多引用程序集只包含[TypeForwardedTo]以定位平台提供的特定运行时程序集.
如果要查看代码,则需要查看实际的运行时程序集.它们很容易进入桌面,您可以直接导航到c:\ windows\microsoft.net\assembly.我使用旧机器来复制.NET 4.0版本.Silverlight也很简单,只需导航到其安装目录即可.您可以通过打开.vhd文件从模拟器中获取Phone.可能也适用于WindowsRT,从未尝试过.忘掉XBox吧.
| 归档时间: |
|
| 查看次数: |
567 次 |
| 最近记录: |