Skip to content

Instantly share code, notes, and snippets.

@jbevain
Created November 20, 2014 10:09
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jbevain/4d3a90714c21f28a63c6 to your computer and use it in GitHub Desktop.
Save jbevain/4d3a90714c21f28a63c6 to your computer and use it in GitHub Desktop.
using System;
using System.Reflection;
using System.Reflection.Emit;
static class TypedRef
{
public static TClass RoundTrip<TClass>(TClass instance) where TClass : class
{
var method = new DynamicMethod("", typeof(TClass), new [] {typeof(TClass)}, true);
var il = method.GetILGenerator();
var tr = il.DeclareLocal(typeof(TypedReference));
il.Emit(OpCodes.Ldarga, 0);
il.Emit(OpCodes.Mkrefany, typeof(TClass));
il.Emit(OpCodes.Stloc, tr);
il.Emit(OpCodes.Ldloc, tr);
il.Emit(OpCodes.Call, typeof(TypedRef).GetMethod("WriteType", BindingFlags.NonPublic | BindingFlags.Static));
il.Emit(OpCodes.Ldloc, tr);
il.Emit(OpCodes.Refanyval, typeof(TClass));
il.Emit(OpCodes.Ldobj, typeof(TClass));
il.Emit(OpCodes.Ret);
var f = (Func<TClass, TClass>) method.CreateDelegate(typeof(Func<TClass, TClass>));
return f(instance);
}
private static void WriteType(TypedReference tr)
{
Console.WriteLine("Type: {0}", TypedReference.GetTargetType(tr));
}
}
class Foo
{
public string Name;
}
class Program
{
static void Main()
{
var foo = new Foo { Name = "Bar" };
var foo2 = TypedRef.RoundTrip(foo);
Console.WriteLine(foo2.Name);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment