24. The Common Language Infrastructure

One of the first items that c# programmers encounter beyond the syntax is the context under which a C# program executes. This chapter discusses the underpinnings of how C# handles memory allocation and de-allocation, type checking, interoperability with other languages, cross-platform execution, and support for programming metadata. In other words, this chapter investigates the Common Language Infrastructure on which C# relies both at compile time and during execution. It covers the execution engine that governs a C# program at runtime and considers how C# fits into a broader set of languages that are governed by the same execution engine. Because of C#’s close ties with this infrastructure, most of the features that come with the infrastructure are made available to C#.

A figure shows the various types included in the common language infrastructure.

Defining the Common Language Infrastructure

Instead of generating instructions that a processor can interpret directly, the C# compiler generates instructions in an intermediate language, the Common Intermediate Language (CIL). A second compilation step then occurs, generally at execution time, that converts the CIL to machine code that the processor can understand. Conversion to machine code is still not sufficient for code execution, however. It is also necessary for a C# program to execute under the context of an agent. The agent responsible for managing the execution of a C# program is the Virtual Execution System (VES), more casually referred to as the runtime. (Note that the runtime in this context does not refer to a specific time, such as execution time; rather, the runtime—the VES—is an agent responsible for managing the execution of a C# program.) The runtime is responsible for loading and running programs and providing additional services (security, garbage collection, and so on) to the program as it executes.

The specifications for the CIL and the runtime are contained within an international standard known as the Common Language Infrastructure (CLI).1 The CLI is a key specification for understanding the context in which a C# program executes and how it can seamlessly interact with other programs and libraries, even when they are written in other languages. Note that the CLI does not prescribe the implementation for the standard but rather identifies the requirements for how a CLI framework should behave once it conforms to the standard. This provides CLI implementers with the flexibility to innovate where necessary while still providing enough structure that programs created by one CLI implementation can execute on a different implementation and even on a different operating system.

1 Throughout the chapter, CLI refers to Common Language Infrastructure rather than command-line interface as in Dotnet CLI.

Note

Note the similarity between the CIL and CLI acronyms and the names they stand for. Distinguishing between them now will help you avoid confusion later.

Contained within the CLI standard are specifications for the following:

  • The Virtual Execution System

  • The Common Intermediate Language

  • The Common Type System

  • The Common Language Specification

  • Metadata

  • The framework

This chapter broadens your view of C# to include the CLI, which is critical to how C# programs operate and interact with programs and with the operating system.

CLI Implementations

The primary implementations of the CLI today are .NET Core, which runs on Windows, as well as UNIX/Linux and Mac OS; the .NET Framework for Windows; and Xamarin, which is intended as a general cross-platform solution including iOS, macOS, and Android applications. Each implementation of the CLI includes a C# compiler and a set of framework class libraries. The version of C# supported by each, as well as the exact set of classes in the libraries, varies considerably, and many implementations are now only of historical interest. Table 24.1 describes these implementations.

Table 24.1: Implementations of the CLI

Compiler

Description

Microsoft .NET Framework

This traditional (and first) version of the CLR is for creating applications that run on Windows. It includes support for Windows Presentation Foundation (WPF), Windows Forms, and ASP.NET. It uses the .NET Framework Base Class Library (BCL).

.NET Core/CoreCLR

The .NET Core project, as the name implies, contains the core functionality common to all new implementations of .NET. It is an open source and platform-portable rewrite of the .NET Framework designed for high-performance applications. The CoreCLR is the implementation of the CLR for this project. At the time of this book’s writing, .NET Core 3.1 has been released for Windows, macOS, Linux, FreeBSD, and NetBSD. However, some of the APIs, such as WPF, only work on Windows. See https://github.com/dotnet/coreclr for more details.

Xamarin

A set of development tools and platform-portable .NET libraries as well as an implementation of the CLR that helps developers create applications that run on Microsoft Windows, iOS, macOS, and Android platforms with a very high degree of code reuse. Xamarin uses the Mono BCL.

Microsoft Silverlight

