The Common Language Runtime
Central to the .NET Framework is its runtime
execution environment, known as the Common
Language Runtime (CLR) or the .NET runtime. Code running under the control of the
CLR is often termed managed code.
However, before it can be executed by the CLR, any
source code that you develop (in C# or some other language) needs
to be compiled. Compilation occurs in two steps in .NET:
-
Compilation of source code to IL
-
Compilation of IL to platform-specific code
by the CLR
This two-stage compilation process is very
important, because the existence of the IL (managed code) is the
key to providing many of the benefits of .NET.
Advantages of Managed Code
Microsoft Intermediate Language shares with
Java byte code the idea that it is a low-level language with a
simple syntax (based on numeric codes rather than text), which can
be very quickly translated into native machine code. Having this
well-defined universal syntax for code has significant
advantages.
Platform Independence
First, it means that the same file containing
byte code instructions can be placed on any platform; at runtime
the final stage of compilation can then be easily accomplished so
that the code will run on that particular platform. In other words,
by compiling to IL you obtain platform independence for .NET, in
much the same way as compiling to Java byte code gives Java
platform independence.
You should note that the platform independence
of .NET is only theoretical at present because, at the time of
writing, a complete implementation of .NET is only available for
Windows. However, a partial implementation is available (see, for
example, the Mono project, an effort to create an open source
implementation of .NET, at go-mono.com.
Performance Improvement
Although we previously made comparisons with
Java, IL is actually a bit more ambitious than Java byte code. IL
is always Just-in-Time compiled (known as
JIT compilation), whereas Java byte code was often interpreted. One
of the disadvantages of Java was that, on execution, the process of
translating from Java byte code to native executable resulted in a
loss of performance (with the exception of more recent cases, where
Java is JIT compiled on certain platforms).
Instead of compiling the entire application in one
go (which could lead to a slow startup time), the JIT compiler
simply compiles each portion of code as it is called (just in
time). When code has been compiled once, the resultant native
executable is stored until the application exits, so that it does
not need to be recompiled the next time that portion of code is
run. Microsoft argues that this process is more efficient than
compiling the entire application code at the start, because of the
likelihood that large portions of any application code will not
actually be executed in any given run. Using the JIT compiler, such
code will never be compiled.
This explains why we can expect that execution of
managed IL code will be almost as fast as executing native machine
code. What it doesn’t explain is why Microsoft expects that we will
get a performance improvement. The reason
given for this is that, because the final stage of compilation
takes place at runtime, the JIT compiler will know exactly what
processor type the program will run on. This means that it can
optimize the final executable code to take advantage of any
features or particular machine code instructions offered by that
particular processor.
Traditional compilers will optimize the code,
but they can only perform optimizations that are independent of the
particular processor that the code will run on. This is because
traditional compilers compile to native executable before the
software is shipped. This means that the compiler doesn’t know what
type of processor the code will run on beyond basic generalities,
such as that it will be an x86-compatible processor or an Alpha
processor. Visual Studio 6, for example, optimizes for a generic
Pentium machine, so the code that it generates cannot take
advantage of hardware features of Pentium III processors. On the
other hand, the JIT compiler can do all the optimizations that
Visual Studio 6 can, and in addition it will optimize for the
particular processor that the code is running on.
Language Interoperability
The use of IL not only enables platform
independence; it also facilitates language
interoperability. Simply put, you can compile to IL from one
language, and this compiled code should then be interoperable with
code that has been compiled to IL from another language.
You’re probably now wondering which languages aside
from C# are interoperable with .NET, so the following sections
briefly discuss how some of the other common languages fit into
.NET.
Visual Basic 2009
Visual Basic .NET 2002 underwent a complete
revamp from Visual Basic 6 to bring it up to date with the first
version of the .NET Framework. The Visual Basic language itself had
dramatically evolved from VB6, and this meant that VB6 was not a
suitable language for running .NET programs. For example, VB6
is heavily integrated into
Component Object Model (COM) and works by exposing only event
handlers as source code to the developer - most of the background
code is not available as source code. Not only that; it does not
support implementation inheritance, and the standard data types
Visual Basic 6 uses are incompatible with .NET.
Visual Basic 6 was upgraded to Visual Basic .NET in
2002, and the changes that were made to the language are so
extensive you might as well regard Visual Basic as a new language.
Existing Visual Basic 6 code does not compile to the present Visual
Basic 2009 code (or to Visual Basic .NET 2002 and 2003 for that
matter). Converting a Visual Basic 6 program to Visual Basic 2009
requires extensive changes to the code. However, Visual Studio 2009
(the upgrade of Visual Studio for use with .NET) can do most of the
changes for you. If you attempt to read a Visual Basic 6 project
into Visual Studio 2009, it will upgrade the project for you, which
means that it will rewrite the Visual Basic 6 source code into
Visual Basic 2009 source code. Although this means that the work
involved for you is heavily cut down, you will need to check
through the new Visual Basic 2009 code to make sure that the
project still works as intended because the conversion might not be
perfect.
One side effect of this language upgrade is
that it is no longer possible to compile Visual Basic 2009 to
native executable code. Visual Basic 2009 compiles only to IL, just
as C# does. If you need to continue coding in Visual Basic 6, you
can do so, but the executable code produced will completely ignore
the .NET Framework, and you’ll need to keep Visual Studio 6
installed if you want to continue to work in this developer
environment.
Visual C++ 2009
Visual C++ 6 already had a large number of
Microsoft-specific extensions on Windows. With Visual C++ .NET,
extensions have been added to support the .NET Framework. This
means that existing C++ source code will continue to compile to
native executable code without modification. It also means,
however, that it will run independently of the .NET runtime. If you
want your C++ code to run within the .NET Framework, you can simply
add the following line to the beginning of your code:
You can also pass the flag /clr to the compiler, which then assumes that you
want to compile to managed code, and will hence emit IL instead of
native machine code. The interesting thing about C++ is that when
you compile to managed code, the compiler can emit IL that contains
an embedded native executable. This means that you can mix managed
types and unmanaged types in your C++ code. Thus the managed C++
code
defines a plain C++ class, whereas the code
will give you a managed class, just as if you’d
written the class in C# or Visual Basic 2009. The advantage of
using managed C++ over C# code is that you can call unmanaged C++
classes from managed C++ code without having to resort to COM
interop.
The compiler raises an error if you attempt to use
features that are not supported by .NET on managed types (for
example, templates or multiple inheritance of classes). You will
also find that you will need to use nonstandard C++ features (such
as the _gc keyword shown in the previous
code) when using managed classes.
Because of the freedom that C++ allows in
terms of low-level pointer manipulation and so on, the C++ compiler
is not able to generate code that will pass the CLR’s memory type
safety tests. If it’s important that your code be recognized by the
CLR as memory type safe, you’ll need to write your source code in
some other language (such as C# or Visual Basic 2009).
Visual J# 2009
The latest language to be added to the mix is
Visual J# 2009. Prior to .NET Framework 1.1, users were able to use
J# only after making a separate download. Now the J# language is
built into the .NET Framework. Because of this, J# users are able
to take advantage of all the usual features of Visual Studio 2009.
Microsoft expects that most J++ users will find it easiest to use
J# if they want to work with .NET. Instead of being targeted at the
Java runtime libraries, J# uses the same base class libraries that
the rest of the .NET-compliant languages use. This means that you
can use J# for building ASP.NET Web applications, Windows Forms,
XML Web services, and everything else that is possible - just as C#
and Visual Basic 2009 can.
Scripting Languages
Scripting languages are still around,
although in general, their importance is likely to decline with the
advent of .NET. JScript, on the other hand, has been upgraded to
JScript .NET. You can now write ASP.NET pages in JScript .NET, run
JScript .NET as a compiled rather than an interpreted language, and
write strongly typed JScript .NET code. With ASP.NET there is no
reason to use scripting languages in server-side Web pages. VBA is,
however, still used as a language for Microsoft Office and Visual
Studio macros.
COM
and COM+
Technically speaking, COM and COM+ aren’t
technologies targeted at .NET, because components based on them
cannot be compiled into IL (although it’s possible to do so to some
degree using managed C++, if the original COM component was written
in C++). However, COM+ remains an important tool, because its
features are not duplicated in .NET. Also, COM components will
still work - and .NET incorporates COM interoperability features
that make it possible for managed code to call up COM components
and vice versa (this is discussed in Chapter 23, “COM
Interoperability”). In general, however, you will probably find
it more convenient for most purposes to code new components as .NET
components, so that you can take advantage of the .NET base classes
as well as the other benefits of running as managed code.
|