Vì bạn đang lấy những Func<MyClass, object>
đại biểu trong thời gian chạy từ các nguồn khác, các loại thông tin được về cơ bản bị mất. Thay vào đó, khi các chức năng này được xác định, bạn có thể có những người gọi về cơ bản mã hóa thông tin kiểu đó trong một đại biểu được bọc bằng cách tận dụng LINQ Expression APIAPI (EDIT: Silly me, đơn giản hơn nhiều tại thời điểm này) có thông tin thời gian biên dịch generic):
public class MyClassDelegate
{
private readonly Func<MyClass, object> Function;
public Type ReturnType { get; private set; }
private MyClassDelegate(Func<MyClass, object> function, Type returnType)
{
this.Function = function;
this.ReturnType = returnType;
}
public object Invoke(MyClass context)
{
return Function(context);
}
public static MyClassDelegate Create<TReturnType>(Func<MyClass, TReturnType> function)
{
Func<MyClass, object> nonTypedFunction = o => function(o);
return new MyClassDelegate(nonTypedFunction, typeof(TReturnType));
}
}
(Một chung lớp có nguồn gốc MyClassDelegate<TReturnType> : MyClassDelegate
thể được thực hiện cũng như để có được xung quanh một số các sillyness trong phương pháp Create
, hoặc tránh giá trị kiểu đấm bốc, hoặc có sự trở lại loại thông tin có sẵn tại thời gian biên dịch hoặc thậm chí bằng cách phản ánh trên bất cứ điều gì MyClassDelegate<TReturnType>
là.)
Người gọi xác định các đại biểu thay vì làm việc trực tiếp với một Func<MyClass, object>
thay vào đó sẽ làm việc với các lớp này và xác định các đại biểu của họ như:
MyClassDelegate f1 = MyClassDelegate.Create(o => o.StringProperty);
MyClassDelegate f2 = MyClassDelegate.Create(o => o.Property.SomeMethod());
API của bạn sẽ yêu cầu một MyClassDelegate
, mà bạn có thể dễ dàng truy cập vào các loại của họ :
Console.WriteLine(f1.ReturnType.FullName); //string
Console.WriteLine(f2.ReturnType.FullName); //whatever `SomeMethod()` is declared to return
Cuối cùng, bạn có thể gọi các đại biểu hoặc thậm chí tạo Func<MyClass, object>
đại biểu vẫn còn:
f1.Invoke(myClassInstance);
Func<MyClass, object> f3 = f1.Invoke;
"Nhận" loại trả về chính xác như thế nào? Một ví dụ giả định? – Jon
@ Jon Tôi nghĩ rằng suy ra kiểu trả về dựa trên thực tế trình biên dịch biết điều này ('string' trong ví dụ đầu tiên, trả về' SomeMethod' trong lần thứ hai), tuy nhiên ví dụ này sẽ sụp đổ tại thời gian chạy dưới dạng biến 'f 'có thể được gán lại. Giả sử, nếu 'f' không thể được gán lại, bạn có thể xác định tĩnh kiểu trả về bằng cách phân tích định nghĩa' Func'. Âm thanh như một ứng cử viên cho Roslyn ;-) –
Tùy thuộc vào mức sử dụng của bạn, có lẽ bạn có thể tận dụng API 'Expression' để kiểm tra kiểu trả về: http://stackoverflow.com/questions/671968/retrieving-property-name-from- lambda-expression (đây không phải là việc thực hiện chính xác những gì bạn đang cố gắng làm, chỉ là một ví dụ liên quan) –