A legacy cross-platform implementation of the CLI intended for creating browser-based web client applications. Microsoft stopped developing Silverlight in 2013.

.NET Compact Framework

A legacy trimmed-down implementation of the .NET Framework designed to run on PDAs, phones, and Xbox 360.

The XNA library and tools for developing Xbox 360 applications are based on the Compact Framework 2.0 release; Microsoft stopped development of XNA in 2013.

.NET Micro Framework

Microsoft’s open source implementation of the CLI for devices so resource constrained that they cannot run the compact framework.

Mono

An open source, cross-platform implementation of the CLI for many UNIX-based operating systems, mobile operating systems such as Android, and game consoles such as PlayStation and Xbox.

DotGNU Portable.NET

This effort to create a cross-platform implementation of the CLI was decommissioned in 2012.

Shared Source CLI (Rotor)

Between 2001 and 2006, Microsoft released shared-source reference implementations of the CLI licensed for noncommercial use.

 

While the list is extensive considering the work required to implement the CLI, just three frameworks are the most relevant going forward.

Microsoft .NET Framework

The Microsoft .NET Framework was the first .NET CLI implementation (released in February 2000). As such, it is the most mature framework and has the largest API set. It supports building web, console, and Microsoft Windows client applications. The biggest limitation of the .NET Framework is that it runs on Microsoft Windows only—in fact, it is bundled with Microsoft Windows. Numerous sub-frameworks are included with the Microsoft .NET Framework; the most prominent are described here:

  • .NET Framework Base Class Library (BCL): Provides types representing the built-in CLI data types, which include support for file IO, fundamental collections classes, custom attributes, string manipulation, and more. The BCL provides the definition for each of the C# native types such as int and string.

  • ASP.NET: Used to build websites and web-based APIs. This framework has formed the foundation of Microsoft-based websites since its release in 2002 but is slowly being usurped by its replacement, ASP.NET Core, which provides operating system portability along with significant performance improvements and an updated API with greater pattern consistency.

  • Windows Presentation Foundation (WPF): A graphical user interface framework used to build rich UI applications that run on Microsoft Windows. WPF provides not only a set of UI components but also a declarative language, called eXtended Application Markup Language (XAML), that enables a hierarchical definition of an application’s user interface.

You will frequently hear the Microsoft .NET Framework referred to simply as the .NET Framework. Notice the capital F, which distinguishes it from a generic implementation of the CLI and the term .NET framework.

.NET Core

.NET Core is the cross-platform implementation of the .NET CLI going forward. Furthermore, .NET Core is an open source rewrite of the .NET Framework, with a focus on high performance and cross-platform compatibility.

.NET Core consists of the .NET Core Runtime (Core CLR), .NET Core framework libraries, and a set of Dotnet command-line tools that can be used to create and build all available application scenarios. The combination of these components is included in the .NET Core SDK. If you’ve followed along with this book’s examples, you’ve already used .NET Core and the Dotnet tools.

The .NET Core API is compatible with existing .NET Framework, Xamarin, and Mono implementations via .NET Standard, which is discussed in further detail later in the chapter.

The current focus of .NET Core is to build high-performant and portable console applications as well as to serve as the .NET Foundation for ASP.NET Core and Windows 10 Universal Windows Platform (UWP) applications. Additional frameworks are emerging from .NET Core as more and more operating systems are supported.

Xamarin

This cross-platform development tool includes application UI development support for Android, macOS, and iOS and (with the release of .NET Standard 2.0) the capability of building Universal Windows Applications, which can run on Windows 10, Xbox One, and HoloLens. What makes Xamarin especially powerful is that the same code base can be used to produce platform-native–looking user interfaces on each of the operating systems supported.

.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. If you wish to write your core application logic once and ensure that it can be used in any modern implementation of .NET, the easiest way to do so is to create a .NET Standard library project (available as a project type in Visual Studio 2017 and above or from the class library template with the Dotnet CLI). The .NET Core compiler will ensure that any code in the library references only APIs available to the version of the .NET Standard you target.

