I need to generate a class using Reflection.Emit that implements the following interface.
public interface IObject
{
T Get(string propertyName);
You forgot to BOX the return:
internal delegate object FastConstructorHandler(object[] paramters);
private static FastConstructorHandler CreateDelegate(Type Tipo)
{
DynamicMethod dynamicMethod = new DynamicMethod(string.Empty,
typeof(object), new Type[] { typeof(object[]) }, Tipo.Module, false);
ILGenerator ilg = dynamicMethod.GetILGenerator();
ilg.DeclareLocal(Tipo);
ilg.Emit(OpCodes.Ldloca_S, (byte)0);
ilg.Emit(OpCodes.Initobj, Tipo);
ilg.Emit(OpCodes.Ldloc_0);
ilg.Emit(OpCodes.Box, Tipo);
ilg.Emit(OpCodes.Ret);
return (FastConstructorHandler)dynamicMethod.CreateDelegate(typeof(FastConstructorHandler));
}
If you're using Reflection.Emit, you really ought to grab a copy of the Reflection.Emit language add-in for Reflector. While not perfect, it should get you at least 95% of the way to any given emitted code.
It seems, you want to make fast access to object's properties by its name without reflection at run time. Using Yappi and its Property<> class you can implement given interface like this:
class GeneratedObject : IObject
{
public string Value { get { return "Test"; } }
public T Get<T>(string propertyName)
{
return Property<GeneratedObject>.Get<T>(this,propertyName);
}
}
and then use it like this:
IObject obj = new GeneratedObject();
var value = obj.Get<String>("Value"); //value contains "Test"
Do you still need IObject and dynamic type construction?
I believe AutoMapper and/or LinFu will do this for you. You can definitely create an instance of an interface using AutoMapper, I've done it.
I don't have a compiler handy, but something like this should work:
var aName = new AssemblyName("temp");
var appDomain = Threading.Thread.GetDomain();
var aBuilder = appDomain.DefineDynamicAssembly(aName, AssemblyBuilderAccess.Run);
var mBuilder = aBuilder.DefineDynamicModule(aName.Name);
var tBuilder = mBuilder.DefineType("GeneratedObject", TypeAttributes.Public | TypeAttributes.Class);
tBuilder.AddInterfaceImplementation(typeof(IObject));
var methBuilder = tBuilder.DefineMethod("Get", MethodAttributes.Public | MethodAttributes.Final | MethodAttributes.Virtual);
var typeParam = mb.DefineGenericParameters(new string[] { "T" })[0];
methBuilder.SetParameters(new Type[] { typeof(string) });
methBuilder.SetReturnType(typeParam);
var ilg = methBuilder.GetILGenerator();
let lBuilder = ilg.DeclareLocal(typeParam);
ilg.Emit(OpCodes.Ldloca_S, (byte)0);
ilg.Emit(OpCodes.Initobj, typeParam);
ilg.Emit(OpCodes.Ldloc_0);
ilg.Emit(OpCodes.Ret);
var generatedType = tBuilder.CreateType();