2009-10-30 24 views
13

Tôi cần tạo một lớp bằng cách sử dụng Reflection.Emit thực hiện giao diện sau đây.Sử dụng Reflection.Emit để tạo một lớp thực hiện một giao diện

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

Có ai có ví dụ về cách tôi phát ra sau đây như một trường hợp thử nghiệm đơn giản không?

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

Tôi viết lại câu hỏi;) –

Trả lời

10

Nếu bạn đang sử dụng Reflection.Emit, bạn thực sự phải lấy một bản sao của Reflection.Emit language add-in cho Reflector. Trong khi không hoàn hảo, nó sẽ giúp bạn có ít nhất 95% con đường đến bất kỳ mã được phát ra nào.

+3

+1 Bổ trợ này cực kỳ hữu ích. –

+0

ReflectionEmitLanguage chỉ đơn giản là tuyệt vời ... –

+0

-1 Trong khi bổ trợ có thể (hoặc có thể không, tôi không biết và cũng không quan tâm, tôi không sử dụng Reflector, nó đắt tiền) cực kỳ hữu ích, điều này không trả lời câu hỏi. – Szybki

0

Tôi tin rằng AutoMapper và/hoặc LinFu sẽ làm điều này cho bạn. Bạn chắc chắn có thể tạo một thể hiện của một giao diện bằng cách sử dụng AutoMapper, tôi đã thực hiện nó.

+0

AutoMapper quá chậm! –

+0

Đó là một tuyên bố khá rộng không có ngữ cảnh. ymmv và nó phụ thuộc vào cách sử dụng của bạn. http://ericlippert.com/2012/12/17/performance-rant/ – Maslow

+0

Bạn có thể thực hiện thử nghiệm đơn giản trên 100000 mục trong mảng. Nếu bạn viết nó tự động, nó sẽ nhanh hơn gấp 10 lần. Đối với thiết lập nhỏ, tôi tin rằng sự khác biệt này không quan trọng ... –

3

Tôi không có một trình biên dịch tiện dụng, nhưng một cái gì đó như thế này nên làm việc:

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

Bạn quên hộp sự trở lại:

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

Có vẻ như, bạn muốn thực hiện truy cập nhanh đối với các thuộc tính của đối tượng theo tên của nó mà không có sự phản ánh tại thời gian chạy. Sử dụng Yappi và tài sản của nó <> lớp học mà bạn có thể thực hiện giao diện cho như thế này:

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

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

và sau đó sử dụng nó như thế này:

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

Bạn vẫn cần IObject và loại động xây dựng?

Các vấn đề liên quan