Is it definitely a good practice to use it?
What are some possible situations in a project that need reflection?
Reflection is just a way of investigating objects during run-time. You shouldn't use it if you don't need to do just that.
The very useful XmlSerialization class relies on reflection. You don't have to deal with reflection yourself to use serialization, the serialization classes invoke reflection themselves. But it helps to tag your code with Attributes that guide how objects are serialized. The serialization classes use reflection at runtime to read those attributes. In the end, the process seems almost magical, requiring very few lines of explicit coding in a application; it's reflection that makes that convenience possible.
XmlSerialization itself is awesome not only because it is a very convenient way to create data files from an application, it's also a very easy means of generating human readable records of a program's internal data model for debugging purposes.
There are many uses for reflection:
However, one of my favorite uses of reflection is to find properties that have been marked with attributes.
For example, I've written attributes that mark which properties in my classes should be indexed using Lucene. At runtime, I can look at any class, and figure out what fields need to get indexed by just querying the class for "marked" properties.
The main value of Reflection is that it can be used to inspect assemblies, types, and members. It's a very powerful tool for determining the contents of an unknown assembly or object and can be used in a wide variety of cases.
Opponents of Reflection will cite that it is slow, which is true when compared to static code execution--however Reflection is used throughout the .NET framework, and provided that it's not abused it can be a very powerful tool in the toolkit.
Some useful applications:
Determining dependencies of an assembly
Location types which conform to an interface, derive from a base / abstract class, and searching for members by attributes
(Smelly) testing - If you depend on a class which is untestable (ie it doesn't allow you to easily build a fake) you can use Reflection to inject fake values within the class--it's not pretty, and not recommended, but it can be a handy tool in a bind.
Debugging - dumping out a list of the loaded assemblies, their references, current methods, etc...
As mentioned above, performance will take a hit.
Another great advantage is that you can dynamically load assemblies, perform property manipulation even though you may not have the scope to see what to change, etc.
The reasons to use this are plenty. Here is an introduction if you need.
Coming from C++ and having needed some simple class hierarchies, I can say that the is
keyword is invaluable!
class MenuItem : Item { }
foreach(Item items in parent.ChildItems) {
if (item is MenuItem) { /* handle differently */ }
}
P.S. Isn't reflection slightly expensive, btw?