Question

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!

Was it helpful?

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.

OTHER TIPS

As always, test and see. I suggest a potentially better alternative.

  1. Retrieve all properties once using reflection (or the methods of TypeDescriptor).
  2. Create getters/setters using dynamic methods or expression trees.
  3. Cache those getters/setters in a Dictionary.
  4. Have your method look to the dictionary and invoke the getter/setter.

In my experience, this will always be faster (sometimes significantly) than anything which involves discovering information about a member at runtime. The string manipulation, looping, multiple method calls, etc. in your sample code looks far more expensive than using a key-based lookup and calling a single method.

The documentation on TypeDescription states that caching is used internally for performance, so how much of a difference it makes can only be revealed with testing.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top