I cringe whenever I spot code that uses System.Reflection. It’s a powerful weapon in our arsenal of .NET programming techniques — and a dangerous one.
These patterns get overused in many .NET frameworks and toolkits. Some of that stems from a desire to avoid complex configuration. Some of it comes from the natural envy programmers in stuffy statically typed languages feel regarding their freewheeling counterparts using dynamically typed languages.
(Wikipedia has a good article exploring the differences in type checking in computer language type systems, if you’re curious about the different paradigms. But I digress.)
System.Reflection two main uses, as Marc Gravell points out in his answer regarding what problems Reflection solves on StackOverflow:
These two capabilities allow you to shoehorn dynamic or late-binding features into C# applications. In other words, it’s a clever hack.
Want to enable Ruby-style convention over configuration in your C# framework? Use reflection! Want to reach into
internal methods for unit testing? Use reflection! Want to add some duck typing goodness to your statically typed language? Use reflection!
The System.Reflection API has some big drawbacks. The performance penalty incurred by reflection is well known. Less well known is that the Reflection API is really difficult to use, especially when inspecting and creating constructor method parameters. So most framework developers skip the hard bits.
This means that most of these frameworks will insist on your using constructors without parameters in your classes. (Sometimes people call parameter-less constructors “default constructors” though it isn’t the same thing.)
But if you can’t use parameters in the constructors of your objects, you’re doing object-oriented programming with one hand tied behind your back.
For example, it’s difficult to achieve object immutability without using a constructor. You’ll also have a hard time enforcing business rules without constructors. And if you’re a fan of dependency injection, you’ll have to implement it via
Init() methods or property setters, both of which can cause significant headaches.
So if you work with a framework or API that makes heavy use of reflection, and thus restricts the sort of constructors you use, prepare yourself for significant pain.