Necesito generar una clase mediante la Reflexión.Emiten que implementa la siguiente interfaz.

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

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

class GeneratedObject : IObject
{
    public T Get<T>(string propertyName)
    {
        //this is the simplest possible implementation
        return default(T);
    }
}
  • Reescribí la pregunta 😉
InformationsquelleAutor karma | 2009-10-30

5 Comentarios

  1. 10

    Si usted está utilizando la Reflexión.Emitir, a la que realmente debería hacerse con una copia de la Reflexión.Emiten complemento de lenguaje para Reflector. Aunque no es perfecta, se debe obtener al menos el 95% de la forma de cualquier código emitido.

    • +1 Este complemento es muy útil.
    • El ReflectionEmitLanguage es simplemente genial…
    • -1 Mientras que el complemento puede ser (o no puede ser, no sé ni me importa, yo no uso Reflector, es caro) extremadamente útil, esto no responde a la pregunta.
  2. 4

    No tengo un compilador a mano, 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();
    • Hola, he utilizado el ejemplo de éxito (código de menor importancia ediciones). Después de crear el generatedType, puedo usar el Activador.CreateInstance(generatedType) para conseguir un control sobre el objeto. Me echó como la interfaz de IObject, y luego llamar al método. De hecho, me da por defecto(T). Lo que necesito es cambiar esa aplicación, y en vez de darme por defecto(T), para enlazar con un método genérico que recibe los parámetros (o la lista de parámetros) y da una adecuada implementación. Cualquier idea sobre cómo lograr eso?
    • Lo siento, no le puedo decir a partir de su descripción exactamente lo que quieres decir. Probablemente sería mejor abrir una nueva pregunta que establece claramente los detalles.
  3. 0

    Creo AutoMapper y/o LinFu va a hacer esto para usted. Definitivamente, usted puede crear una instancia de una interfaz con AutoMapper, yo lo he hecho.

    • AutoMapper es tan lento!
    • Es un tema bastante amplio declaración sin contexto. ymmv y depende de su uso. ericlippert.com/2012/12/17/performance-rant
    • Usted puede hacer simple prueba más de 100000 elementos en la matriz. Si se escribe sin automap será 10 veces más rápido. Para pequeño conjunto creo que esta diferencia no importa…
    • Pero cuellos de botella de rendimiento no es sólo basora determinada línea de código. Imagibe cuando algún método donde esa línea de código se ejecuta con mucha frecuencia, entonces estoy seguro de que usted podría considerar la posibilidad de cambiar la forma en cómo se implementa 😉
    • no te ves en el artículo que enlaza a todos?
  4. 0

    Olvidó CUADRO de la vuelta:

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

    Parece, quieres hacer un acceso rápido a las propiedades de los objetos por su nombre sin la reflexión en tiempo de ejecución.
    El uso de Yappi y su Propiedad<> clase puede implementar determinado de la interfaz como esta:

    class GeneratedObject : IObject
    {
        public string Value { get { return "Test"; } }
    
        public T Get<T>(string propertyName)
        {
            return Property<GeneratedObject>.Get<T>(this,propertyName);
        }
    }

    y, a continuación, utilizarlo como este:

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

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

Dejar respuesta

Please enter your comment!
Please enter your name here