Search code examples
c#performancetypedescriptor

TypeDescriptor Peformance


I've created a simple method to return a property I know is a string from a hierarchy of properties in an object. Eg the object "contract" with the property "Person" with the Subproperty "Contact" and the subproperty (known already to be a string) "PhoneNumber"

I intend to use the method for a specific dynamic binding purpose.

Invoking the method would look like: GetProperty(contract, "Person.Contact.PhoneNumber");

I was wondering what the performance implications are of the following code:

 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);
    }

Thanks!


Solution

  • If the names are known and fixed, a simple approach is:

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

    The dynamic implementation is optimized internally, so this won't do massive amounts of reflection each time - it is resolved per-type only.

    As for "how fast", you'd need to profile it - however, the regular reflection implementation is based on PropertyInfo, and is not gloriously fast. Fast enough for ad-hoc use, but in a tight loop, not so great.

    If you want optimised and more flexibly than using dynamic (where you need the names at compile), then maybe FastMember; this has both type-based and instance-based APIs, and is deliberately optimized; usage for an arbitrary property fetch:

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

    In that article, I also mention HyperDescriptor, a previous implementation that uses the PropertyDescriptor API (but optimized is) - however, unless you need the PropertyDescriptor implementation, I see no need to enforce using it.