Now we will go in detail about the various components that build the .NET framework and its functionalities.
Common Language Runtime
At the core of the .NET platform is the Common Language Runtime (CLR). The CLR simplifies application development, provides a robust and secure execution environment, supports multiple languages and simplifies application deployment and management.
The diagram below provides more details on the CLR's features:
In this section we will cover some of the more significant features provided to .NET applications by the CLR. These include:
• Memory Management
• Common Type System
Before moving further let us discuss briefly about Common Language Infrastructure(CLI) according to Standardizing Information and Communication Systems(ECMA) specifications. The Microsoft Shared Source CLI Implementation is a file archive containing working source code for the ECMA-334 (C#) and ECMA-335 (Common Language Infrastructure, or CLI) standards. In addition to the CLI implementation and the C# compiler, the Shared Source CLI Implementation from Microsoft called ROTOR contains tools, utilities, additional Framework classes, and samples.
For the benefit of existing codebases, the CLI standard also takes pains to describe in detail how unmanaged software can co-exist safely with managed components, enabling seamless sharing of computing resources and responsibilities.
Like the C runtime, the CLI has been designed to exploit the power of diverse platforms, as well as to complement existing tools, languages, and runtimes. Let's look at a few of the likely ways that the Shared Source CLI Implementation might interest you:
• There are significant differences in implementation between this code and the code for Microsoft's commercial CLR implementation, both to facilitate portability and to make the code base more approachable. If you are a developer who is interested in knowing how JIT compilers and garbage collectors work, or of how Microsoft Visual Studio works on your behalf under the covers, this distribution
will definitely hold your attention!
• The distribution will help you in creating courseware around interesting topics that can be illustrated by this codebase.
• The distribution will help you in implementing your own version of the CLI and it also helps you in understanding the way the compilers and tools target the CLI.
The Garbage Collector (GC) is responsible for collecting the objects no longer referenced by the application. The GC may automatically be invoked by the CLR or the application may explicitly invoke the GC by calling GC.Collect. Objects are not released from memory until the GC is invoked and setting an object reference to
Nothing does not invoke the GC, a period of time often elapses between when the object is no longer referenced by the application and when the GC collects it.
• 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, which helps ensure that objects written in different languages can interact with each other.
The Common Type System can be divided into two general categories of types, Reference type and Value type each of which is further divided into subcategories.
Value types directly contain the data, and instances of value types are either allocated on the stack or allocated inline in a structure. Value types can be built-in (implemented by the runtime), user-defined, or enumerations.
The core value types supported by the .NET platform reside within the root of the System namespace. There types are often referred to as the .NET “Primitive Types”.
They include:
• Boolean
• Byte
• Char
• DateTime
• Decimal
• Double
• Guid
• Int16
• Int32
• Int64
• SByte
• Single
• Timespan
Reference types store a reference to the value's memory address, and are allocated on the heap. Reference types can be self-describing types, pointer types, or interface types. The type of a reference type can be determined from values of selfdescribing types. Self-describing types are further split into arrays and class types.
Sub Test()
Dim myInteger as Integer
Dim myObject as Object
End Sub
‘myInteger a Value type is automatically cleaned up when the Sub ends.
‘But myObject a Reference type is not cleaned up until the GC is run.
Another difference is when one variable is set equal to another or passed as a parameter to a method call. When a variable of a reference type (A) is set equal to another variable of the same type (B), variable A is assigned a reference to B. Both variables reference the same object. When a variable of value type (A) is set equal to another variable of the same type (B), variable A receives a copy of the contents of B. Each variable will have its own individual copy of the data.
Yet another difference between the behaviors of value types versus reference types is how equality is determined. Two variables of a given reference type are determined to be equal if both the variables refer to the same object. Two variables of a given value type are determined to be equal if the state of the two variables are equal.
The final difference between the two is the way the instances of a type are initialized. In a reference type, the variable is initialized with a default value of Null. The variable will not reference an object until explicitly done by the object. Whereas a variable declared as a value type will always reference a valid object.
In vb.net we can define custom types by using the Structure keyword. Let’s look at an example wherein we define a custom value type.
Module Module1
Public Structure Test
Public myString as String
Public myInteger as Integer
End Structure
Public Sub Main()
‘Notice that both declarations are equivalent
‘Both x and y are instance of type test
Dim x as New Test()
Dim y as Test
x.myInteger = 4
y.myString = “Test”
‘Reference to x is assigned to y
y = x
y.myInteger = 1
y.myString = “Changed”
Console.WriteKine(String.Format(“x : myInt = {0} and String = {1} ”, _
x.myInteger, x.myString))
Console.WriteKine(String.Format(“y : myInt = {0} and String = {1} ”, _
y.myInteger, y.myString))
End Sub
x and then set y equal to x. Since x and y are both instances of value types, y is set equal to the value of x. After changing the fields in y write the value of the fields in both x and y to the Console. The output of the program is:
x: myInt = 4 and myString = Test
y: myInt = 1 and myString = Changed
Notice that even after changing the value of fields in y it did not affect x. This is exactly the behavior required for primitive types.
Boxing occurs when an instance of a value type is converted to a reference type. An instance of a value type can be converted either to a System.Object or to any other interface type implemented by the value type.
Module Module1
Public Function Add(ByVal x As Object, ByVal y As Object) As Object
Add = x + y
End Function
Public Sub Main
Dim x As Integer = 2
Dim y As Integer = 3
Dim sum As Integer
Sum = Add(x , y)
Console.WriteLine(“ {0) + {1} = {2} ”, x, y, sum)
End Sub
End Module
In the above example both x and y are boxed before they are passed to Add.
Then x,y and Sum are boxed before they are passed to WriteLine. Unboxing involves the conversion of an instance of a reference type back to its original value type. In Vb.net it is done using the helper functions in the Microsoft.VisualBasic.Helpers namespace. For example in the above example, IntegerType.FromObject is called to unbox the return parameter of type object back to Integer.
Since the .NET Class Framework contains literally thousands of types, a set of related types is presented to the developer within a single namespace. For example, the System namespace (which you should be most familiar with) contains the Object base type, from which all other types ultimately derive. In addition the System namespace contains types of integers, characters, strings, exception handling, and console I/O’s as well as a bunch of utility types that convert safely between data types, format data types, generate random numbers, and perform various math functions. All applications use types from System namespace.
To access any platform feature, you need to know which namespace contains the type that exposes the functionality you want. If you want to customize the behavior of any type, you can simply derive your own type from the desired .NET framework type. The .NET Framework relies on the object-oriented nature of the platform to present a consistent programming paradigm to software developers. It also enables you to create your own namespaces containing their own types, which merge seamlessly into the programming paradigm. This greatly simplifies the Software Development.
The table below lists some of the general namespaces, with a brief description of what the classes in that namespace is used for:
Common Language Runtime
At the core of the .NET platform is the Common Language Runtime (CLR). The CLR simplifies application development, provides a robust and secure execution environment, supports multiple languages and simplifies application deployment and management.
The diagram below provides more details on the CLR's features:
In this section we will cover some of the more significant features provided to .NET applications by the CLR. These include:
• Memory Management
• Common Type System
Before moving further let us discuss briefly about Common Language Infrastructure(CLI) according to Standardizing Information and Communication Systems(ECMA) specifications. The Microsoft Shared Source CLI Implementation is a file archive containing working source code for the ECMA-334 (C#) and ECMA-335 (Common Language Infrastructure, or CLI) standards. In addition to the CLI implementation and the C# compiler, the Shared Source CLI Implementation from Microsoft called ROTOR contains tools, utilities, additional Framework classes, and samples.
For the benefit of existing codebases, the CLI standard also takes pains to describe in detail how unmanaged software can co-exist safely with managed components, enabling seamless sharing of computing resources and responsibilities.
Like the C runtime, the CLI has been designed to exploit the power of diverse platforms, as well as to complement existing tools, languages, and runtimes. Let's look at a few of the likely ways that the Shared Source CLI Implementation might interest you:
• There are significant differences in implementation between this code and the code for Microsoft's commercial CLR implementation, both to facilitate portability and to make the code base more approachable. If you are a developer who is interested in knowing how JIT compilers and garbage collectors work, or of how Microsoft Visual Studio works on your behalf under the covers, this distribution
will definitely hold your attention!
• The distribution will help you in creating courseware around interesting topics that can be illustrated by this codebase.
• The distribution will help you in implementing your own version of the CLI and it also helps you in understanding the way the compilers and tools target the CLI.
Automatic Memory Management
Now let us discuss about an important feature of the CLR called Automatic Memory Management. A major feature of .NET framework CLR is that the runtime automatically handles the allocation and release of an object’s memory resources. Automatic memory management enhances code quality and developer productivity without negatively impacting expressiveness or performance.The Garbage Collector (GC) is responsible for collecting the objects no longer referenced by the application. The GC may automatically be invoked by the CLR or the application may explicitly invoke the GC by calling GC.Collect. Objects are not released from memory until the GC is invoked and setting an object reference to
Nothing does not invoke the GC, a period of time often elapses between when the object is no longer referenced by the application and when the GC collects it.
Common Type System
The Common Type System defines how data types are declared, used, and managed in the runtime, and is also an important part of the runtime’s support for the Cross- Language Integration. The common type system 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, which helps ensure that objects written in different languages can interact with each other.
The Common Type System can be divided into two general categories of types, Reference type and Value type each of which is further divided into subcategories.
Common Type System Architecture
The .NET type system has two different kinds of types namely Value types and Reference types.Value types directly contain the data, and instances of value types are either allocated on the stack or allocated inline in a structure. Value types can be built-in (implemented by the runtime), user-defined, or enumerations.
The core value types supported by the .NET platform reside within the root of the System namespace. There types are often referred to as the .NET “Primitive Types”.
They include:
• Boolean
• Byte
• Char
• DateTime
• Decimal
• Double
• Guid
• Int16
• Int32
• Int64
• SByte
• Single
• Timespan
Reference types store a reference to the value's memory address, and are allocated on the heap. Reference types can be self-describing types, pointer types, or interface types. The type of a reference type can be determined from values of selfdescribing types. Self-describing types are further split into arrays and class types.
Value Type vs. Reference Type
The primary difference between reference and value types is how instances of the two types are treated by the CLR. One difference is that the GC collects instances of reference types that are no longer referenced by the application. Instances of value types are automatically cleaned up when the variable goes out of scope. Let’s take a look at an example in VB.NET:Sub Test()
Dim myInteger as Integer
Dim myObject as Object
End Sub
‘myInteger a Value type is automatically cleaned up when the Sub ends.
‘But myObject a Reference type is not cleaned up until the GC is run.
Another difference is when one variable is set equal to another or passed as a parameter to a method call. When a variable of a reference type (A) is set equal to another variable of the same type (B), variable A is assigned a reference to B. Both variables reference the same object. When a variable of value type (A) is set equal to another variable of the same type (B), variable A receives a copy of the contents of B. Each variable will have its own individual copy of the data.
Yet another difference between the behaviors of value types versus reference types is how equality is determined. Two variables of a given reference type are determined to be equal if both the variables refer to the same object. Two variables of a given value type are determined to be equal if the state of the two variables are equal.
The final difference between the two is the way the instances of a type are initialized. In a reference type, the variable is initialized with a default value of Null. The variable will not reference an object until explicitly done by the object. Whereas a variable declared as a value type will always reference a valid object.
Custom Types
A Custom Type is a set of data and related behavior that is defined by the developer. A developer can define both custom reference type and custom value types.In vb.net we can define custom types by using the Structure keyword. Let’s look at an example wherein we define a custom value type.
Module Module1
Public Structure Test
Public myString as String
Public myInteger as Integer
End Structure
Public Sub Main()
‘Notice that both declarations are equivalent
‘Both x and y are instance of type test
Dim x as New Test()
Dim y as Test
x.myInteger = 4
y.myString = “Test”
‘Reference to x is assigned to y
y = x
y.myInteger = 1
y.myString = “Changed”
Console.WriteKine(String.Format(“x : myInt = {0} and String = {1} ”, _
x.myInteger, x.myString))
Console.WriteKine(String.Format(“y : myInt = {0} and String = {1} ”, _
y.myInteger, y.myString))
End Sub
x and then set y equal to x. Since x and y are both instances of value types, y is set equal to the value of x. After changing the fields in y write the value of the fields in both x and y to the Console. The output of the program is:
x: myInt = 4 and myString = Test
y: myInt = 1 and myString = Changed
Notice that even after changing the value of fields in y it did not affect x. This is exactly the behavior required for primitive types.
Boxing and Unboxing Value Types
Sometimes it is required to treat an instance of a value type as if it were an instance of a reference type. An example of this is when a value type is passed ByRef as a parameter of a method. This is where the concept of Boxing becomes important.Boxing occurs when an instance of a value type is converted to a reference type. An instance of a value type can be converted either to a System.Object or to any other interface type implemented by the value type.
Module Module1
Public Function Add(ByVal x As Object, ByVal y As Object) As Object
Add = x + y
End Function
Public Sub Main
Dim x As Integer = 2
Dim y As Integer = 3
Dim sum As Integer
Sum = Add(x , y)
Console.WriteLine(“ {0) + {1} = {2} ”, x, y, sum)
End Sub
End Module
In the above example both x and y are boxed before they are passed to Add.
Then x,y and Sum are boxed before they are passed to WriteLine. Unboxing involves the conversion of an instance of a reference type back to its original value type. In Vb.net it is done using the helper functions in the Microsoft.VisualBasic.Helpers namespace. For example in the above example, IntegerType.FromObject is called to unbox the return parameter of type object back to Integer.
The .NET Class Framework
We will now discuss about the .NET Class Framework. In conjunction with the CLR, the Microsoft has developed a comprehensive set of framework classes, several of which are shown below:Since the .NET Class Framework contains literally thousands of types, a set of related types is presented to the developer within a single namespace. For example, the System namespace (which you should be most familiar with) contains the Object base type, from which all other types ultimately derive. In addition the System namespace contains types of integers, characters, strings, exception handling, and console I/O’s as well as a bunch of utility types that convert safely between data types, format data types, generate random numbers, and perform various math functions. All applications use types from System namespace.
To access any platform feature, you need to know which namespace contains the type that exposes the functionality you want. If you want to customize the behavior of any type, you can simply derive your own type from the desired .NET framework type. The .NET Framework relies on the object-oriented nature of the platform to present a consistent programming paradigm to software developers. It also enables you to create your own namespaces containing their own types, which merge seamlessly into the programming paradigm. This greatly simplifies the Software Development.
The table below lists some of the general namespaces, with a brief description of what the classes in that namespace is used for:
In addition to the general namespace the .Net Class Framework offers namespaces whose types are used for building specific application types. The table below lists some of the application specific namespaces:
The figure below shows the JIT Process:
JIT Compilation Process
The JIT process enables a secure environment by making certain assumptions:
• Type references are compatible with the type being referenced.
• Operations are invoked on an object only if they are within the execution parameters for that object.
• Identities within the application are accurate.
By following these rules, the managed execution can guarantee that code being executed is type safe; the execution will only take place in memory that it is allowed to access. This is possible by the verification process that occurs when the MSIL is converted into CPU-specific code. During this verification, the code is examined to ensure that it is not corrupt, it is type safe, and the code does not interfere with existing security policies that are in place on the system.
Just-In-Time Compilation (JIT)
The MSIL is the language that all of the .NET languages compile down to. After they are in this intermediate language, a process called Just-In-Time (JIT) compilation occurs when resources are used from your application at runtime. JIT allows “parts” of your application to execute when they are needed, which means that if something is never needed, it will never compile down to the native code. By using the JIT, the CLR can cache code that is used more than once and reuse it for subsequent calls, without going through the compilation process again.The figure below shows the JIT Process:
JIT Compilation Process
The JIT process enables a secure environment by making certain assumptions:
• Type references are compatible with the type being referenced.
• Operations are invoked on an object only if they are within the execution parameters for that object.
• Identities within the application are accurate.
By following these rules, the managed execution can guarantee that code being executed is type safe; the execution will only take place in memory that it is allowed to access. This is possible by the verification process that occurs when the MSIL is converted into CPU-specific code. During this verification, the code is examined to ensure that it is not corrupt, it is type safe, and the code does not interfere with existing security policies that are in place on the system.