Reflection lets you examine at runtime the same information used by the compiler at compile time. Consequently, anything you can do with reflection can be done without reflection during compilation. This doesn't mean reflection has no use: you may not know what exact question you want to ask until runtime.
If you know something at compile time, express it in the type system. This will allow you to catch mistakes at compile time. For example,
string propVal = myObj.SomeProperty;
Here we are saying that we know for sure at compile time that myObj
has a property called SomeProperty
that is of a type that is assignable to string
- and in fact, although it isn't visible here, we must also have specified a class or interface type of myObj
.
string propVal = (string)myObj.GetType()
.GetProperty("SomeProperty")
.GetValue(myObj, null);
Here we are saying that myObj
might have that same property - or it might not (in which case we'll get an exception at runtime).
The second one, using reflection, looks butt-ugly, but in C# 4.0 it will look practically identical. It is often held to be slower too, but that depends on the context, and will probably be less true of the dynamic features in C# 4.0.
The real distinction remains, though: the statically typed version helps us find mistakes during compilation, instead of delaying this discovery until runtime.
So if you want to make full use of the static type system to catch bugs during compilation, then try to state your assumptions via the type system, which is equivalent to saying: avoid reflection except where really necessary.