Một đại biểu mở là một đại biểu cho một phương pháp thể hiện mà không có đích. Để gọi nó, bạn cung cấp các mục tiêu như là tham số đầu tiên của nó. Họ là một cách thông minh để tối ưu hóa mã mà nếu không sẽ sử dụng sự phản chiếu và có hiệu suất kém. Để có giới thiệu cho các đại biểu mở, hãy xem this. Cách bạn sẽ sử dụng nó trong thực tế là phải có mã phản chiếu đắt tiền để xây dựng các đại biểu mở này, nhưng sau đó bạn sẽ có thể gọi chúng rất rẻ như một cuộc gọi Đại biểu đơn giản.Tạo một đại diện mở có hiệu suất cho một trình thiết lập thuộc tính hoặc getter
Tôi đang cố gắng viết mã sẽ biến đổi một PropertyInfo tùy ý, thành một đại biểu cho trình thiết lập của nó. Cho đến nay tôi đã đưa ra điều này:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
namespace Test
{
class TestClass
{
static Action<T, object> MakeSetterDelegate<T>(PropertyInfo property)
{
MethodInfo setMethod = property.GetSetMethod();
if (setMethod != null && setMethod.GetParameters().Length == 1) //skips over nasty index properties
{
//To be able to bind to the delegate we have to create a delegate
//type like: Action<T,actualType> rather than Action<T,object>.
//We use reflection to do that
Type setterGenericType = typeof(Action<,>);
Type delegateType = setterGenericType.MakeGenericType(new Type[] { typeof(T), property.PropertyType });
var untypedDelegate = Delegate.CreateDelegate(delegateType, setMethod);
//we wrap the Action<T,actualType> delegate into an Action<T,object>
Action<T, object> setter = (instance, value) =>
{
untypedDelegate.DynamicInvoke(new object[] { instance, value });
};
return setter;
}
else
{
return null;
}
}
int TestProp
{
set
{
System.Diagnostics.Debug.WriteLine("Called set_TestProp");
}
}
static void Test()
{
PropertyInfo property = typeof(TestClass).GetProperty("TestProp");
Action<TestClass, object> setter = MakeSetterDelegate<TestClass>(property);
TestClass instance = new TestClass();
setter(instance, 5);
}
}
}
Mã tương tự sẽ được viết cho getter. Nó hoạt động, nhưng các đại biểu setter sử dụng một DynamicInvoke để chuyển đổi từ một hành động <derivedType
> sang hành động <object
>, mà tôi nghi ngờ là ăn một phần tốt của tối ưu hóa tôi sau. Vì vậy, các câu hỏi là:
- DynamicInvoke có phải là mối quan ngại thực sự không?
- Có cách nào xung quanh nó không?
Bạn có thể xây dựng trên câu trả lời của bạn? 1-Ý bạn là gì bởi "Phản chiếu chống lại một loại bên trong chung chung"; 2 - API Expression sẽ giúp tôi như thế nào? –
@David - ví dụ về biểu thức được thêm vào. Tôi sẽ roi lên một ví dụ loại bên trong chung chung –
@David - và thêm ví dụ kiểu chung bên trong –