c# - 运行时反射类的属性获取/设置委托(delegate)

标签 c# delegates properties

据我了解,委托(delegate)提供高性能反射,可能只比常规显式 C# 代码慢 15%。然而,我在 stackoverflow 上找到的所有示例都是基于通过委托(delegate)访问的方法/属性类型的先验知识。

鉴于对类有这样的先验知识,为什么首先要诉诸反射的委托(delegate)访问?

无论如何,我面临的反射编码任务是如何对未知的类属性列表实现高性能属性获取/设置访问,其中在运行时仅提供类类型名称?我可以编写反射检查的基础知识来生成属性列表,但是如何为一组可能随机的属性类型连接一组基于委托(delegate)的访问器?

假设属性类型仅限于一系列基本数据库列类型,则 case 语句返回:

Func<int> or Func<string> etc? 

Edit-1:我仅限于 .Net 3.5

最佳答案

此解决方案使用表达式树,因为它们相当容易编写,并且它们提供了方便的 Compile() 方法来获取可以调用的实际委托(delegate)。我让 Func 实际上接受对象(因此 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/

相关文章:

c# - 关于 ComboBoxes、ValueMember 和 DisplayMember 的一些混淆

c# - 我应该使用 List<IObserver> 还是简单地使用 Action<T> 来跟踪 IObservable 的订阅者?

java - 有没有现成的组件可以将java *.properties文件转换成对应的json?

C# 从作为 Func<> 的委托(delegate)获取类型参数

iphone - _property 和 self.property 的区别

jquery - 如何从元素中获取内联 CSS 样式属性

C# KeyDown事件多个Key加ControlKey

c# - 在 C# 中将 Short[2] 转换为 Int32

C# 闭包堆分配发生在方法开始时

objective-c - id 类型实例变量向实例方法发送消息