2009-10-30 36 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提取和動態型建設?