Class library authors should think carefully when choosing which standard to support. The higher the version number of the .NET Standard you target, the less you need to worry about writing your own implementation of APIs that might be missing in lower .NET Standard versions. However, the disadvantage of targeting a higher .NET Standard version is that it will not be as portable across different .NET frameworks. If you wish your library to work with .NET Core 1.0, for example, then you will need to target .NET Standard 1.6 and consequently will not have access to all the reflection APIs that are common to the Microsoft .NET Framework. To summarize this dichotomy: Target higher .NET Standard versions if you are lazy and lower .NET Standard versions if portability is more important than reducing your workload.

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.

A figure shows the stages involved in the compilation of c sharp code to machine code.

Figure 24.1: Compiling C# to machine code

In other words, C# compilation requires two steps:

  1. Conversion from C# to CIL by the C# compiler

  2. 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.

Runtime

Even after the runtime converts the CIL code to machine code and starts to execute it, it continues to maintain control of the execution. The code that executes under the context of an agent such as the runtime is managed code, and the process of executing under control of the runtime is managed execution. The control over execution transfers to the data; this makes it managed data because memory for the data is automatically allocated and de-allocated by the runtime.

Somewhat inconsistently, the term Common Language Runtime is not technically a generic term that is part of the CLI. Rather, CLR is the Microsoft-specific implementation of the runtime for the .NET framework. Regardless, CLR is casually used as a generic term for runtime, and the technically accurate term, Virtual Execution System, is seldom used outside the context of the CLI specification.

Because an agent controls program execution, it is possible to inject additional services into a program, even though programmers did not explicitly code for them. Managed code, therefore, provides information to allow these services to be attached. Among other items, managed code enables the location of metadata about a type member, exception handling, access to security information, and the capability to walk the stack. The remainder of this section includes a description of some additional services made available via the runtime and managed execution. The CLI does not explicitly require all of them, but the established CLI frameworks have an implementation of each.

Garbage Collection

Garbage collection is the process of automatically de-allocating memory according to the program’s needs. It represents a significant programming problem for languages that don’t have an automated system for performing this cleanup. Without the garbage collector, programmers must remember to always free any memory allocations they make. Forgetting to do so, or doing so repeatedly for the same memory allocation, can introduce memory leaks or corruption into the program—something exacerbated by long-running programs such as web servers. Because of the runtime’s built-in support for garbage collection, programmers targeting runtime execution can focus on adding program features rather than on the “plumbing” related to memory management.

The garbage collector takes responsibility only for handling memory management; that is, it does not provide an automated system for managing resources unrelated to memory. Therefore, if an explicit action to free a resource (other than memory) is required, programmers using that resource should utilize special CLI-compatible programming patterns that will aid in the cleanup of those resources (see Chapter 10).

Platform Portability

C# programs are platform-portable, supporting execution across different operating systems (cross-platform support)—that is, C# programs are capable of running on multiple operating systems and executing on different CLI implementations. Portability in this context is not limited to recompiling source code for each platform, but rather a single CLI module compiled for one framework can run on any CLI-compatible framework without needing to be recompiled. This portability occurs because the work of porting the code lies in the hands of the runtime implementation rather than the application developer (thanks to the .NET Standard). The restriction is, of course, that no platform-specific APIs can be used in your cross-platform code. When developing a cross-platform application, developers can package, or refactor, common code into cross-platform–compatible libraries and then call the libraries from platform-specific code to reduce the total amount of code required to support cross-platform applications.

Performance

Many programmers accustomed to writing unmanaged code will correctly point out that managed environments impose overhead on applications, no matter how simple they are. The trade-off is one of increased development productivity and reduced bugs in managed code versus runtime performance. The same dichotomy emerged as programming went from assembler to higher-level languages such as C, and from structured programming to object-oriented development. In the majority of scenarios, development productivity wins out, especially as the speed and reduced price of hardware surpass the demands of applications. Time spent on architectural design is much more likely to yield big performance gains than the complexities of low-level development. In the climate of security holes caused by buffer overruns, managed execution is even more compelling.

Undoubtedly, certain development scenarios (e.g., device drivers) may not yet fit with managed execution. However, as managed execution increases in capability and sophistication, many of these performance considerations will likely vanish. Unmanaged execution will then be reserved for development where precise control or circumvention of the runtime is deemed necessary.3

3. Indeed, Microsoft has indicated that managed development will be the predominant means of writing applications for its Windows platform in the future, even for those applications that are integrated with the operating system.

Furthermore, the runtime introduces several factors that can contribute to improved performance over native compilation. For example, because translation to machine code takes place on the destination machine, the resultant compiled code matches the processor and memory layout of that machine, resulting in performance gains generally not leveraged by non-jitted languages. Also, the runtime is able to respond to execution conditions that direct compilation to machine code rarely takes into account. If, for example, the box has more memory than is required, unmanaged languages will still de-allocate their memory at deterministic, compile-time–defined execution points in the code. Alternatively, JIT-compiled languages will need to de-allocate memory only when it is running low or when the program is shutting down. Even though jitting can add a compile step to the execution process, code efficiencies that a jitter can insert may lead to improved performance rivaling that of programs compiled directly to machine code. Ultimately, CLI programs are not necessarily faster than non-CLI programs, but their performance is competitive.

Assemblies, Manifests, and Modules

Included in the CLI is the specification of the CIL output from a source language compiler, usually an assembly. In addition to the CIL instructions themselves, an assembly includes a manifest that is made up of the following components:

  • The types that an assembly defines and imports

  • Version information about the assembly itself

  • Additional files the assembly depends on

  • Security permissions for the assembly

The manifest is essentially a header to the assembly, providing all the information about what an assembly is composed of, along with the information that uniquely identifies it.

Assemblies can be class libraries or the executables themselves, and one assembly can reference other assemblies (which, in turn, can reference more assemblies), thereby establishing an application composed of many components rather than existing as one large, monolithic program. This is an important feature that modern programming frameworks take for granted, because it significantly improves maintainability and allows a single component to be shared across multiple programs.

In addition to the manifest, an assembly contains the CIL code within one or more modules. Generally, the assembly and the manifest are combined into a single file, as was the case with HelloWorld.exe in Chapter 1. However, it is possible to place modules into their own separate files and then use an assembly linker (al.exe) to create an assembly file that includes a manifest referencing each module.4 This approach not only provides another means of breaking a program into components but also enables the development of one assembly using multiple source languages.

4. This is partly because one of the primary CLI IDEs, Visual Studio .NET, lacks functionality for working with assemblies composed of multiple modules. Current implementations of Visual Studio .NET do not have integrated tools for building multimodule assemblies, and when they use such assemblies, IntelliSense does not fully function.

Casually, the terms module and assembly are somewhat interchangeable. However, the term assembly is predominant when talking about CLI-compatible programs or libraries. Figure 24.2 depicts the various component terms.

A schematic representation of assemblies with modules.

Figure 24.2: Assemblies with the modules and files they reference

Note that both assemblies and modules can also reference files such as resource files that have been localized to a particular language. Although it is rare, two different assemblies can reference the same module or file.

Even though an assembly can include multiple modules and files, the entire group of files has only one version number, which is placed in the assembly manifest. Therefore, the smallest versionable component within an application is the assembly, even if that assembly is composed of multiple files. If you change any of the referenced files—even to release a patch—without updating the assembly manifest, you will violate the integrity of the manifest and the entire assembly itself. As a result, assemblies form the logical construct of a component or unit of deployment.

Note

Assemblies—not the individual modules that compose them—form the smallest unit that can be versioned and installed.

Even though an assembly (the logical construct) could consist of multiple modules, most assemblies contain only one. Furthermore, Microsoft now provides an ILMerge.exe utility for combining multiple modules and their manifests into a single file assembly.

Because the manifest includes a reference to all the files an assembly depends on, it is possible to use the manifest to determine an assembly’s dependencies. Furthermore, at execution time, the runtime needs to examine only the manifest to determine which files it requires. Only tool vendors distributing libraries shared by multiple applications (e.g., Microsoft) need to register those files at deployment time. This makes deployment significantly easier. Often, deployment of a CLI-based application is referred to as xcopy deployment, after the Windows xcopy command that simply copies files to a selected destination.

Common Intermediate Language

In keeping with the Common Language Infrastructure name, another important feature of the CIL and the CLI is to support the interaction of multiple languages within the same application (instead of portability of source code across multiple operating systems). As a result, the CIL is the intermediate language not only for C#, but also for many other languages, including Visual Basic .NET, the Java-like language J#, some incantations of Smalltalk, C++, and a host of others (more than 20 at the time of this writing, including versions of COBOL and FORTRAN). Languages that compile to the CIL are termed source languages, and each has a custom compiler that converts the source language to the CIL. Once compiled to the CIL, the source language is insignificant. This powerful feature enables the development of libraries by different development groups across multiple organizations, without concern for the language choice of a particular group. Thus, the CIL enables programming language interoperability as well as operating system portability.

Note

A powerful feature of the CLI is its support for multiple languages. This support enables the creation of programs using multiple languages and the accessibility of libraries written in one language from code written in a different language.

Common Type System

Regardless of the programming language, the resultant program operates internally on data types; therefore, the CLI includes the Common Type System (CTS). The CTS defines how types are structured and laid out in memory, as well as the concepts and behaviors that surround types. It includes type manipulation directives alongside the information about the data stored within the type. The CTS standard applies to how types appear and behave at the external boundary of a language because the purpose of the CTS is to achieve interoperability between languages. It is the responsibility of the runtime at execution time to enforce the contracts established by the CTS.

Within the CTS, types are classified into two categories:

  • Values are bit patterns used to represent basic types, such as integers and characters, as well as more complex data in the form of structures. Each value type corresponds to a separate type designation not stored within the bits themselves. The separate type designation refers to the type definition that provides the meaning of each bit within the value and the operations that the value supports.

  • Objects contain within them the object’s type designation. (This helps in enabling type checking.) Objects have identity that makes each instance unique. Furthermore, objects have slots that can store other types (either values or object references). Unlike with values, changing the contents of a slot does not change the identity of the object.

These two categories of types translate directly to C# syntax that provides a means of declaring each type.

Common Language Specification

Since the language integration advantages provided by the CTS generally outweigh the costs of implementing it, the majority of source languages support the CTS. However, there is also a subset of CTS language conformance called the Common Language Specification (CLS), whose focus is on library implementations. The CLS is intended for library developers and provides them with standards for writing libraries that are accessible from the majority of source languages, regardless of whether the source languages using the library are CTS-compliant. It is called the Common Language Specification because it is intended to also encourage CLI languages to provide a means of creating interoperable libraries, or libraries that are accessible from other languages.

For example, although it is perfectly reasonable for a language to provide support for an unsigned integer, such a type is not included as part of the CLS. Therefore, developers implementing a class library should not externally expose unsigned integers because doing so would cause the library to be less accessible from CLS-compliant source languages that do not support unsigned integers. Ideally, then, any libraries that are to be accessible from multiple languages should conform to the CLS. Note that the CLS is not concerned with types that are not exposed externally to the assembly.

Also note that it is possible to have the compiler issue a warning when you create an API that is not CLS-compliant. To accomplish this, you use the assembly attribute System.CLSCompliant and specify a value of true for the parameter.

Metadata

In addition to execution instructions, CIL code includes metadata about the types and files included in a program. The metadata includes the following items:

  • A description of each type within a program or class library

  • The manifest information containing data about the program itself, along with the libraries it depends on

  • Custom attributes embedded in the code, providing additional information about the constructs that the attributes decorate

The metadata is not a cursory, nonessential add-on to the CIL, but rather represents a core component of the CLI implementation. It provides the representation and the behavior information about a type and includes location information about which assembly contains a particular type definition. It plays a key role in saving data from the compiler and making it accessible at execution time to debuggers and the runtime. This data not only is available in the CIL code but also is accessible during machine code execution so that the runtime can continue to make any necessary type checks.

