Like any other platform, the .NET Framework introduces terminology that you need to be aware of. Following is a list of some of these terms.
1.1 CLR
The Common Language Runtime (CLR) is a key .NET Framework
component. The CLR is the container, or the execution environment, in which all the managed code runs. The CLR gets its name from the fact that .NET provides a binary standard and any programming language that adheres to the binary standard can be used for writing code that can be run by the CLR. In its function and nature, the CLR is similar to the Java Virtual Machine (JVM). The CLR provides infrastructure services to support execution of managed code. These services include automatic memory management, type safety, thread and process management, security, and versioning. The CLR sits between the managed code and the operating system so that your code is insulated from interacting directly with the operating system. This arrangement makes your code portable to some extent and also frees you from having to do system-level tasks so that you can concentrate on writing application code.
Microsoft .NET Framework provides a Common Language Runtime (CLR) that manages the execution of source code after being compiled into Microsoft intermediate language (MSIL), OptIL, or native machine code. All code based on MSIL or OptIL executes as managed code; that is code that runs under a "contract of cooperation" with the .NET Framework. The.NET Framework provides services such as memory management, cross language integration, exception handling, code access security, and automatic lifetime control of objects. In return, managed code must supply enough information in metadata to enable the .NET Framework to locate and unwind stack frames. For a high level description of the features that the .NET Framework provides to managed code, see the ".NET Framework Overview" specification. A key feature of CLR is its ability to provide software isolation of programs running within a single address space. It does this by enforcing typesafe access to all areas of memory when running typesafe managed code. Some compilers generate MSIL that is not only typesafe but whose type safety can be proven by simply examining the MSIL. This process, verification, allows servers to quickly examine user programs written in MSIL and only run those that it can demonstrate will not make unsafe memory references. This independent verification is critical to truly scalable servers that execute user-defined programs (scripts).
The CLR provides the following services:
Code management
Software memory isolation
Verification of the type safety of MSIL
Conversion of MSIL to native code
Loading and execution of managed code (MSIL or native)
Accessing metadata (enhanced type information)
Managing memory for managed objects
Insertion and execution of security checks
Handling exceptions, including cross-language exceptions
Interoperation between .NET Framework objects and COM objects
Automation of object layout for late binding
Supporting developer services (profiling, debugging, etc.)
The CLR supplies the common infrastructure that allows tools and programming languages to benefit from cross-language integration. Any
technical improvements to the CLR will benefit all languages and tools that
target the .NET Framework.
One of the most important functions of the CLR is on-the-fly conversion of MSIL (or OptIL) to native code. Source code compilers generate MSIL (or OptIL), and JIT compilers convert that MSIL to native code for specific machine architectures. As long as a simple set of rules is followed by the MSIL generator, the same MSIL code will run on any architecture that supports the .NET Framework. Because the conversion from MSIL to native code occurs on the target machine, the generated native code can take advantage of hardware-specific optimizations. Other significant CLR functions include class loading, verification, and support for security checks
1.2 Managed Code
Managed code runs under a contract of cooperation with the CLR. This means that managed code must supply the metadata necessary for the runtime to provide services such as memory management, cross-language integration, code access security, and automatic control of object lifetime

