据我了解,委托(delegate)提供高性能反射,可能只比常规显式 C# 代码慢 15%。然而,我在 stackoverflow 上找到的所有示例都是基于通过委托(delegate)访问的方法/属性类型的先验知识。
鉴于对类有这样的先验知识,为什么首先要诉诸反射的委托(delegate)访问?
无论如何,我面临的反射编码任务是如何对未知的类属性列表实现高性能属性获取/设置访问,其中在运行时仅提供类类型名称?我可以编写反射检查的基础知识来生成属性列表,但是如何为一组可能随机的属性类型连接一组基于委托(delegate)的访问器?
假设属性类型仅限于一系列基本数据库列类型,则 case 语句返回:
Func<int> or Func<string> etc?
Edit-1:我仅限于 .Net 3.5
最佳答案
此解决方案使用表达式树,因为它们相当容易编写,并且它们提供了方便的 Compile() 方法来获取可以调用的实际委托(delegate)。我让 Func 实际上接受对象(因此 Func
编辑:还添加了 setter 实现。
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();
}
}
首先使用动态 setter 将其设置为“Hello”,然后使用动态 getter 从对象获取属性,从而打印出“Hello”。
关于c# - 运行时反射类的属性获取/设置委托(delegate),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3672377/