tags:

views:

1701

answers:

16

I understand the reflection API (in c#) but I am not sure in what situation would I use it. What are some patterns - anti-patterns for using reflection?

+1  A: 

I'm not about to drop any patterns, but I would suggest that it's a good idea to avoid reflection until you actually need it. It's especially useful for interop and extensibility situations where you cannot control ahead of time the type of an object.

Randolpho
+6  A: 

I don't know if it is a pattern but I use reflection to generate SQL from DAO's class definitions.

Otávio Décio
Why are you recreating NHibernate? Just use the real deal.
Justice
One of the reasons is because my DAL predates NHibernate. I considered switching but just didn't want to deal with the xml configuration mess. For my use what I have is way cleaner. But thank you for the suggestion.
Otávio Décio
+5  A: 

There is no hard and fast rule. Basically, you don't use reflection without a good reason. Use reflection when you can't do what you want without it, or when your code would be much longer or more difficult to understand without reflection.

Glomek
+10  A: 

The only place I've used the Reflection stuff in C# was in factory patterns, where I'm creating objects (in my case, network listeners) based on configuration file information. The configuration file supplied the location of the assemblies, the name of the types within them, and any additional arguments needed. The factory picked this stuff up and created the listeners based on that.

Harper Shelby
Done the same with a database table -- activating new features / deactivating obsolete features by just editing a database record... Love it! +1
Austin Salonen
Same here. Basically using Type.GetType followed by Activator.CreateInstance
Dmitri Nesteruk
A: 

I went for 2 years of development without understanding the purpose of reflection. It has very niche uses, but is extremely powerful when it is the right tool for the job.

I think what I'm trying to say is only use it when you are sure it's the only way to achieve what you want.

Garry Shutler
+7  A: 

In one product I'm working on we use it a lot, but Reflection is a complex, slow beast. Don't go looking for places to use it just because it sounds fun or interesting. You'll use it when you run into a problem that can't be solved in any other way (dynamically loading assemblies for plug ins or frameworks, assembly inspection, factories where types ren't know at build, etc). It's certainly worth looking at reflection tutorials to see how it works, but don't fall into the trap of "having a hammer and everything looking like a nail." It's got very specialized use cases.

ctacke
+1! Reflection is complex, slow and circumvents compile-time checking. Overusing it will make your project hard to maintain.
Kevin Thiart
+1  A: 

I use it in a case similar to that mentioned by Harper Shelby, in which a configuration file specifies at runtime which object to instantiate. In my particular case there's nothing as elaborate as a factory--only a set of classes that implement a common interface, and a simple function that reads the configuration file and creates the proper object, returning the interface.

JSBangs
A: 

I most often use it when I need to break somebody else's (usually the framework's) encapsulation. That is, I need to change some private field, or call a private method, or create an instance of some internal class in a library I have no power to change. A good example is the code in my answer to this question. In this case, the behavior of the framework method ServiceBase.Run was unacceptable, so I used reflection to do the same thing it does in a more acceptable manner.

Reflection has many other uses, though, including duck typing, working with attributes, and late binding.

P Daddy
If you're breaking someone else's encapsulation, chances are you're doin' it wrong.
abelenky
On the contrary. I'm usually doing it right because they did it wrong.
P Daddy
but its still broken, no matter which way you look at it :)
gbjbaanb
And thankfully we have reflection, allowing us to fix it. Don't delude yourself into thinking you'll never have to deal with somebody else's broken code. And anyway, a library author can never foresee every use you'll have for their code. With encapsulation, this is compounded.
P Daddy
A: 

I use reflection a fair amount in my unit tests, especially when the things I'm checking are anonymous types. I've also used it as a way to easily clone/copy model objects. Rather than write the code to do this for every model object, I can easily create an object of a particular type using reflection, interrogate the incoming object's public properties and invoke the settors on the cloned objects corresponding properties. I also use it with designer generated classes that implement the same method signatures, but don't have an associated interface. In those cases, I can interrogate the object to see if it has the required method and invoke it if it does. LINQ2SQL entities are like this so in my fake data context wrapper OnSubmit method I use reflection to get the OnValidate method and invoke it for unit testing.

tvanfosson
+1  A: 

I use it in a binary serializer (protobuf-net). I use reflection only to build the model - when it is used (i.e. during [de]serialization) it is using delegates etc for maximum performance.

I also used it (along with ComponentModel and Reflection.Emit) in HyperDescriptor, to build accelerated property access (~100x the speed of regular reflection).

And by necessity, you need to use reflection if you are building your own Expressions.

