Years ago, when I was just a shy junior programmer, I had a dream. I dreamt of a world in which I had no need to figure out the right messages for handling in my Windows applications. Moreover, I didn’t want to research the best way to export functions from Visual C++ to accommodate incoming calls from Visual Basic (VB) applications. As a first-year student at the Windows university, I found particularly hostile the different programming models that the various Windows programming tools were featuring. It wasn't a matter of preference, though—it's natural to feel more comfortable with VB syntax than with C++ syntax, or vice versa. It was a more rooted difficulty. First, you had to think about applications in different ways. Next, you had to code them to comply with the syntax of different languages.
I understand that the most obvious answer to this complaint is, "OK, but what about using just one language and one tool for all of your development efforts?" Although this suggestion isn't far-fetched, it only partially applies to the world of Windows programming. In Windows, it’s inevitable that you'll use different tools to build applications and multi-tier systems.
Windows programming tools are different by nature and have emerged from different backgrounds. Microsoft conceived of Windows with the C language in mind but ended up with a tough, somewhat dumbed-down model for brave and patient programmers only. Along the way, and not especially quickly, Microsoft realized that there had to be a better way to do the same things. Then came VB, with its nice flavor of object orientation and its rapid development features.
VB, though, was probably ahead of its time. It was based on one of the best ideas of the software era, but the actual design wasn’t as good as it should have been. Over time, several versions of VB and Visual C++ repeatedly failed to offer a unique programming model and, more importantly, a common set of objects callable through the same semantic model. For a time, a common sentiment was that COM+ could have upgraded itself to the rank of Common Windows Runtime Engine. And in fact, it seems that the early name of what we know today as the .NET common language runtime was COM++.
However, several structural flaws in COM and COM+ suggested that a complete redesign was necessary before a runtime environment based entirely on them shipped. COM components are raw binaries with a rough model for exposing functionalities, handling events, registering, and versioning, to say the least. Also, COM components leave the programmer responsible for managing the memory clean-up, which isn't a light task. The big picture for COM was great and timely, but it needed some radical makeup to upgrade. Then came .NET.
.NET seems to fulfill the somewhat childish dream of that shy junior programmer in the early 90s. I dreamt of a common runtime for all applications and development tools available under the Windows umbrella. I envisioned a world in which whatever the language of choice, the programming objects were the same. No more Microsoft Foundation Classes (MFCs) or ATL C++ classes for the Visual C++ programmers and runtime COM classes for outstanding VB programmers. Thanks to the .NET infrastructure, that dream has come true at last.
.NET has a runtime engine that manages the code execution and provides services for easier programming. All the code you develop specifically for .NET is called managed code, and it benefits from all the platform features built into .NET, including cross-language integration and exception handling, debugging and profiling services, enhanced security, and more effective versioning and deployment. In addition, .NET gives us a brand new model for component interaction and the long-awaited common class library. This class hierarchy is called the Base Class Library (BCL), and it’s available through the same programming interface, whatever language you use for coding.
With the advent of .NET, there will be two different executables in Windows: traditional unmanaged .exe files and .NET managed programs. The traditional unmanaged code runs outside the .NET runtime and can't access any of the runtime-provided services. It also needs Windows to work. Any .NET executable, instead, can run on any platform where the .NET runtime is available.
Basically, .NET takes in the essence of the Java architecture: intermediate bytecode and a feature-rich virtual machine. The Microsoft Intermediate Language (MSIL), a sort of higher-level Assembly language, assumes the role of the bytecode. The common language runtime plays the role of the virtual machine.
In this scenario, how do you write .NET code? You just need a .NET-specific compiler, which produces MSIL code instead of the raw Win32 binary code. With the .NET framework, Microsoft makes a few of these compilers available for C#, VB, JScript, and C++. Other companies are about to ship .NET compilers for other languages, including Eiffel and Pascal.
In whatever .NET language you use, the intermediate code is always the same. This is the key feature that lets .NET applications exploit common services such as cross-language inheritance, exception handling, and debugging. To enable the .NET runtime to provide these services, compilers emit special chunks of information called metadata. Metadata provides information about the types, properties, and methods in your code. Metadata is part of any .NET executable, and it enables the runtime to locate and load classes and resolve method invocations.
The runtime manages references to objects and implements an automatic garbage collector that's responsible for releasing objects when no longer needed. Objects managed in this way are called managed data. This built-in memory management mechanism eliminates a lot of memory leaks and other frequent programming errors.
The .NET common language runtime is a sort of virtual machine that significantly blurs the distinction between languages. At the same time, it unifies the programming model, making the language choice mostly a matter of personal preference. Different people on the same team can now use different languages without losing reusability and integration. In addition, there’s just one common (and consistent) class library for all .NET applications, and it has none of COM+’s quirkiness. You lose some of the system’s low-level control, but you gain a lot in ease of development and overall programming power.
That ingenuous dream took years to come true, but it definitely has. That shy junior programmer would have really enjoyed .NET and the common language runtime!