简体   繁体   English

在C#中按名称获取和保留属性引用的最佳方法是什么

[英]What is the best way get and hold property reference by name in c#

I want to know if there is a better way (than what I'm currently doing) to obtain and hold a reference to a property in another object using only the object and property string names. 我想知道是否有更好的方法(比我目前正在做的更好)来获取和持有仅使用对象和属性字符串名称的另一个对象中对属性的引用。 Particularly, is there a better way to do this with the new dynamic functionality of .Net 4.0? 尤其是,是否有更好的方法利用.Net 4.0的新动态功能来做到这一点?

Here is what I have right now. 这就是我现在所拥有的。

I have a " PropertyReference<T> " object that takes an object name and property name in the constructor. 我有一个“ PropertyReference<T> ”对象,该对象在构造函数中带有对象名称和属性名称。

An Initialize() method uses reflection to find the object and property and stores the property Getter as an Action<T> and the property Setter as an Func<T> . Initialize()方法使用反射来查找对象和属性,并将Getter属性存储为Action<T>而将Setter属性存储为Func<T>

When I want to actually call the property I do something like this: 当我想实际调用该属性时,请执行以下操作:

int x = _propertyReference.Get();

or 要么

_propertyReference.Set(2);

Here is my PropertyReference<T> code. 这是我的PropertyReference<T>代码。 Please dissect and make suggestions for improvement. 请剖析并提出改进建议。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using System.Xml;

namespace WindowsFormsApplication2
{
    public class PropertyReference<T> : IPropertyReference
    {
        public string ComponentName { get; set; }
        public string PropertyName { get; set; }
        public bool IsInitialized
        {
            get
            {
                return (_action != null && _func != null);
            }
        }

        Action<T> _action;
        Func<T> _func;

        public PropertyReference() { }

        public PropertyReference(string componentName, string propertyName)
        {
            ComponentName = componentName;
            PropertyName = propertyName;
        }

        public void Initialize(IEntity e)
        {            
            Object component = e.GetByName(ComponentName);
            if (component == null) return;

            Type t = e.GetByName(ComponentName).GetType();
            PropertyInfo pi = t.GetProperty(PropertyName);

            _action = (T a) => pi.SetValue(component, a, null);
            _func = () => (T)pi.GetValue(component, null);
        }

        public void Reset()
        {
            _action = null;
            _func = null;

        }

        public void Set(T value)
        {
            _action.Invoke(value);
        }

        public T Get()
        {
            return _func();
        }

    }
}

Note: I can't use the "Emit" functionality as I need this code to work on the new Windows Phone 7 and that does not support Emit. 注意:我不能使用“发射”功能,因为我需要此代码在新的Windows Phone 7上工作,并且不支持发射。

UPDATE: 更新:

Just did some speed tests after replacing: 更换后只是做了一些速度测试:

_action = (T a) => pi.SetValue(component, a, null);
_func = () => (T)pi.GetValue(component, null);

With

_action = Action<T>)Delegate.CreateDelegate(typeof(Action<T>),component,pi.GetSetMethod());
_func = (Func<T>)Delegate.CreateDelegate(typeof(Func<T>), component, pi.GetGetMethod());

As suggested by dtb below. 如以下dtb所建议。

Tested by making 100,000 calls to the Get() property. 通过对Get()属性进行100,000次调用进行了测试。 Here are the results. 这是结果。

_func = () => (T)pi.GetValue(component, null)

took about 200ms 花了大约200ms

_func = (Func<T>)Delegate.CreateDelegate(typeof(Func<T>), component, pi.GetGetMethod());

took about 10ms 花了大约10ms

Huge difference. 差异很大。 Wasn't expecting that, but cool! 没想到,但是很酷!

Still open to more improvements. 仍然需要更多改进。

You could obtain delegates directly representing the getter and setter method: 您可以获得直接代表getter和setter方法的委托:

object component;
PropertyInfo pi;

_action = (Action<T>)Delegate.CreateDelegate(typeof(Action<T>),
                                             component,
                                             pi.GetSetMethod());

_func = (Func<T>)Delegate.CreateDelegate(typeof(Func<T>),
                                         component,
                                         pi.GetGetMethod());

It really depends on how often you're going to be calling it. 这实际上取决于您要多久调用一次。 If it isn't massive throughput, then fine - but note that the reflection-based GetValue / SetValue are pretty slow. 如果不是很大的吞吐量,那很好-但是请注意,基于反射的GetValue / SetValue相当慢。 You could cache the delegates, but another simple approach might be to look at HyperDescriptor - this uses the same API as PropertyDescriptor (so you again get GetValue / SetValue ), but it uses dynamic methods underneath. 您可以缓存委托,但是另一种简单的方法可能是查看HyperDescriptor-它使用与PropertyDescriptor相同的API(因此您再次获得GetValue / SetValue ),但是它在下面使用了动态方法。 The API then is something like: 然后,API类似于:

PropertyDescriptor prop = TypeDescriptor.GetProperties(type)["PropertyName"];

or 要么

PropertyDescriptor prop = TypeDescriptor.GetProperties(obj)["PropertyName"];

then 然后

object value = prop.GetValue(component);
prop.SetValue(component, newValue);

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

相关问题 C#数据结构-引用调用对象属性的最佳方法是什么? - C# data structure - what is the best way to reference a calling object's property? C#保存XML数据的最佳方法 - C# Best way to hold xml data 在C#中,按字符串属性对对象列表进行排序并获得正确顺序的最佳方法是什么? - In C#, what is the best way to sort a list of objects by a string property and get correct order? 从C#关键字获取正确类型名称的最佳方法是什么? - What is the best way to get a proper type name from a C# keyword? 在C#中初始化公共属性的最佳方法是什么? - What's the best way to initialize a public property in C#? 在C#对象中实现动态属性的最佳方法是什么? - What is the best way to implement dynamic property in a C# object? 坚持学习 C# - 使用 OOB 和 TDD 启动您的第一个应用程序的最佳方式是什么? [等候接听] - Stuck with learning C# - What is best way to start your first app with OOB and TDD? [on hold] 除了 T4 [暂停] 从模板文件生成 C# 中的代码文件的最佳方法是什么 - What is the best way to generate code files in C# from template file apart from T4 [on hold] 使用C#从ColdFusion QueryBean获取值的最佳方法是什么 - What is the best way to get values from a ColdFusion QueryBean with C# 在C#中,递归获取父ID列表的最佳方法是什么? - In C#, what is the best way to get a list of parent Ids recursively?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM