.NET Standard

Historically, it has been quite difficult to write a library of C# code that can be used on multiple operating systems or even different .NET frameworks on the same operating system. The problem was that the framework APIs on each framework had different classes available (and/or methods in those classes). The .NET Standard solves this issue by defining a common set of .NET APIs that each framework must implement to be compliant with a specified version of the .NET Standard. This uniformity ensures that developers have a consistent set of APIs available to them across each .NET framework that is compliant with the .NET Standard version they target.

For more information, including the mapping of .NET framework implementations and their versions to their corresponding .NET Standard version, see http://itl.tc/NETStandard.

Base Class Library

In addition to providing a runtime environment in which CIL code can execute, the CLI defines a core set of class libraries that programs may employ, called the Base Class Library. The class libraries contained in the BCL provide foundational types and APIs, allowing programs to interact with the runtime and underlying operating system in a consistent manner. The BCL includes support for collections, simple file access, some security, fundamental data types (string, among others), streams, and the like.

Similarly, a Microsoft-specific library called the Framework Class Library (FCL) includes support for rich client user interfaces, web user interfaces, database access, distributed communication, and more.

C# Compilation to Machine Code

The HelloWorld program listing in Chapter 1 is obviously C# code, and you compiled it for execution using the C# compiler. However, the processor still cannot directly interpret compiled C# code. An additional compilation step is required to convert the result of C# compilation into machine code. Furthermore, the execution requires the involvement of an agent that adds more services to the C# program—services that it was not necessary to code for explicitly.

All computer languages define syntax and semantics for programming. Since languages such as C and C++ compile to machine code, the platform for these languages is the underlying operating system and machine instruction set, be it Microsoft Windows, Linux, macOS, or something else. In contrast, with languages such as C#, the underlying context is the runtime (or VES).

CIL is what the C# compiler produces after compiling. It is termed a common intermediate language because an additional step is required to transform the CIL into something that processors can understand. Figure 24.1 shows the process.

Figure 24.1: Compiling C# to machine code

In other words, C# compilation requires two steps:

Conversion from C# to CIL by the C# compiler
Conversion from CIL to instructions that the processor can execute

The runtime understands CIL statements and compiles them to machine code. Generally, a component within the runtime performs this compilation from CIL to machine code. This component is the just-in-time (JIT) compiler, and jitting can occur when the program is installed or executed. Most CLI implementations favor execution-time compilation of the CIL, but the CLI does not specify when the compilation needs to occur. In fact, the CLI even allows the CIL to be interpreted rather than compiled, in the same way that many scripting languages work. In addition, .NET includes a tool called NGEN that enables compilation to machine code prior to running the program. This pre-execution-time compilation needs to take place on the computer on which the program will be executing because it will evaluate the machine characteristics (processor, memory, and so on) as part of its effort to generate more efficient code. The advantage of using NGEN at installation (or at any time prior to execution) is that you can reduce the need for the jitter to run at startup, thereby decreasing startup time.

As of Visual Studio 2015 and later, the C# compiler also supports .NET native compilation, whereby the C# code is compiled into native machine code when creating a deployed version of the application, much like using the NGEN tool. Universal Windows Applications make use of this feature.

{{ snackbarMessage }}