Created
August 21, 2014 21:21
-
-
Save AArnott/d285feef75c18f6ecd2b to your computer and use it in GitHub Desktop.
Creating a static method that accepts a first argument supplied by the delegate.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
namespace ILExaminer | |
{ | |
using System; | |
static class Program | |
{ | |
internal static Func<T> AsFunc<T>(this T value) | |
where T : class | |
{ | |
return new Func<T>(value.Return); | |
} | |
private static T Return<T>(this T value) | |
{ | |
return value; | |
} | |
static void Main(string[] args) | |
{ | |
Func<string> foo = "hi".AsFunc(); | |
string v = foo(); | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
.class private abstract auto ansi sealed beforefieldinit ILExaminer.Program | |
extends [mscorlib]System.Object | |
{ | |
.custom instance void [mscorlib]System.Runtime.CompilerServices.ExtensionAttribute::.ctor() = ( 01 00 00 00 ) | |
.method assembly hidebysig static class [mscorlib]System.Func`1<!!T> | |
AsFunc<class T>(!!T 'value') cil managed | |
{ | |
.custom instance void [mscorlib]System.Runtime.CompilerServices.ExtensionAttribute::.ctor() = ( 01 00 00 00 ) | |
// Code size 18 (0x12) | |
.maxstack 8 | |
IL_0000: ldarg.0 | |
IL_0001: box !!T | |
IL_0006: ldftn !!0 ILExaminer.Program::Return<!!0>(!!0) | |
IL_000c: newobj instance void class [mscorlib]System.Func`1<!!T>::.ctor(object, | |
native int) | |
IL_0011: ret | |
} // end of method Program::AsFunc | |
.method private hidebysig static !!T Return<T>(!!T 'value') cil managed | |
{ | |
.custom instance void [mscorlib]System.Runtime.CompilerServices.ExtensionAttribute::.ctor() = ( 01 00 00 00 ) | |
// Code size 2 (0x2) | |
.maxstack 8 | |
IL_0000: ldarg.0 | |
IL_0001: ret | |
} // end of method Program::Return | |
.method private hidebysig static void Main(string[] args) cil managed | |
{ | |
.entrypoint | |
// Code size 19 (0x13) | |
.maxstack 1 | |
.locals init ([0] class [mscorlib]System.Func`1<string> foo) | |
IL_0000: ldstr "hi" | |
IL_0005: call class [mscorlib]System.Func`1<!!0> ILExaminer.Program::AsFunc<string>(!!0) | |
IL_000a: stloc.0 | |
IL_000b: ldloc.0 | |
IL_000c: callvirt instance !0 class [mscorlib]System.Func`1<string>::Invoke() | |
IL_0011: pop | |
IL_0012: ret | |
} // end of method Program::Main | |
} // end of class ILExaminer.Program | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
OK, I figured out why this box must be emitted even if T is constrained to be a reference type. It is required to be verifiable. The key is in the next sentence in the spec that I left out of the above excerpt:
If you strip out that box via ildasm/ilasm and run peverify, you get something like:
So from the verifier's perspective, you simply can't pass an 'unboxed' T to object. It does not take in to account the constraint and that makes sense when you factor in that requiring the box has no impact on the native code that will run.