Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>When you disassemble the generated code, you can see that in .NET 3.5, the <code>ldtoken</code> instruction in connection to the open generic method is emitted as follows:</p> <pre><code>.method public static void GeneratedMethod&lt;T&gt;() cil managed { // Code size 11 (0xb) .maxstack 1 IL_0000: ldtoken method instance void [ConsoleApplication16]ConsoleApplication16.Program/Foo::FooMethod&lt;!!0&gt;() IL_0005: call void [ConsoleApplication16]ConsoleApplication16.Program::PrintMethodInfo(valuetype [mscorlib]System.RuntimeMethodHandle) IL_000a: ret } // end of method TestType::GeneratedMethod </code></pre> <p>The syntax <code>!!0</code> is a reference to the type parameter of the surrounding method (<code>GeneratedMethod</code>), so the <code>Foo</code> method is loaded instantiated with the <code>T</code> belonging to <code>GeneratedMethod&lt;T&gt;</code>. (In fact, this is the same IL as would be emitted for <code>IL.Emit (OpCodes.Ldtoken, methodInfo.MakeGenericMethod (&lt;typeParameterOfGeneratedMethod&gt;))</code>.) This <code>!!0</code> reference is emitted even when <code>GeneratedMethod</code> is not generic at all - the resulting program is then no longer verifiable (and, when executed, results in a BadImageFormatException).</p> <p>This is clearly a bug, and in .NET 4, this seems to be fixed, as the (disassembled) emitted code now looks like this:</p> <pre><code>.method public static void GeneratedMethod&lt;T&gt;() cil managed { // Code size 11 (0xb) .maxstack 1 IL_0000: ldtoken method instance void [ConsoleApplication16]ConsoleApplication16.Program/Foo::FooMethod&lt;[1]&gt;() IL_0005: call void [ConsoleApplication16]ConsoleApplication16.Program::PrintMethodInfo(valuetype [mscorlib]System.RuntimeMethodHandle) IL_000a: ret } // end of method TestType::GeneratedMethod </code></pre> <p>As you can see, the signature now refers to the uninstantiated <code>FooMethod</code> (in IL assembly, this is denoted as <code>FooMethod[1]</code>).</p> <p>So yes, this looks like a bug in .NET 3.5 that was fixed with .NET 4. However, it doesn't seem to be a change in the semantics of <code>ldtoken</code>; it was just that Reflection.Emit didn't emit references to open generic methods correctly. I suspect it's also connected to <a href="http://www.mail-archive.com/advanced-dotnet@discuss.develop.com/msg12626.html" rel="nofollow">the fact that IL assembler didn't even have a syntax to denote open generic methods in the past</a>.</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload