Điều này được giải thích tốt nhất khi sử dụng mã. Tôi có một lớp chung chung có một phương thức trả về một số nguyên. Dưới đây là một phiên bản đơn giản nhằm mục đích giải thích ...Làm thế nào để tạo một Expression.Lambda khi một loại không được biết đến cho đến khi chạy?
public class Gen<T>
{
public int DoSomething(T instance)
{
// Real code does something more interesting!
return 1;
}
}
Khi chạy tôi sử dụng phản ánh để khám phá các loại một cái gì đó và sau đó muốn tạo một thể hiện của lớp Gen tôi cho rằng loại hình cụ thể. Điều đó thật dễ dàng và được thực hiện như thế này ...
Type fieldType = // This is the type I have discovered
Type genericType = typeof(Gen<>).MakeGenericType(fieldType);
object genericInstance = Activator.CreateInstance(genericType);
Bây giờ tôi muốn tạo một Biểu thức sẽ lấy tham số là một thể hiện của loại chung và sau đó gọi phương thức DoSomething thuộc loại đó. Vì vậy, tôi muốn Expression để thực hiện có hiệu quả này ...
int answer = genericInstance.DoSomething(instance);
... ngoại trừ tôi không có 'dụ' cho đến khi một số điểm sau khi chạy và genericInstance là loại được tạo ra như có thể thấy ở trên. nỗ lực của tôi lúc tạo Lambda của việc này là như sau ...
MethodInfo mi = genericType.GetMethod("DoSomething",
BindingFlags.Instance | BindingFlags.Public);
var p1 = Expression.Parameter(genericType, "generic");
var p2 = Expression.Parameter(fieldType, "instance");
var x = Expression.Lambda<Func<genericType, fieldType, int>>
(Expression.Call(p1, mi, p2),
new[] { p1, p2 }).Compile();
... để sau này tôi có thể gọi nó với một cái gì đó như thế này ...
int answer = x(genericInstance, instance);
Tất nhiên, bạn không thể cung cấp Func với các tham số cá thể và vì vậy tôi không có ý tưởng làm thế nào để tham số hóa thế hệ Lambda. Bất kỳ ý tưởng?
Một ý tưởng hay thực sự hiệu quả. Thật không may là lý do tôi muốn sử dụng một lambda biên soạn mạnh mẽ là hiệu suất. Sử dụng DynamicInvoke là khá chậm so với Lambda đã nhập. –
Có thể chụp các biến trong cây Biểu thức không? Tôi sẽ giúp nắm bắt genericInstance vì điều đó sẽ không bao giờ thay đổi. –
@PhilWright Hm, tôi hiểu rồi. Hãy để tôi xem những gì khác tôi có thể đến với. – vcsjones