2009-10-30 5 views
13

다음 인터페이스를 구현하는 Reflection.Emit을 사용하여 클래스를 생성해야합니다.Reflection.Emit을 사용하여 인터페이스를 구현하는 클래스 만들기

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

간단한 테스트 사례로 다음을 방출하는 방법에 대한 예가 있습니까? 당신이 Reflection.Emit를를 사용하는 경우

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

질문을 다시 작성했습니다.) –

답변

10

, 당신은 정말 ReflectorReflection.Emit language add-in의 사본을 잡아해야한다. 완벽하지는 않지만 주어진 방출 코드에 대해 최소한 95 % 이상을 가져와야합니다.

+3

+1이 추가 기능은 매우 유용합니다. –

+0

ReflectionEmitLanguage는 단순히 훌륭합니다 ... –

+0

-1 추가 기능이 매우 유용 할 수도 있지만 (모름지도 모르겠지만, 리플렉터를 사용하지 않습니다. 비싸지 만) 매우 유용합니다. 질문. – Szybki

0

나는 AutoMapper 및/또는 LinFu이이 작업을 수행 할 것으로 믿습니다. AutoMapper를 사용하여 인터페이스의 인스턴스를 만들 수 있습니다.

+0

AutoMapper가 너무 느립니다! –

+0

문맥이없는 꽤 폭 넓은 성명서입니다. ymmv 그리고 당신의 사용법에 달려 있습니다. http://ericlippert.com/2012/12/17/performance-rant/ – Maslow

+0

배열로 100000 개가 넘는 간단한 테스트를 할 수 있습니다. 당신이 automap없이 whithout 그것을 쓰면 10 배 빠를 것입니다. 작은 세트에 대해서 나는이 차이가 중요하지 않다는 것을 믿습니다 ... –

3

I 편리 컴파일러를 가지고 있지 않지만,이 같은 일을해야 :

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

당신이 빠르게 액세스 할 수 있도록하려는 것 같다 런타임시 반영하지 않고 이름으로 객체의 속성에 적용합니다.

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

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

다음과 같이 사용 : 이 같은 지정된 인터페이스를 구현할 수 Yappi과 그 속성 <> 클래스를 사용

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

여전히 IObject 및 동적 유형의 건설 필요하십니까?

관련 문제