2009-10-30 24 views
13

我需要使用Reflection.Emit生成一个实现以下接口的类。使用Reflection.Emit创建实现接口的类

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

有没有人有我如何发出以下作为简单测试用例的例子?

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

我重写了这个问题;) – 2009-10-30 18:38:45

回答

10

如果您使用Reflection.Emit的,你真的应该抓住Reflection.Emit language add-in的副本Reflector。虽然不完美,但它应该能够让你至少有95%的途径可用于任何给定的发射代码。

+3

+1这个加载项非常有用。 – 2009-10-30 18:33:44

+0

ReflectionEmitLanguage简直是太棒了... – 2010-12-14 21:46:49

+0

-1虽然插件可能(或者可能不是,我不知道也不关心,我没有使用Reflector,但它很贵)非常有用,这不会回答这个问题。 – Szybki 2018-02-08 18:55:05

0

我相信AutoMapper和/或LinFu会为你做这个。你可以使用AutoMapper创建一个接口的实例,我已经完成了。

+0

AutoMapper太慢了! – 2014-01-30 12:56:29

+0

这是一个非常广泛的声明,没有上下文。 ymmv,这取决于你的使用情况。 http://ericlippert.com/2012/12/17/performance-rant/ – Maslow 2014-01-30 14:58:04

+0

您可以对数组中的100000个项目进行简单测试。如果你在没有automap的情况下编写它,它会快10倍。对于小集我相信这种差异并不重要... – 2014-01-31 08:29:14

3

我没有编译器方便,但这样的事情应该工作:

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

你忘了框返回:

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

看来,你想快速访问在运行时通过名称反映对象的属性而不反映。 使用Yappi及其属性<>类可以实现这样定的接口:

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

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

,然后用它是这样的:

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

你还需要IObject提取和动态型建设?