3

この質問に好奇心をそそられ、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自分のものを見るために使用することはできますが、フレームワーク コードを調べるために使用する経験はありません。

アップデート

ハンスのポインターを正しい方向に使用すると、次のようになりました。

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

これにより、 の 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

そのため、 を見て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

これも行き止まりですが、少なくともこの種の情報をどこで入手すればよいかはわかりました。

4

2 に答える 2

3

これを行う方法はおそらくたくさんあるので、たまたまLinqPadReflectorのコピーを持っているので、これは私の方法です。

LinqPad を開いて小さなスクリプトを書きます

var x = new List<String>();
x.Clear();

次に、マウスを の上に移動してClear()Shift-F1 を押すと、正しい位置でリフレクターが開き、Clear() が逆コンパイルされます。これにより、どの dll に実際のコードが含まれているかを把握する必要がなくなります。

おそらく無料の逆コンパイラ (ILspy や DotPeek など) を使用して同様のことを行うことができますが、それらは LinqPad にフックしないため、どの dll を開くかを決定する必要があります。

于 2015-04-25T18:17:38.043 に答える