Marc Gravell
A: 

Use reflection as little as possible.

moffdub
+1  A: 

+1 on the factory pattern usage -- very powerful there.

Aside from the factory pattern, every time I've used it, I probably shouldn't have...

I've used it to dynamically load classes that implement certain interfaces (mine were menu items from assemblies) at startup and I really regret that usage. I wish I would've loaded from a config file (and later added a form that showed available interfaces to load). It's cool but terribly slow...

An anti-pattern is to use it access properties that class designers marked as private without knowing why they marked them as private. I've done this with the DataGridView WinForms control to unset a boolean variable so I could have a "companion" column move when its complement was moved. Once again, it's very cool but that code will fail horribly if a new release changes that private property (it very well could be gone in 3.0 or 3.5...).

Austin Salonen
+4  A: 

I find reflection (combined with runtime class loading) indispensable for implementing plugins:

  1. search for jars / assemblies in a known location
  2. enumerate jars / assemblies for classes supporting the interface your plugin supports
  3. instantiate the plugin at runtime
JeffV
+1  A: 

Reflection allows you to solve problems that would otherwise require you to duplicate code. If you find yourself copying and pasting code, and can't see how an OO pattern can help, maybe if you can call them, then the "r team" can help.

Only joking. I couldn't understand the point of reflection for ages. If you can write code to perform a job, why do you need to use reflection at all?

Say you have lots of GUI objects like Forms or 'table' objects. It binds to a business object like a Customer:

public class Customer
{
   public string FirstName;
   public string LastName;

}

Your users don't want to see the column headings 'FirstName' or 'LastName'. They want 'Christian Name' and Surname. You don't want to code the literal strings in all your GUI objects in case they change their minds to 'First Name' and 'Father's last name' (I know , crap example).

If you define your class using attributes:

public class Customer
{
   [Description("Christian Name")]
   public string FirstName;

   [Description("Surname")]
   public string LastName;

}

You can use reflection to pull out the column names. If you need to change the way all your GUI objects describe the customer object, you now do it in one place.

I am not aware of any anti-patterns. My advice is to jump in and try it. You will start to see all sorts of ways in which reflection gives you an elegant solution. Performance is often cited as a reason for not using relfection. There is a performance overhead with relfection but I would discount it unless you can prove the overhead is hurting an algorithm you need.

Jimmy McNulty
+1: Reflection does reduce code duplication.-1: Compile-time checking is a far more important reason not to use reflection.The reflection in the example is part of the framework, not implemented by the developer. For any reflection not implemented in the framework I'd seriously try to rethink my approach.You'll find that the string literals containing code can get just as difficult to maintain as the duplicate code you tried to avoid. Here code generation might be a good alternative.
Kevin Thiart
A: 

I have used reflection in a number of places. The main broad categories include:

  1. Auto-generated GUIs (ie, a property editor). You can loop over the properties of an object and use a registry of UI element factories to build a form. I use attributes on properties to guide the UI creation.
  2. Serialization. I have written serialization frameworks the use reflection to serialize and deserialize objects.
  3. Web Services. Similar to serialization, I have used reflection to create and consume SOAP messages and also to generate WSDL.
  4. Domain Specific Languages. Interpreted scripting languages will typically bind to objects and methods using reflection.
  5. Debugging tools. Such tools can use reflection to examine the state of an object. Handy for creating log messages under fault conditions.

Patterns wise, I'm not sure what the patterns are. A common thread between all the uses is reference by name and late binding - you want to bind to a member at runtime. This is often the case when you dynamically load assemblies and do not know the types of objeccts you need to create/manipulate.

Using reflection is powerful, but it wont make you more popular at parties. Only use it where the coupling is intentionally weak. So weak that you expect it to break at runtime. A great example is data binding in WPF.

I'm unsure about anti-patterns, but surely it would relate to doing things at runtime that should be done at compile time...

Daniel Paull
A: 

The prime place I use reflection: Pulling a type out of a database.

I have a class that needs to know which library to call. Keep in mind that as new tools are added to the list, the class needs to recognize the new tools without a recompile, so a switch statement is out of the question.

Instead, I store the reflection string in the DB that tells the class to "create one of these..." Since I (the programmer) always ensure that the class is derived from a single base class, the idea works. It's clean and efficient.

But I agree that if you use reflection for more than these "auto-generated code" scenarios, then you could be opening yourself up for a world of hurt when it comes to maintaining the code in the future.

(enter voice of wise, old sage)
Reflection comes with incredible power... use the power with wisdom.

Jerry