2011-09-14 25 views
17

Bạn sẽ sử dụng phản chiếu như thế nào để thực thi phương thức sau đây khi loại chỉ có thể suy ra khi chạy?Cách kích hoạt một phương thức chung để thực hiện hành động làm tham số

MainObject.TheMethod<T>(Action<OtherObject<T>>) 

trong sử dụng hàng ngày, điển hình là:

mainObject.Method<Message>(m => m.Do("Something")) 

Vì vậy, đưa ra một danh sách các loại, tôi cần phải thay thế chúng cho T trong phương pháp trên và gọi.

Đây là nơi tôi đã nhận trước khi đầu tôi để quay sang putty:

var mapped = typeof(Action<OtherObject<>>).MakeGenericType(t.GetType()); 
Activator.CreateInstance(mapped, new object[] { erm do something?}); 

typeof(OtherObject) 
    .GetMethod("TheMethod") 
    .MakeGenericMethod(t.GetType()) 
    .Invoke(model, new object[] { new mapped(m => m.Do("Something")) }); 

Cập nhật: Để làm rõ, tôi có một danh sách các loại và tôi muốn thực hiện cùng một phương pháp được biết đến của OtherObject cho mỗi . Pseudo-code:

foreach(var t in types) 
{ 
    mainObject.TheMethod<t>(mo => mo.Do("Something")) 
} 

(Kiểu của tham số cho TheMethod() là Action<OtherObject<T>> như đã nêu trên)

FluentNHibernate.Automapping.AutoPersistenceModel Override<T>(System.Action<AutoMapping<T>> populateMap) 

hành động là như nhau của AutoMapping<T>.Where("something")

model.Override<Message>(m => m.Where("DeletedById is null")) 

Bây giờ, làm điều đó cho một loạt các loại :)

+2

là cơ thể của hành động luôn luôn giống nhau, ví dụ luôn 'm.Do ("Something") '? –

+0

có, thêm một số làm rõ ở trên –

+0

Câu trả lời của tôi có giúp ích cho bạn không? –

Trả lời

3

Bạn có thể giải quyết điều này bằng cách sử dụng các biểu thức:

foreach(var t in types) 
{ 
    var mapped = typeof(AutoMapping<>).MakeGenericType(t); 

    var p = Expression.Parameter(mapped, "m"); 
    var expression = Expression.Lambda(Expression.GetActionType(mapped), 
             Expression.Call(p, mapped.GetMethod("Do"), 
             Expression.Constant("Something")), p); 

    typeof(SomeOtherObject).GetMethod("TheMethod").MakeGenericMethod(t) 
          .Invoke(model, new object[] { expression.Compile() }); 
} 

UPDATE: Toàn bộ ví dụ làm việc (dán vào LINQPad và chạy nó):

void Main() 
{ 
    var types = new []{typeof(string), typeof(Guid)}; 
    SomeOtherObject model = new SomeOtherObject(); 
    foreach(var t in types) 
    { 
     var mapped = typeof(AutoMapping<>).MakeGenericType(t); 

     var p = Expression.Parameter(mapped, "m"); 
     var expression = Expression.Lambda(
          Expression.GetActionType(mapped), 
          Expression.Call(p, mapped.GetMethod("Do"), 
          Expression.Constant("Something")), p); 

     typeof(SomeOtherObject).GetMethod("TheMethod") 
           .MakeGenericMethod(t) 
           .Invoke(model, 
             new object[] { expression.Compile() }); 
    } 
} 

class AutoMapping<T> 
{ 
    public void Do(string p) 
    { 
     Console.WriteLine(typeof(T).ToString()); 
     Console.WriteLine(p); 
    } 
} 

class SomeOtherObject 
{ 
    public void TheMethod<T>(Action<AutoMapping<T>> action) 
    { 
     var x = new AutoMapping<T>(); 
     action(x); 
    } 
} 
+0

Xin lỗi vì đã trả lời muộn. Đã đặt nó vào đúng vị trí. Tôi đang nhận được loại dự kiến ​​về điều này: var mapped = typeof (Hành động >). MakeGenericType (t); –

+0

Bạn đang sử dụng phiên bản .NET nào? Và bạn có thể vui lòng cho tôi thông báo lỗi hoàn chỉnh không? Tôi cho rằng đây là lỗi biên dịch? –

+0

@BobTodd: Vui lòng xem mã cập nhật. Thử cái này. –

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