Metadata provides a mechanism for the runtime to handle a mixture of native and managed code execution. Also, it increases code and execution robustness because it smooths the migration from one library version to the next, replacing compile-time–defined binding with a load-time implementation.

All header information about a library and its dependencies is found in a portion of the metadata known as the manifest. As a result, the manifest portion of the metadata enables developers to determine a module’s dependencies, including information about particular versions of the dependencies and signatures indicating who created the module. At execution time, the runtime uses the manifest to determine which dependent libraries to load, whether the libraries or the main program has been tampered with, and whether assemblies are missing.

The metadata also contains custom attributes that may decorate the code. Attributes provide additional metadata about CIL instructions that are accessible via the program at execution time.

Metadata is available at execution time by a mechanism known as reflection. With reflection, it is possible to look up a type or its member at execution time and then invoke that member or determine whether a construct is decorated with a particular attribute. This provides for late binding, in which the system determines which code to execute at execution time rather than at compile time. Reflection can even be used for generating documentation by iterating through metadata and copying it into a help document of some kind (see Chapter 18).

.NET Native and Ahead of Time Compilation

The .NET Native feature (supported by .NET Core and recent .NET Framework implementations) creates a platform-specific executable. This is referred to as ahead of time (AOT) compilation.

.NET Native allows programmers to continue to code in C# while achieving native code performance and faster startup times by eliminating the need to JIT compile code. When .NET Native compiles an application, the .NET FCL is statically linked to the application; .NET Framework runtime components optimized for static pre-compilation are included as well. These specially built components are optimized for .NET Native and provide improved performance over the standard .NET runtime. The compilation step does not change your application in any way. You are free to use all the constructs and APIs of .NET, as well as depend on managed memory and memory cleanup, since .NET Native will include all components of the .NET Framework in your executable.

Summary

This chapter described many new terms and acronyms that are important for understanding the context under which C# programs run. The preponderance of three-letter acronyms can be confusing, so Table 24.2 summarizes the terms and acronyms that are part of the CLI.

Table 24.2: Common C#-Related Acronyms

Acronym

Definition

Description

.NET

None

Microsoft’s implementation of the entire CLI stack. Includes the CLR, CIL, and various languages, all of which are CLS-compliant.

BCL

Base Class Library

The portion of the CLI specification that defines the collection, threading, console, and other base classes necessary to build virtually all programs.

C#

None

A programming language. Separate from the CLI standard is a C# Language Specification, also ratified by the ECMA and ISO standards bodies.

CIL (IL)

Common Intermediate Language

The language of the CLI specification that defines the instructions for the code executable on implementations of the CLI. It is sometimes also referred to as IL or Microsoft IL (MSIL) to distinguish it from other intermediate languages. (To indicate that it is a standard broader than Microsoft, CIL is preferred over MSIL and even IL.)

CLI

Common Language Infrastructure

The specification that defines the intermediate language, base classes, and behavioral characteristics that enable implementers to create Virtual Execution Systems and compilers in which source languages are interoperable on top of a common execution environment.

CLR

Common Language Runtime

Microsoft’s implementation of the runtime, as defined in the CLI specification.

CLS

Common Language Specification

The portion of the CLI specification that defines the core subset of features that source languages must support to be executable on runtimes implemented according to the CLI specification.

CTS

Common Type System

A standard generally implemented by CLI-compliant languages that defines the representation and behavior of types that the language exposes visibly outside a module. It includes concepts for how types can be combined to form new types.

FCL

.NET Framework Class Library

The class library that makes up Microsoft’s .NET Framework. It includes Microsoft’s implementation of the BCL as well as a large library of classes for such things as web development, distributed communication, database access, and rich client user interface development, among others.

VES (runtime)

Virtual Execution System

An agent that manages the execution of a program that is compiled for the CLI.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.15.225.173