The Power of Reflection
Reflection enables a program to dynamically analyze and discover elements (such as fields, methods, constructors, and attributes) of types (such as classes, interfaces, and structures) in existing assemblies. When this type information is obtained, it may be simply displayed, similar to the Ildasm tool. Or, the types may be instantiated, accessed, and invoked in a very dynamic and interactive manner, making it possible to implement interesting programming tools such as an interpreted test script language.
Reflection is not limited to analyzing existing compiled code. It can also be used to dynamically generate new types that may then be instantiated and manipulated in the same way as any traditional source codedefined types. An example of this is a tool that studies the functional interface of a class and then creates a wrapper class (also known as an adapter or a proxy) that provides some mediated access to an instance of the original class. This is a part of the remoting architecture used in the .NET platform.
As just mentioned, reflection lets you programmatically generate new types in memory at runtime. In other words, the program can become its own author as it executes! This allows you to experiment with self-generating code. Self-generating code is typically frowned upon (as is self-modifying code, which is a relic of the early Wild West era of assembly programming) for use in bread-and-butter software development because its behavior tends to be hard to predict and because it is often a nightmare to debug and maintain. However, this is still a fascinating area of computer science research, and it could have applications in self-organizing systems and artificial intelligence. Such a self-organizing program would, with luck, eventually perform its duties correctly, but no human would have a clue about how it performs its duties! If nothing else, this impressive capability to generate new types at runtime demonstrates the awesome power of reflection.
Thus, an algorithm may be generated on the fly, without ever having been written by a human programmer or stored in a source file. This is a rather advanced technique, but the possibilities are endless and astonishing. For example, an exciting area of computer research known as genetic algorithms requires that a program dynamically tweak its own algorithms as it heuristically searches for an optimal solution to some mathematically hard problem. A program that can evolve its behavior in an effective manner based on past successes and failures is an independently learning system that discovers how to solve its own problems. But don't worry. Success in this field is probably decades away, so you will not lose your job as a human programmer to genetic programming just yet!
At a much more mundane level, reflection is used for implementing many programming tools, such as compilers, decompilers, interpreters, debuggers, class browsers, and object inspectors. For example, you may want to develop a tool that decompiles an existing compiled assembly into its equivalent source code, similar to Mocha, which is a powerful reverse-engineering utility used by some Java programmers. In this scenario, you would use reflection to discover all the details of the types defined in the assembly. Then you could use another cool .NET class library feature, known as the Code Document Object Model (CodeDOM) to generate the source code from the discovered type information. The System::CodeDom and System::CodeDom::Compiler namespaces contain classes that support the generation and compilation of source code in supported programming languages. The Microsoft::CSharp and Microsoft::VisualBasic namespaces contain additional classes that support language-specific source-code generation and compilation.
One word of caution: The current version of Visual Studio does not yet support reflection down to individual expressions and statements, so it is not yet easy to implement all the capabilities of Mocha. However, I expect that this feature will become a part of future releases, making full decompiler functionality possible. (If you develop commercial applications and are concerned about others decompiling your code and stealing your company jewels, you may want to look into obfuscation technology.)