views:

512

answers:

5

Hi All, I went through all the posts on Reflection but couldn't find the answer to my question.

Can you please tell me what were the problems in programming world before .Net Reflection came and how it solved those problems.

Please explain with example.

+11  A: 

It should be stated that .NET reflection isn't revolutionary - the concepts have been around in other framework.

Reflection in .NET has 2 facets:

Investigating type information

Without some kind of reflection / introspection API, it becomes very hard to perform things like serialization. Rather than having this provided at runtime (by inspecting the properties/fields/etc), you often need code-generation instead, i.e. code that explicitly knows how to serialize each of your types. Tedious, and painful if you want to serialize something that doesn't have a twin.

Likewise, there is nowhere to store additional metadata about properties etc, so you end up having lots of additional code, or external configuration files. Something as simple as being able to associate a friendly name with a property (via an attribute) is a huge win for UI code.

Metaprogramming

.NET reflection also provides a mechanism to create types (etc) at runtime, which is hugely powerful for some specific scenarios; the alternatives are:

  • essentially running a parser/logic tree at runtime (rather than compiling the logic at runtime into executable code) - much slower
  • yet more code generation - yay!
Marc Gravell
A: 

reflection is definately quite slow....

Bhaskar
-1, does not answer question
Spoike
Only if used incorrectly. There are plenty of ways to get very fast reflection, including: Delegate.CreateDelegate (and cache) to get typed delegate access to arbitrary methods (including getters/setters), and runtime IL writing (dynamic method etc). Things like `HyperDescriptor` (search...) bring this together to hide the complex bits from the caller, letting them just have really quick access. In 3.5+, `Expression` plays a strong role here too, allowing dynamic methods without having to know IL.
Marc Gravell
+6  A: 

I think to understand the need for reflection in .NET, we need to go back to before .NET. After all, modern languages like like Java and C# do not have a history BF (before reflection).

C++ arguably has had the most influence on C# and Java. But C++ did not originally have reflection and we coded without it and we managed to get by. Occasionally we had void pointer and would use a cast to force it into whatever type we wanted. The problem here was that the cast could fail with terrible consequences:

double CalculateSize(void* rectangle) {
    return ((Rect*)rectangle)->getWidth() * ((Rect*)rectangle)->getHeight());
}

Now there are plenty of arguments why you shouldn't have coded yourself into this problem in the first place. But the problem is not much different from .NET 1.1 with C# when we didn't have generics:

Hashtable shapes = new Hashtable();
....
double CalculateSize(object shape) {
    return ((Rect)shape).Width * ((Rect)shape).Height;
}

However, when the C# example fails it does so with a exception rather than a potential core dump.

When reflection was added to C++ (known as Run Time Type Identification or RTTI), it was hotly debated. In Stroustrup's book The Design and Evolution of C++, he lists the following arguments against RTTI, in that some people:

Declared the support unnecessary
Declared the new style inherently evil ("against the spirit of C++")
Deemed it too expensive
Thought it too complicated and confusing
Saw it as the beginning of an avalanche of new features

But it did allow us to query the type of objects, or features of objects. For example (using C#)

Hashtable shapes = new Hashtable();
....
double CalculateSize(object shape) {
    if(shape is Rect) {
        return ((Rect)shape).Width * ((Rect)shape).Height;
    }
    else if(shape is Circle) {
        return Math.Power(((Circle)shape).Radius, 2.0) * Math.PI;
    }
}

Of course, with proper planning this example should never need to occur.

So, real world situations where I've needed it include:

  • Accessing objects from shared memory, all I have is a pointer and I need to decide what to do with it.
  • Dynamically loading assemblies, think about NUnit where it loads every assembly and uses reflection to determine which classes are test fixtures.
  • Having a mixed bag of objects in a Hashtable and wanting to process them differently in an enumerator.
  • Many others...

So, I would go as far as to argue that Reflection has not enabled the ability to do something that couldn't be done before. However, it does make some types of problems easier to code, clearer to reader, shorter to write, etc.

Of course that's just my opinion, I could be wrong.

Adrian
+1  A: 

I once wanted to have unit tests in a text file that could be modified by a non technical user in the format in c++

MyObj Function args //textfile.txt

but I couldn't find a way to read in a string and then have the code create an object instance of the type represented by the string without reflection which c++ doesn't support.

char *str; //read in some type from a text file say the string is "MyObj"
str *obj;  //cast a pointer as type MyObj  
obj = new str;  //create a MyObj

Another use might be to have a generic copy function that could copy the members of an class without knowing them in advance.

iterationx
A: 

It helps a lot when you are using c# attributes like [Obsolete] or [Serializable] in your code. Frameworks like NUnit using reflection on classes and containing methods to understand which methods are tests, setup, teardown etc.

darthjit