This chapter discussed the use of reflection to read the metadata that is compiled into the CIL. Using reflection, it is possible to provide a late binding in which the code to call is defined at execution time rather than at compile time. Although reflection is entirely feasible for deploying a dynamic system, it executes considerably more slowly than statically linked (compile-time), defined code. This tends to make it more prevalent and useful in development tools when performance is potentially not as critical.
Reflection also enables the retrieval of additional metadata decorating various constructs in the form of attributes. Typically, custom attributes are sought using reflection. You can define your own custom attributes that insert additional metadata of your own choosing into the CIL. At runtime, you can then retrieve this metadata and use it within the programming logic.
Many programmers view attributes as a precursor to a concept known as aspect-oriented programming, in which you add functionality through constructs such as attributes instead of manually implementing the functionality wherever it is needed. It will take some time before you see true aspects within C# (if ever); however, attributes provide a clear steppingstone in that direction, without creating a significant risk to the stability of the language.
Finally, this chapter explored dynamic programming using the new type dynamic13. This coverage included a discussion of why static binding, although preferred when the API is strongly typed, has limitations when you are working with dynamic data.
The next chapter looks at multithreading, where attributes are used for synchronization.