1.3 MSIL
The Microsoft Intermediate Language (MSIL) is the equivalent of Java byte code. The MSIL executes the managed code. Languages that support generating MSIL can leverage the infrastructure services of the CLR. MSIL is a stack-based set of instructions designed to be easily generated from source code by compilers and other tools. Several kinds of instructions are provided, including instructions for arithmetic and logical operations, control flow, direct memory access, exception handling, and method invocation. There is also a set of MSIL instructions for implementing object-oriented
programming constructs such as virtual method calls, field access, array access, and object allocation and initialization.The MSIL instruction set can be directly interpreted by simply tracking the
data types on the stack and emulating the MSIL instructions. It can also be converted efficiently into native code. The design of MSIL allows this process to produce optimized native code at reasonable cost. The design of MSIL allows programs that are not typesafe to be expressed, since this is essential for support of some common programming languages. At the same time, by following a simple set of rules, it is possible to generate MSIL programs that are not only typesafe but can easily be proven to be so (see the Verification section for more information about type safety and verification).
OptIL is a subset of MSIL that can be generated by optimizing compiler front ends. OptIL contains embedded annotations, which are MSIL instructions that supply control flow and register allocation information. Since OptIL is a subset of MSIL, any component that can execute or analyze MSIL can also analyze or execute OptIL (ignoring the embedded annotations if necessary). The OptJIT compiler (to be shipped in a future release), however, uses the embedded information to rapidly produce optimized native code. The correctness of this native code depends on the annotations, so they are subject to verification. OptIL is useful in situations where limited time and memory resources are available during the conversion to native code (ie at JIT time), yet the native code produced must meet high performance standards.
1.4 JIT Compilation
The CLR provides three JIT compilers for converting MSIL to native code:
EconoJIT, JIT, and OptJIT. Each JIT compiler has been designed to meet
specific goals with respect to performance and resource usage. The
performance characteristics are summarized in
1. Because of the low overhead of the EconoJIT compiler, as well as the ease with which it can be ported to new architectures, the .NET Framework does not include an interpreter for MSIL. (EconoJIT is so named because it performs the same task as the full JIT compiler, but using less computer resources. As a trade-off, the quality of the generated code is not so high). In some cases, tools vendors or researchers might want to design their own JIT compilers for use with the .NET Framework. Using the standard interface between the CLR and a JIT compiler, a third-party JIT compiler can
be "plugged in" to the CLR and interact appropriately. This interface (to be published in a future release) will consist of two parts: one used when MSIL is compiled to native code (the JIT/CLR interface) and the other when the compiled code is executed (the code manager). The code manager performs the stack walks required for memory management, exception handling, and security checks. It also performs other functions, such as converting the .NET Framework exceptions into the form expected by the source language processor's exception handlers. Vendors who design custom JIT compilers
can use the CLR's code manager or they can design a custom code manager to describe the layout of the method state for code they have compiled
1.5 Assembly
An assembly is a versionable unit of deployment of the .NET Framework. It is equivalent to Java's .jar, .war, and .ear file formats but is a lot more feature-rich. An assembly performs the following functions:
It contains code that the runtime executes. MSIL code in a
Portable eecutable (PE) file will not be executed if it does not
ve an associated assembly manifest. Note that each assembly n have nly one entry point.
It forms a security boundary. An assembly is the unit at which permissions are requested and granted. An assembly is to .NET security what a protection domain is to Java security.
It forms a type boundary. Every type's identity includes the name of the assembly in which it resides. A type MyType loaded in the scope of one assembly is not the same as a type MyType loaded in the scope of another assembly.
It forms a reference scope boundary. The assembly's manifest contains assembly metadata that is used for resolving types and satisfying resource requests. The manifest specifies the types and resources that are exposed outside the assembly. The manifest also enumerates other assemblies on which it depends.
It forms a version boundary. The assembly is the smallest versionable unit in the CLR; all types and resources in the same assembly are versioned as a unit. The assembly's manifest describes the version dependencies you specify for any dependent assemblies.
It forms a deployment unit. When an application starts, only the assemblies the application initially calls must be present. Other assemblies, such as localization resources or assemblies containing utility classes, can be retrieved on demand. In this way, applications can be kept simple and thin when first downloaded.
Assemblies can be static or dynamic. Static assemblies can include .NET Framework types (interfaces and classes) as well as resources for the assembly (bitmaps, JPEG files, resource files, and so on). Static assemblies are stored on disk in PE files. You can also use the .NET Framework to create dynamic assemblies, which are run directly from memory and are not saved to disk before execution.
You can save dynamic assemblies to disk after they have executed.
There are several ways to create assemblies. You can use development tools,such as Visual Studio .NET, that you have used in the past to create .dll or .exe files. You can use tools provided in the .NET Framework Software Development Kit (SDK) to create assemblies by referencing modules created in other development environments. You can also use CLR application programming interfaces (APIs) to create dynamic assemblies.
1.6 Application Domain
Application domains provide a secure and versatile unit of processing that the CLR can use to enable isolation between applications. You can run several application domains in a single process with the same level of isolation that would exist in separate processes, but without incurring the additional overhead of making cross-process calls or switching between processes. The ability to run multiple applications within a single process
increases server scalability dramatically. The isolation provided by
application domains has the following benefits:
Faults in one application cannot affect other applications. Because type-safe code cannot cause memory faults, using application domains ensures that code running in one domain cannot affect other applications in the process.
You can stop individual applications without stopping the entire process. Using application domains enables you to unload the code running in a single application.
Code running in one application cannot directly access code or resources in another application. The CLR enforces this isolation by preventing direct calls between objects in different application domains. Cross-domain calls use the same remote call infrastructure as calls between two processes or between two machines.
The behavior of code is scoped by the application in which it runs. In other words, the application domain provides configuration settings such as application version policies, the location of any remote assemblies it accesses, and information about where to locate assemblies that are loaded into the domain.
You can control permissions granted to code according to the application domain in which the code is running. Application domains help to isolate multiple applications running on a single process. Much like the modern-day Java 2 Enterprise Edition (J2EE) application servers, which use dynamic class loaders to isolate applications from one another, an application domain isolates applications in their own little world.
1.7 Runtime Host
The runtime host loads the runtime into a process, creates the application domains within the process, and loads user code into the application domains. The various runtime hosts are as follows:
ASP.NET loads the runtime into the process that is to handle the Web request. ASP.NET also creates an application domain for each Web application that will run on a Web server.
A shell executable invokes runtime hosting code to transfer control to the runtime each time an executable is launched from the shell.
Microsoft Internet Explorer creates application domains in which to run managed controls. The .NET Framework supports the downloading and execution of browser-based controls. The runtime interfaces with the extensibility mechanism of Microsoft Internet Explorer through a Multipurpose Internet Mail Extensions (MIME) filter to create application domains in which to run the managed controls. By default, one application domain is created for each Web site.
1.8 The Common Type System
As mentioned earlier, the CLR can provide infrastructure services to MSIL generated by any programming language (as long as the language can generate valid MSIL). Uniformity of data types becomes an issue when you're dealing with a standard for multiple languages. The Common Type System (CTS) is designed to streamline the types supported in the .NET world. The CTS defines how types are declared, used, and managed in the runtime, and it is also an important part of the runtime's support for cross-language integration. The CTS performs the following functions:
Establishes a framework that enables cross-language integration, type safety, and high-performance code execution.
Provides an object-oriented model that supports the complete
implementation of many programming languages.
Defines rules that languages must follow, something that helps to ensure that objects written in different languages can interact with one another.
A type can have several members:
Event: Defines an incident that can be responded to and defines methods for subscribing to, unsubscribing from, and firing the event. Events are often used to inform other types of state changes.
Field: Describes and contains the value of a type. Fields can be of any type supported by the runtime.
Nested type: Defines a type within the scope of the enclosing type.
Method: Describes operations available on the type. A method's signature specifies the allowable types of all its arguments and of its return value. A constructor is a special kind of method that initializes new instances of a type.
Property: Names a logical value or the state of the type and defines methods for getting or setting the property's value. Properties are often used to keep the public interface of a type independent from the type's actual representation. Type members have signatures and are inherited from their base type. Members such as methods can be overloaded and overridden.
1.8 Common Language Specification
The Common Language Specification (CLS) defines a set of rules for interoperability between components in different languages. Components written in other languages that adhere to this set of rules are said to be CLS-compliant and are accessible from other CLS-compliant languages.The CLS rules define a subset of the CTS; all the rules that apply to the Common Type System apply to the CLS, except where stricter rules are defined in the CLS. Most of the members defined by types in the .NET Framework are CLS-compliant. (These members are discussed later in this chapter.) Any language construct that would make it impossible to rapidly verify the type safety of code has been excluded from the CLS. As a result, all CLS-compliant languages can produce verifiable code.CLS compliance generally refers to the claim that CLS rules and restrictions are being followed. However, the concept has a more specific meaning, depending on whether you are describing CLS-compliant code or CLS-compliant development tools, such as a compiler. If you want your code to be CLS-compliant, you must expose functionality in a way that is CLS-compliant in the following places:
Definitions of your public classes
Definitions of the public members of public classes, and of members accessible to derived classes
Parameters and return types of public methods of public classes and of methods accessible to derived classes
The features you use in the definitions of your private classes, in the definitions of private methods on public classes, and in local variables do not have to follow the CLS rules. You can also use any language features you want in the code that implements your class and still have a CLS-compliant component. Code compliance is discussed in detail later, when we discuss the various code components, such as assemblies, methods,and types. For now, note that the C# language, which this book is about,has all the tools necessary to make your code CLS-compliant

