views:

1684

answers:

22

I see a lot of C#, .net questions solved here using reflection. To me, a lot of them look like bending the rules at the cost of good design (OOP). Many of the solutions look unmaintenable and "scripty".

Is using reflection a good practice in general? Are there things that can only be solved by reflection?

edit:

Please give examples where reflection is the only good solution.

A: 

No its a heavy use of reflection by the dot net framework itself that has earned it so much popularity

use F# heavily uses reflection

Umair Ahmed
Can we say that a framework has different design requirements than the applications that use it?
Mank
No. MS is continuously giving more functionality based on reflection with each framework. eg 4.0 introduce dynamic types. that again is based on reflection
Umair Ahmed
+10  A: 

Reflection is sometimes the only way to do certain things. It is a very powerful tool that can at times be overused by someone that knows reflection really well but perhaps not something else. An over use of reflection when something else will work better might be a design smell...but more often likely just bad coding.

Andrew Siemer
+6  A: 

I wouldn't say that using reflection is a design smell. It is an useful feature of the framework that makes the statical languages a little more dynamic. Now from practical point of view I try to avoid reflection if I can solve my problem without it.

Darin Dimitrov
Agreed. I am looking for some more answers to see any kind of consensus.
Mank
+2  A: 

There are some problems which can be solved only with reflection, but I think that it can and maybe should be avoided wherever it is possible to. C# is a static and type-safe language, so use this advantages. Using reflection is often quite error-prone, I think.

Oliver Hanappi
I agree that reflection can be quite error-prone due to its dynamic nature.
Mank
+2  A: 

like all things the answer is "it depends"

A valid use of reflection is in frameworks, for example a plugin framework might make use of Attributes for declaring plugin classes, Testing and Mocking Frameworks are another example.

But I would agree that generally speaking in a line of business app, most of the time it would be a "code smell" (not always though....)

Tim Jarvis
I concur. I wrote in Umair's post that frameworks have different design goals than line-of-business applications. Testing and mocking frameworks are examples of good use of reflection.
Mank
+3  A: 

With great power come great responsibility, reflection is a very powerful tool and when used properly very good, when used improperly it's very bad, the trick is to know when your over using it

Bob The Janitor
A: 

Well, clearly reflection APIs are there because they fill a need, and there are some problems that can only be solved with the use of reflection. Basically, reflection is needed when decisions need to be made in your code based on type information which is available only at runtime but not at compile time.

Vinay Sajip
There are design patterns like visitor, strategy that allow one to take decision at design time based on type information.
Mank
I meant to say runtime instead of design time.
Mank
Saying they're "there because they fill a need" is a very circular argument, and could be just as easily applied to pretty much any feature of any API or programming language. Many features exists merely because they seemed like a good idea at the time. Many were experiments. Many were added simply to fill in a checkbox on a feature list.
Laurence Gonsalves
Sometimes the visitor pattern is a design smell. It's much uglier to extend code built on the visitor pattern.
JasonTrue
But is using reflection better than using visitor/double-dispatch?
Mank
I didn't *just* say reflection filled a need, I also gave the basic circumstances in which reflection might be useful.
Vinay Sajip
Good luck on getting visitor to work when you don't know until runtime which packages will be deployed... Granted, double dispatch can solve that category of problem if you have an alternate method of plugging in unrelated code.
JasonTrue
Besides, double-dispatch is basically a reflection technique, at least in most dynamic type systems. I'm not sure why it would be "better" except in languages where it's easier to read (e.g. Ruby).
JasonTrue
+3  A: 

As with any other technology, if you focus too much on it you may start applying it to the wrong kind of problems.

There are however things that simply are not possible without reflection; any kind of general serialisation is a prime example. Another would be any kind of plug-in framework that does not at compile time have access to all the classes it may need to work with at run-time.

jerryjvl
Serialization is a good example. It is a cross-cutting concern in most applications.
Mank
A: 

Sometimes it actually improves the reusability of code. As a particular example, I once wrote a program for importing a csv into a database. Using an ORM to create classes for the tables, then reflecting on these, I was able to create an importer where only exceptional situations had to be noted, and adding a column may not have required anything other than adding it to the db table, and knowing it exists in the file.

But as others have stated, it's mostly an issue of correct use.

krdluzni
+4  A: 

In my humble opinion, reflection should be a last resort. Reflection makes code really difficult to understand by merely looking at it since the semantics of the language can be altered in very odd ways.

I would consider it a smell. Maybe not bad practice, but something that would raise an eyebrow.

Jeremy Powell
+37  A: 

Examples:

  • Dynamic loading of types via configuration
  • Using "convention" style registration (register components with your container that implement an interface or have a certain naming convention)
  • Checking for/using custom attributes/type metadata

Reflection is a tool, like "throw". should you use throw everywhere? No! So is it a code smell to use throw?

Philip Rieck
Exactly what I would have written.
Alex
A: 

All reflection does is let you observe types at runtime. If you are a hack I suppose you could potentially code up some Rube Goldberg contraption with it, but the same can be said of a lot of other techniques.

Many core features of the framework, such as attributes, wouldn't work at all without reflection.

Robert Harvey
+4  A: 

Conceptually, reflection is a powerful tool to use as a gateway from non-code into code as well as a polymorphic tool.

For example...

  • taking a string representation of a type and turning it into an object.
  • not hardcoding frameworks or plugins together.
  • dynamically using objects from different assemblies without knowing what they are in advance.
  • serializing data without writing dedicated code to do it.

