2009-10-30 16 views
13

necesito para generar una clase usando Reflection.Emit que implementa la interfaz siguiente.Reflection.Emit para crear una clase que implementa una interfaz

public interface IObject 
{ 
    T Get<T>(string propertyName); 
} 

¿Alguien tiene un ejemplo de cómo emitiría lo siguiente como un caso de prueba simple?

class GeneratedObject : IObject 
{ 
    public T Get<T>(string propertyName) 
    { 
     // this is the simplest possible implementation 
     return default(T); 
    } 
} 
+2

Reescribí la pregunta;) –

Respuesta

10

Si está utilizando Reflection.Emit, que realmente debería hacerse con una copia de la Reflection.Emit language add-in para Reflector. Si bien no es perfecto, debe obtener al menos el 95% del camino a cualquier código emitido.

+3

1 Este complemento es de gran utilidad. –

+0

El ReflectionEmitLanguage es simplemente genial ... –

+0

-1 Mientras que el complemento puede ser (o puede ser que no, no lo sé ni me importa, yo no uso del reflector, es caro) de gran utilidad, esto no responde la pregunta. – Szybki

0

creo AutoMapper y/o LinFu lo hará por ti. Definitivamente puede crear una instancia de una interfaz usando AutoMapper, lo he hecho.

+0

¡AutoMapper es tan lento! –

+0

Esa es una afirmación bastante amplia sin contexto. ymmv y depende de tu uso. http://ericlippert.com/2012/12/17/performance-rant/ – Maslow

+0

Puede hacer una prueba simple de más de 100000 elementos en el conjunto. Si lo escribe sin automatización, será 10 veces más rápido. Para los pequeños fijaron i belive esta diferencia no importa ... –

3

no tengo un compilador útil, pero algo como esto debería funcionar:

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(); 
0

que se olvidó de la casilla de retorno:

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)); 
    } 
0

Parece, desea realizar un acceso rápido a las propiedades del objeto por su nombre sin reflejo en el tiempo de ejecución. Usando Yappi y su propiedad <> clase puede implementar interfaz dada así:

class GeneratedObject : IObject 
{ 
    public string Value { get { return "Test"; } } 

    public T Get<T>(string propertyName) 
    { 
     return Property<GeneratedObject>.Get<T>(this,propertyName); 
    } 
} 

y luego usarlo como esto:

IObject obj = new GeneratedObject(); 
var value = obj.Get<String>("Value"); //value contains "Test" 

¿Todavía necesita IObject y el tipo dinámico de la construcción?

Cuestiones relacionadas