tags:

views:

290

answers:

2

Hello

I have a function that accepts any object, then it gets values from the properties or fields that it has as input.

It currently looks like this:

private string GetFieldValue(object o, Field f)
{
 //field.name is name of property or field
        MemberInfo[] mi = o.GetType().GetMember(field.name, MemberTypes.Field | MemberTypes.Property,
            BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic | 
            BindingFlags.ExactBinding );

        if (mi.Length == 0) throw new ArgumentException("Field", "Can't find member: " + f.name);

        Object value;
        if (mi[0].MemberType == MemberTypes.Property)
             value = ((PropertyInfo)mi[0]).GetValue(o, null);
        else value = ((FieldInfo)mi[0]).GetValue(o);

Today I read about System.ComponentModel and its XXXDescriptor classes. What is the difference, when performance is in question, between 2 frameworks (Reflection & ComponentModel). Will rewriting the above using ComponentModel achieve better performance or flexibility ? The only other difference between those two that I know is support for virtual properties by CM.

Ty.

+3  A: 

TypeDescriptor (in System.ComponentModel) caches internally, so it can have better performance, though there's nothing stopping you adding a cache to the above code. TypeDescriptor uses reflection, although it allows you to extend your object and add properties and events that aren't backed by 'real' properties and events. TypeDescriptor doesn't support fields, however.

If I were you, and I didn't care about TypeDescriptor's extensibility features, and I was happy to add your own cache on top of GetMember, then I'd stick with reflection.

Edit: Standard reflection has cached MemberInfo objects since 2.0 -- see MSDN "Using .NET: Avoid Common Performance Pitfalls for Speedier Apps".

Tim Robinson
TypeDescriptor doesn't really do much more caching than stanadrd reflection - the main bottleneck is invoke, which is slow with either. But see my reply for how to improve this (with customisations around ComponentModel).
Marc Gravell
I always thought TypeDescriptor was cached (MSDN page on the TypeDescriptor class has "Properties and events are cached by TypeDescriptor for speed"), whereas reflection parses assembly metadata.
Tim Robinson
Isn't Reflection cashing MemberInfo already ? From MSDN: " The MemberInfo cache is lazily populated in the .NET Framework 2.0, which means lower working set cost, and less time to retrieve the method. If you know the name of the particular method you want to obtain, use the non-plural GetXX method."
majkinetor
I choosed non plural version becaue of that. The first solution was to iterate over all members and see what I need, but I abandoned that because of the above quote in favor of non-plural method.
majkinetor
Thanks for the caching tip -- I must have missed that way back on the 1.1-to-2.0 switch!
Tim Robinson
+5  A: 

The difference is that ComponentModel is an abstraction over raw classes. This means that you can define properties that don't exist - and indeed, that is exactly how DataView / DataRowView expose columns as properties for data binding. Using ComponentModel, the, you can get something like "dynamic" even in 1.1.

You might think that means that ComponentModel is slower; but actually, you can exploit this abstraction for gain... HyperDescriptor does exactly that - using Reflection.Emit to write direct IL to represent properties, giving much faster access than either reflection or vanilla ComponentModel.

Note, however, that ComponentModel is, by default, limited to properties (not fields). You can do it via on-the-fly PropertyDescriptor facades, but it isn't a good idea. There also isn't much place for a "write only" property in ComponentModel.

Marc Gravell