這個解決方案使用表達式樹,因爲它們相當容易編寫,並且它們提供了方便的Compile()方法來獲取可以調用的實際Delegate。我做了Func鍵採取實際的對象(所以Func鍵< T,TResult >而不僅僅是Func鍵<TResult>),這樣你可以從任何實例的屬性值。
編輯:添加二傳手實施爲好。
public class MyClass
{
public string MyStringProperty { get; set; }
}
class Program
{
static void Main(string[] args)
{
PropertyInfo propertyInfo = typeof(MyClass).GetProperty("MyStringProperty");
Delegate getter = CreateGetter(propertyInfo);
Delegate setter = CreateSetter(propertyInfo);
object myClass = new MyClass();
setter.DynamicInvoke(myClass, "Hello");
Console.WriteLine(getter.DynamicInvoke(myClass));
}
public static Delegate CreateGetter(PropertyInfo property)
{
var objParm = Expression.Parameter(property.DeclaringType, "o");
Type delegateType = typeof(Func<,>).MakeGenericType(property.DeclaringType, property.PropertyType);
var lambda = Expression.Lambda(delegateType, Expression.Property(objParm, property.Name), objParm);
return lambda.Compile();
}
public static Delegate CreateSetter(PropertyInfo property)
{
var objParm = Expression.Parameter(property.DeclaringType, "o");
var valueParm = Expression.Parameter(property.PropertyType, "value");
Type delegateType = typeof(Action<,>).MakeGenericType(property.DeclaringType, property.PropertyType);
var lambda = Expression.Lambda(delegateType, Expression.Assign(Expression.Property(objParm, property.Name), valueParm), objParm, valueParm);
return lambda.Compile();
}
}
打印出「你好」通過首先使用動態設置器將其設置爲「你好」,然後使用動態吸氣劑,以獲得來自對象的屬性。
你正在尋找的typeof(Func鍵<>)。MakeGenericType(myDbType);?或者你是否也需要執行委託?此外,** events **的概念是代表們常用的基於非反射的使用場景。 Enumerable的擴展方法也爲代表/ lambdas的實用程序提供了大量示例。 – 2010-09-08 22:48:53
@Kirk。對於需要通過委託設置者填充的每個類,我需要保存這些設置者的數組。當填充委託設置器的數組時,我需要根據我剛剛通過反射發現的Property類型來製作Delegate。 MakeGenericType()似乎是我缺失的鏈接。 – camelCase 2010-09-09 06:33:21