TypeDescriptor性能

时间:2012-02-14 07:47:30

标签: c# performance typedescriptor

我创建了一个简单的方法来返回一个属性,我知道这是一个来自对象属性层次结构的字符串。例如,对象与具有子属性“Contact”的属性“Person”的“契约”和子属性(已知已经是一个字符串)“PhoneNumber”

我打算将该方法用于特定的动态绑定目的。

调用该方法如下所示:GetProperty(contract,“Person.Contact.PhoneNumber”);

我想知道以下代码的性能影响:

 public string GetProperty(object obj, string name)
    {
        string[] index = name.Split('.');
        object result = null;


        for (int i = 0; i < index.Length - 1; i++)
        {
            result = TypeDescriptor.GetProperties(obj).Find(index[i], true).GetValue(obj);

            if (result == null)
                return null;

            obj = result;
        }

        PropertyDescriptor pd = TypeDescriptor.GetProperties(result).Find(index.Last(), true);

        return (string)pd.GetValue(result);
    }

谢谢!

2 个答案:

答案 0 :(得分:6)

如果名称已知且已修复,则一个简单的方法是:

dynamic obj = ...
string name = obj.Person.Contract.PhoneNumber;

dynamic实施内部优化,因此不会每次都进行大量反射 - 它仅按类型解析。

至于“有多快”,您需要对其进行分析 - 但是,常规反射实现基于PropertyInfo,而且光荣快。对于临时使用来说足够快,但是在紧密的循环中,不是那么好。

如果你想要优化和更灵活,而不是使用dynamic(你需要编译时的名字),那么也许FastMember;这有基于类型和基于实例的API,并且是有意优化的;用于任意属性获取:

var acc = ObjectAccessor.Create(obj);
string propName = "PhoneNumber";
var value = acc[propName];

在那篇文章中,我还提到了HyperDescriptor,这是一个使用PropertyDescriptor API的先前实现(但已经过优化) - 但是,除非你需要 PropertyDescriptor实现,我认为没有必要强制使用它。

答案 1 :(得分:1)

一如既往,测试一下。我建议一个更好的选择。

  1. 使用反射(或TypeDescriptor的方法)检索所有属性。
  2. 使用dynamic methodsexpression trees创建getter / setter。
  3. Dictionary
  4. 中缓存这些getter / setter
  5. 让您的方法查看字典并调用getter / setter。
  6. 根据我的经验,这将比在运行时发现有关成员的信息的任何事情都更快(有时是显着的)。示例代码中的字符串操作,循环,多个方法调用等比使用基于键的查找和调用单个方法要昂贵得多。

    documentation on TypeDescription表示缓存在内部用于提高性能,因此如何它所带来的大部分差异只能通过测试来揭示。