5.6.1 Technical foundation

The .NET platform is in many respects similar to the Java platform. The core of .NET is a stack-based virtual machine called the Common Language Runtime (CLR), which executes object-savvy bytecode.1 The CLR typically compiles bytecode to native code using a just-in-time compiler, but there are also provisions for ahead-of-time compilation, which is often used with embedded systems. Microsoft refers to bytecode as “managed code,” and to machine code that runs natively on a CPU as “unmanaged code.” To write low-level managed code, one can use the Common Intermediate Language (CIL), which is an assembly language that targets the CLR. Like the JVM, the CLR manages memory automatically through garbage collection, and natively supports exceptions (although the CLR does not have Java’s distinction between checked and unchecked exceptions; all are unchecked).

.NET has been standardized as the Common Language Infrastructure (CLI), which has been implemented by vendors other than Microsoft. Notably, Novell has created the Mono implementation, which is available for a wider range of platforms than .NET, such as Linux, various Unix platforms and Apple’s Mac OS X. .NET has a counterpart to the Micro Edition of Java in the .NET Compact Framework, which is a version of the .NET platform designed to run on embedded systems, such as cellular phones. Libby and Kent (2009) have done research on implementing the CLI in hardware for the benefit of embedded systems.

While it is possible for languages other than Java to target the JVM (and many do), .NET was specifically created to allow programs written in different programming languages to run on the same virtual machine. By contrast, the JVM was specifically designed for programs written in the Java programming language. This can be seen in that while both the JVM and the CLR have explicit support for classes, only the CLR allows methods outside of classes, thus enabling procedural languages to easily target the CLR.2 Also, a number of specifications are associated with .NET that enable different languages to interoperate. The Common Type Specification (CTS) formally defines the type system used by various .NET languages. The Common Language Specification (CLS) is a subset of the CTS, and is a set of rules that all languages targeting the CLI should comply with in order to be interoperable with other CLS-compliant languages (Troelsen 2007).

Visual Basic and C# are Microsoft’s two flagship languages targeting the CLR. Visual Basic has been retrofitted as a pure .NET language, and does not retain source-level compatibility with its previous incarnations. C# is in many respects similar to Java, and is an object-oriented programming language supporting interfaces, single implementation inheritance and parameterized types (generics). C# does sport some noteworthy features that are not in Java, though, such as language-level support for properties and lambda expressions. Language-integrated queries (LINQ) can be used to query databases (instead of including SQL string literals that are parsed at runtime, as is done in Java and most other languages).

CLR has rich support for runtime metadata, which is accessed programmatically through reflection. Unlike Java, the type system of the CLR (the CTS) is aware of generics, and makes this information available through reflection.3 .NET Remoting, a .NET technology for realizing distributed computing and similar to Java’s RMI, is one of many technologies to take advantage of reflection. By using metadata available at runtime, .NET Remoting is, like RMI, able to use dynamically synthesized client-side proxies and generic server-side proxies instead of requiring users to generate them statically (Rammer and Szpuszta 2005).

Footnotes

  1. The instruction set of .NET is formally divided into the “Base Instruction Set” and the “Object Model.”
  2. A procedural language can target the JVM by simply implementing procedures as static methods that are part of an unnamed class.
  3. Generics are also available in Java, but in order to preserve backwards compatibility, Sun decided to make them strictly a compile-time tool, and as such, generic type information is not available at runtime. (Java removes generic type information through a process called “type erasure”).