Used properly it's an ingenious tool to take code to the next level of reusability and flexibility. Nothing wrong with that.

The only time it's a design smell is when it's being used to do something that conventional functionality already covers. (i.e., you wouldn't want to use Reflection to get the values of a DataRow or something).

routeNpingme
+9  A: 

To me, a lot of them look like bending the rules at the cost of good design (OOP). Many of the solutions look unmaintenable and "scripty".

Honestly, "good design" has little to do with OOP. I'd say a far bigger design smell to be concerned with is the belief that good design is exactly equal to OOP. That we can't have good design without OOP, and that we can't follow the rules of OOP without it becoming good design. It's almost as bad as people's obsession with "smells". Programmers should use their brains, not their noses.

Is using reflection a good practice in general? Are there things that can only be solved by reflection?

The way I see it, reflection is mostly a symptom of language shortcomings. Ideally, a language should allow you to do what you want without "bending the rules" through reflection. But most don't, and C# definitely doesn't, so reflection is occasionally your only sensible choice.

There are plenty of "correct" uses of reflection. Dynamically loading types/libraries would be an obvious one. Or inspecting attributes. Most unit testing frameworks depend on reflection as well, which is fine, because they have to be a bit intrusive in order to be easy to use and gain access to the code we wish to test.

But most user code which performs some kind of type inspection, testing at runtime whether a type implements a certain interface or has a certain member function, is a sign of something that, in an ideal language, shouldn't be necessary.

If you want to consider it a smell, call it a language smell, not a design one. (Of course it can be overused in design as well, but where I most often encounter it, it's a necessity because of the lack of expressiveness of the language)

jalf
Agreed that OOP is not the only good design, but it is one of them for many problems. In my question, I meant using reflection in OOP projects but I think I was not clear.
Mank
Good point about good design.
AraK
@Mank: OOP is not one of good designs, the role of OOP is to guide developers to avoid worst design.I totally agree with all jalf points. C# does have a "language smell" and reflection is a quick fix of C# language and OOP design flaws. One of OOP design flaws is shallow inheritance model.
alpav
+11  A: 

Once had a program that processed files (how generic is that description)

By using reflection all you had to do was drop in a DLL into a folder, the app would pick that up and use reflection to look for classes that implemented a certain interface and check some attributes. There was no need for config files. Just drop and go, which was handy for a production system as we didn't require any downtime.

As with most solutions. there are a number of other ways to achieve the same purpose, but reflection did make this quite easy.

Robert Paulson
Thanks for the example. As others have mentioned, plugins are a good use of reflection.
Mank
That's exactly how i do it, too. I would hate having to register each plugin type in some config file or registry or whatever (which gave me headaches a few times before i started using .NET).
Botz3000
+1  A: 

No, Reflection is not a design smell. It could, arguably, be called a "language/platform smell".

Reflection is used because code and code metadata are both stored in the assembly. Thus, they are always updated and in synch. You can code general conventions on metadata rather than being explicit on the common case.

For modularity in .NET, it is a great benefit that modules are self-describing.

This may be due to my own personal development as a programmer, but I find that learning reflection advocates a sorely needed attention to the deliverables (assemblies). Along with TDD, of course.

Tormod
+2  A: 

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.

Daniel Earwicker
+1  A: 

One nice use of reflection is when you want to implement an add-in architecture. You need some way to specify "here's a DLL, go load it and try to instantiate a type". You don't know the type before hand; all you know is that there is some interface in there that you can access. The only way to do this is with reflection.

Our application has a large number of modules you can run inside it. Rather than hard-coding a list of classes we need to launch when you select a module, we have a data table that lists the name of the module's DLL and a class to run from it. This way, when we need to add a new module, we just need a new entry in the table. The code that launches the modules doesn't change.

Paul Williams
+1 This is exactly what we are using Reflection for. It isn't a *design smell* so much as a necessity to provide a rich addin/plugin architecture. Without Reflection, this could be a very difficult task to accomplish.
dboarman
+2  A: 

Programming is all about building abstractions. Reflection is a very powerful tool to build abstractions. So no, if it leads to less code that is easier to understand, I wouldn't say it's a design smell.

A number of you have pointed out that reflection has a place in frameworks, testing, mocks etc. How about in line-of-business applications?

In my experience, when you write a line-of-business application of some size, you inevitably end up writing your own domain specific framework and libraries. That's where reflection has it's place.

nikie
A: 

This is one of the stinkiest of smells. A language that is "fully closed" has no need for reflection.

Can you clarify what you mean by "fully closed"?
UserControl
A: 

Anyone can see benefits of using reflection, and I think reflection can help you achieve better design and especially OOP design concepts without writing much more code.

For example, you can build loosely coupled layers that depend on abstraction and use reflection to control behavior specific to instances at runtime.

Most obviously: generalized UI layers/components.

Flexibility and productivity of ASP.Net MVC and Dynamic data are just an example also you can see GridView as one too.

Ahmed Khalaf
A: 

I'm in the middle of a project that uses (for my first time, ever) Reflection. I have to admit, it doesn't look very good. Normally I strive for very minimal commenting, in the belief that code should be self-commenting to the max extent possible, but with this project I am adding frequent comments; this is both to explain what's going on to the next developer who may have to maintain the code, and as "thinking out loud" for my own benefit.

Bottom line: if it doesn't look obvious, add comments. Always think about the person who comes after you who may have to deal with your mess. Reflection can look messy, so comment accordingly.

Jay