Reflection is one of the features of .Net that when used with care can provide great power and flexibility. Its use is often discouraged as being “slow”, though it’s used to enable many features of .Net that are core to .Net’s power. It’s as though Reflection is “good” when the framework uses it without the need to get our hands dirty, but “bad” if we actually dare use it directly. Sure, it’s slower then using typed references. But what is too “slow”? Does a solution using Reflection make it impossible to meet your performance requirements? Do you have a formal performance requirement?
There are some solutions that can be implemented quite easily with Reflection that would be painful to do without. One thing about Reflection that often got in my way is its complexity. Like many powerful features there’s a lot of options to consider when Reflecting. Or is there? While there are all kinds of things you CAN do, there’s probably a very small subset that you’ll actually need 90% of the time.
So how to make life easier? Certainly a nice Facade to simplify the API, but I never really had one I liked/was comfortable enough with to use Reflection regularly.
Enter extension methods. Using some simple extension methods I now have a Reflection Facade that is natural and trivial to use. One day I was doing some Javascript work and really enjoying the simplicity of statements like
for (prop in myObj) { fn( myObj[prop] ); }
to operate on all the properties of an object. I wanted to be able to do something similar in .Net. The first order of business was to easily get all properties of an object
using System; using System.Reflection; using System.Collections.Generic; using System.Linq; namespace Extensions.Reflection { public static class ObjectExtension { public static IEnumerable Properties(this object obj) { BindingFlags flags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.GetProperty; var propInfos = obj.GetType().GetProperties(flags); return (from property in propInfos select property.Name); } } }
That will allow the following on any object
using Extensions.Reflection; ... for (var prop in myObj.Properties()) { ... }
Next let’s get a property’s value :
public static object Properties(this object obj, string property) { BindingFlags flags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.GetProperty; var propInfo = obj.GetType().GetProperty(property, flags); return propInfo.GetValue(obj, flags & BindingFlags.GetProperty, null, null, null); }
to get us to
for (var prop in myObj.Properties()) {
fn( myObj.Properties(prop) );
}
Because PropInfo.GetValue returns an object it may be necessary to cast the return value in the caller. So let’s add one more method that can be used if the return type is known.
public static T Properties<T>(this object obj, string property) { BindingFlags flags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.GetProperty; var propInfo = GetPropertyInfo(obj, property, flags); return (T) propInfo.GetValue(obj, flags & BindingFlags.GetProperty, null, null, null); }
Now, you’ll probably only use Properties<T> in specialized cases. If you’re going to call it with a known return type at design time you probably also know the property name and should call the property directly. But suppose you have a special generic method that you know will be calling a String property, but you won’t know which object or property until run-time. Properties<String> could be used to Reflectively get the property value without having to cast in the calling code.
Finally, let’s set the property’s value
public static object Properties(this object obj, string property, object value) { BindingFlags flags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.GetProperty; var propInfo = obj.GetType().GetProperty(property, flags); object result; if (propInfo.CanWrite) { propInfo.SetValue(obj, value, null); result = value; } else { result = propInfo.GetValue(obj, flags & BindingFlags.GetProperty, null, null, null); } return result; }
This extension method takes the property name and a value to set the property to. This implementation returns the value just set. Now, the property may be read only, in which case the method returns the current value of the property instead of the new value. You may want different behavior, but it works for me. There’s no error and I can compare the new and returned values to see if they’re different and decide what to do next.
Now, setting a value isn’t quite as nice as the associated Javascript, but it’s quite servicable.
Javascript:
for (prop in myObj) { myObj[prop] = aValue; }
.Net :
for (var prop in myObj.Properties()) { myObj.Properties(prop, aValue); }
Now this code ignored any Reflection exceptions for the sake of brevity. You may want to handle situations where the property doesn’t exist on the object. But it doesn’t complicate it much to add such code.
Reflection can do much more if you need it. You can access protected and private methods if you want, but do you need to (should you) most of the time? No. In keeping with C# conventions the property names are case sensitive, but you could use the BindingFlags.IgnoreCase flag to be more VB like.
What ever your need, these simple methods make Reflection much easier to use. If you don’t need reflection, no problem. But when it would make life easier, just add using Extensions.Reflection; and you have full intellisense at your finger tips, property reflection on every object and a simple API.
I like to use Reflection where it makes the job easier, code simpler and let’s me get things done quickly. Where it proves to be responsible for a performance issue I will re-work just that part to not use Reflection.