C Sharp

Unified Type System

One of the key features of any development environment is its type system. After all, a development environment with a limited amount of types or a system that limits the programmer's ability to extend the system-supplied types isn't an environment with a long life expectancy. The .NET runtime does more than just give the developer a single, unified type system that is used across all CLS-compliant languages. It also lets language writers extend the type system by adding new types that look and act just like the system built-in types. This means that you, as a developer, can use all typesin a uniform manner, regardless of whether they are .NET predefined types or user-created types. I'll discuss the details of the type system and how the C# compiler supports it in Chapter 4, "The Type System." -

Metadata and Reflection

As I mentioned in the earlier section "Microsoft Intermediate Language and the JITters," the CLS-compliant compilers take your source code as input and produce MSIL code for the runtime to compile (via the JITters) and execute. In addition to mapping source code to MSIL instruction sequences, CLS-compliant compilers have another equally important task: embedding metadata into the resulting EXE.

Metadata is data that describes data. In this context, metadata is the collection of programmatic items that constitute the EXE, such as the types declared and the methods implemented. If this sounds vaguely familiar, it should. This metadata is similar to the type libraries (typelibs) generated with Component Object Model (COM) components. Not only is the metadata output from a .NET compiler substantially more expressive and complete than the COM typelibs we're accustomed to, but the metadata is also always embedded in the EXE. This way, there's no chance of losing the application's metadata or having a mismatched pair of files.

The reason for using metadata is simple. It allows the .NET runtime to know at run time what types will be allocated and what methods will be called. This enables the runtime to properly set up its environment to more efficiently run the application. The means by which this metadata is queried is called reflection. In fact, the .NET Framework class libraries provide an entire set of reflection methods that enable any application-not just the CLR-to query another application's metadata.

Tools such as Visual Studio.NET use these reflection methods to implement features such as IntelliSense. With IntelliSense, as you type in a method name, that method's arguments pop up in a list box on the screen. Visual Studio.NET takes that functionality even further, showing all the members of a type. I'll discuss the reflection APIs in Chapter 15, "Multithreaded Programming."-

Another incredibly useful .NET tool that takes advantage of reflection is the Microsoft .NET Framework IL Disassembler (ILDASM). This powerful utility parses the target application's metadata and then displays information about the application in a treelike hierarchy. Figure 2-1 illustrates what the "Hello, World" C# application looks like in ILDASM.

-

Figure 2-1 The C# "Hello, World" application displayed in ILDASM.-

The window in the background of Figure 2-1 is the main IL Disassembler window. Double-clicking the Main method in the tree view brings up the window in the foreground that shows the Main method's details.