简体   繁体   English

属性获取/设置运行时反射类的代理

[英]Property get/set Delegates for runtime reflected class

I understand that Delegates offer high performance reflection maybe just 15% slower than regular explicit c# code. 据我所知,Delegates提供的高性能反射可能比常规显式c#代码慢15%。 However all the examples I can find on stackoverflow are based on prior knowledge of the type of a method/property being accessed via a delegate. 但是,我可以在stackoverflow上找到的所有示例都基于通过委托访问的方法/属性类型的先验知识。

Given such prior knowledge of a class, why resort to reflected Delegate access in the first place? 鉴于此类先前的知识,为什么首先要反映代表访问?

Anyhow the reflection coding task I face is how to implement high performance property get/set access for an unknown list of class properties where just a class type name is supplied at runtime? 无论如何,我面临的反射编码任务是如何为未知的类属性列表实现高性能属性获取/设置访问,其中只在运行时提供类类型名称? I can code the basics of reflection inspection to produce a list of properties but how do I wire up a set of Delegate based accessors for a potentially random set of property types? 我可以编写反射检查的基础知识来生成属性列表,但是如何为一组可能随机的属性类型连接一组基于委托的访问器?

Assuming the property types are limited to a range of basic DB column types is the answer a case statement that returns a: 假设属性类型仅限于一系列基本DB列类型,则返回一个case语句的答案:

Func<int> or Func<string> etc? 

Edit-1: I am limited to .Net 3.5 编辑-1:我仅限于.Net 3.5

This solution uses expression trees since they're fairly easy to compose, and they provide the handy Compile() method to get an actual Delegate upon which you can invoke. 这个解决方案使用表达式树,因为它们相当容易编写,并且它们提供了方便的Compile()方法来获取可以调用的实际Delegate。 I made the Func actually take in the object (so Func<T, TResult> rather than just Func<TResult>) so you can obtain the property value from any instance. 我让Func实际上接受了对象(所以Func <T,TResult>而不仅仅是Func <TResult>)所以你可以从任何实例获取属性值。

Edit : Added setter implementation as well. 编辑 :添加了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();
    }
}

Prints out "Hello" by first using the dynamic setter to set it to "Hello" and then using the dynamic getter to obtain the property from the object. 通过首先使用动态setter将其设置为“Hello”然后使用动态getter从对象获取属性来打印出“Hello”。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM