.NET Framework
The
.NET Framework is Microsoft's platform for building applications that
have visually stunning user experiences, seamless and secure
communication, and the ability to model a range of business processes.
The .Net Framework consists of:
- Common Language Runtime – provides an abstraction layer over the operating system
- Base Class Libraries – pre-built code for common low-level programming tasks
- Development frameworks and technologies – reusable, customizable solutions for larger programming tasks.
By
providing you with a comprehensive and consistent programming model and
a common set of APIs, the .NET Framework helps you to build
applications that work the way you want, in the programming language you
prefer, across software, services, and devices.
Common Language Runtime Overview
Compilers
and tools expose the runtime's functionality and enable you to write
code that benefits from this managed execution environment. Code that
you develop with a language compiler that targets the runtime is called
managed code; it benefits from features such as cross-language
integration, cross-language exception handling, enhanced security,
versioning and deployment support, a simplified model for component
interaction, and debugging and profiling services.
To enable the runtime to provide services to managed code, language compilers must emit metadata that describes the types, members, and references in your code. Metadata is stored with the code; every loadable common language runtime portable executable (PE) file contains metadata. The runtime uses metadata to locate and load classes, lay out instances in memory, resolve method invocations, generate native code, enforce security, and set run-time context boundaries.
The runtime automatically handles object layout and manages references to objects, releasing them when they are no longer being used. Objects whose lifetimes are managed in this way are called managed data. Garbage collection eliminates memory leaks as well as some other common programming errors. If your code is managed, you can use managed data, unmanaged data, or both managed and unmanaged data in your .NET Framework application. Because language compilers supply their own types, such as primitive types, you might not always know (or need to know) whether your data is being managed.
The common language runtime makes it easy to design components and applications whose objects interact across languages. Objects written in different languages can communicate with each other, and their behaviors can be tightly integrated. For example, you can define a class and then use a different language to derive a class from your original class or call a method on the original class. You can also pass an instance of a class to a method of a class written in a different language. This cross-language integration is possible because language compilers and tools that target the runtime use a common type system defined by the runtime, and they follow the runtime's rules for defining new types, as well as for creating, using, persisting, and binding to types.
As part of their metadata, all managed components carry information about the components and resources they were built against. The runtime uses this information to ensure that your component or application has the specified versions of everything it needs, which makes your code less likely to break because of some unmet dependency. Registration information and state data are no longer stored in the registry where they can be difficult to establish and maintain. Rather, information about the types you define (and their dependencies) is stored with the code as metadata, making the tasks of component replication and removal much less complicated.
Language compilers and tools expose the runtime's functionality in ways that are intended to be useful and intuitive to developers. This means that some features of the runtime might be more noticeable in one environment than in another. How you experience the runtime depends on which language compilers or tools you use. For example, if you are a Visual Basic developer, you might notice that with the common language runtime, the Visual Basic language has more object-oriented features than before.
To enable the runtime to provide services to managed code, language compilers must emit metadata that describes the types, members, and references in your code. Metadata is stored with the code; every loadable common language runtime portable executable (PE) file contains metadata. The runtime uses metadata to locate and load classes, lay out instances in memory, resolve method invocations, generate native code, enforce security, and set run-time context boundaries.
The runtime automatically handles object layout and manages references to objects, releasing them when they are no longer being used. Objects whose lifetimes are managed in this way are called managed data. Garbage collection eliminates memory leaks as well as some other common programming errors. If your code is managed, you can use managed data, unmanaged data, or both managed and unmanaged data in your .NET Framework application. Because language compilers supply their own types, such as primitive types, you might not always know (or need to know) whether your data is being managed.
The common language runtime makes it easy to design components and applications whose objects interact across languages. Objects written in different languages can communicate with each other, and their behaviors can be tightly integrated. For example, you can define a class and then use a different language to derive a class from your original class or call a method on the original class. You can also pass an instance of a class to a method of a class written in a different language. This cross-language integration is possible because language compilers and tools that target the runtime use a common type system defined by the runtime, and they follow the runtime's rules for defining new types, as well as for creating, using, persisting, and binding to types.
As part of their metadata, all managed components carry information about the components and resources they were built against. The runtime uses this information to ensure that your component or application has the specified versions of everything it needs, which makes your code less likely to break because of some unmet dependency. Registration information and state data are no longer stored in the registry where they can be difficult to establish and maintain. Rather, information about the types you define (and their dependencies) is stored with the code as metadata, making the tasks of component replication and removal much less complicated.
Language compilers and tools expose the runtime's functionality in ways that are intended to be useful and intuitive to developers. This means that some features of the runtime might be more noticeable in one environment than in another. How you experience the runtime depends on which language compilers or tools you use. For example, if you are a Visual Basic developer, you might notice that with the common language runtime, the Visual Basic language has more object-oriented features than before.
Some benefits of the runtime:
- Performance improvements.
- The ability to easily use components developed in other languages.
- Extensible types provided by a class library.
New
language features such as inheritance, interfaces, and overloading for
object-oriented programming; support for explicit free threading that
allows creation of multithreaded, scalable applications; support for
structured exception handling and custom attributes.
If you use Microsoft® Visual C++® .NET, you can write managed code using Visual C++, which provides the benefits of a managed execution environment as well as access to powerful capabilities and expressive data types that you are familiar with.
If you use Microsoft® Visual C++® .NET, you can write managed code using Visual C++, which provides the benefits of a managed execution environment as well as access to powerful capabilities and expressive data types that you are familiar with.
Additional runtime features include:
- Cross-language integration, especially cross-language inheritance.
- Garbage collection, which manages object lifetime so that reference counting is unnecessary.
- Self-describing objects, which make using Interface Definition Language (IDL) unnecessary.
- The ability to compile once and run on any CPU and operating system that supports the runtime.
You can also write managed code using the C# language, which provides the following benefits:
- Complete object-oriented design.
- Very strong type safety.
- A good blend of Visual Basic simplicity and C++ power.
- Garbage collection.
- Syntax and keywords similar to C and C++.
Common Type System
The common type system supports two general categories of types, each
of which is further divided into subcategories:
All types derive from the System..::.Object base type.
The following example shows the difference between reference types and value types.
The output from this program is as follows.
The following diagram illustrates how these various types are related.
Note that instances of types can be simply value types or
self-describing types, even though there are subcategories of these
types.
For more information about each type, see value
types, enumerations, classes, delegates, arrays, interfaces, and
pointers.
-
Value types
Value types directly contain their 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. For a list of built-in value types, see the .NET Framework Class Library. -
Reference types
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 self-describing types. Self-describing types are further split into arrays and class types. The class types are user-defined classes, boxed value types, and delegates.
All types derive from the System..::.Object base type.
The following example shows the difference between reference types and value types.
Visual Basic
Class Class1 Public Value As Integer = 0End Class 'Class1 Class Test Shared Sub Main() Dim val1 As Integer = 0 Dim val2 As Integer = val1 val2 = 123 Dim ref1 As New Class1() Dim ref2 As Class1 = ref1 ref2.Value = 123 Console.WriteLine("Values: {0}, {1}", val1, val2) Console.WriteLine("Refs: {0}, {1}", ref1.Value, ref2.Value) End Sub 'Main End Class 'Test
C#
using System;class Class1 {public int Value = 0; }class Test { static void Main() { int val1 = 0; int val2 = val1; val2 = 123; Class1 ref1 = new Class1(); Class1 ref2 = ref1; ref2.Value = 123; Console.WriteLine("Values: {0}, {1}", val1, val2); Console.WriteLine("Refs: {0}, {1}", ref1.Value, ref2.Value); } }
Values: 0, 123
Refs: 123, 123
Type classification
Values are binary representations of data, and types provide a way of
interpreting this data. A value type is stored directly as a binary
representation of the type's data. The value of a reference type is the
location of the sequence of bits that represent the type's data.
Every value has an exact type that completely defines the value's representation and the operations that are defined on the value. Values of self-describing types are called objects. While it is always possible to determine the exact type of an object by examining its value, you cannot do so with a value type or pointer type. A value can have more than one type. A value of a type that implements an interface is also a value of that interface type. Likewise, a value of a type that derives from a base type is also a value of that base type.
Every value has an exact type that completely defines the value's representation and the operations that are defined on the value. Values of self-describing types are called objects. While it is always possible to determine the exact type of an object by examining its value, you cannot do so with a value type or pointer type. A value can have more than one type. A value of a type that implements an interface is also a value of that interface type. Likewise, a value of a type that derives from a base type is also a value of that base type.
The runtime uses assemblies to locate and load types. The assembly
manifest contains the information that the runtime uses to resolve all
type references made within the scope of the assembly.
A type name in the runtime has two logical parts: the assembly name and the name of the type within the assembly. Two types with the same name but in different assemblies are defined as two distinct types.
Assemblies provide consistency between the scope of names seen by the developer and the scope of names seen by the runtime system. Developers author types in the context of an assembly. The content of the assembly a developer is building establishes the scope of names that will be available at run time.
A type name in the runtime has two logical parts: the assembly name and the name of the type within the assembly. Two types with the same name but in different assemblies are defined as two distinct types.
Assemblies provide consistency between the scope of names seen by the developer and the scope of names seen by the runtime system. Developers author types in the context of an assembly. The content of the assembly a developer is building establishes the scope of names that will be available at run time.
From the viewpoint of the runtime, a namespace is just a collection of
type names. Particular languages might have constructs and
corresponding syntax that help developers form logical groups of types,
but these constructs are not used by the runtime when binding types.
Thus, both the Object and String classes are part of the System namespace, but the runtime only recognizes the full names of each type, which are System..::.Object and System..::.String, respectively.
You can build a single assembly that exposes types that look like they
come from two different hierarchical namespaces, such as System.Collections and System.Windows.Forms. You can also build two assemblies that both export types whose names contain MyDll.MyClass.
If you create a tool to represent types in an assembly as belonging to
a hierarchical namespace, the tool must enumerate the types in an
assembly or group of assemblies and parse the type names to derive a
hierarchical relationship.
Language Interoperability Overview
Language interoperability is the ability of code to interact with code
that is written using a different programming language. Language
interoperability can help maximize code reuse and, therefore, improve
the efficiency of the development process.
Because developers use a wide variety of tools and technologies, each
of which might support different features and types, it has
historically been difficult to ensure language interoperability.
However, language compilers and tools that target the common language
runtime benefit from the runtime's built-in support for language
interoperability.
The common language runtime provides the necessary foundation for language interoperability by specifying and enforcing a common type system and by providing metadata. Because all languages targeting the runtime follow the common type system rules for defining and using types, the usage of types is consistent across languages. Metadata enables language interoperability by defining a uniform mechanism for storing and retrieving information about types. Compilers store type information as metadata, and the common language runtime uses this information to provide services during execution; the runtime can manage the execution of multilanguage applications because all type information is stored and retrieved in the same way, regardless of the language the code was written in.
To ensure that your managed code is accessible to developers using any programming language, the .NET Framework provides the Common Language Specification Writing CLS-Compliant Code. (CLS), which describes a fundamental set of language features and defines rules for how those features are used.
The common language runtime provides the necessary foundation for language interoperability by specifying and enforcing a common type system and by providing metadata. Because all languages targeting the runtime follow the common type system rules for defining and using types, the usage of types is consistent across languages. Metadata enables language interoperability by defining a uniform mechanism for storing and retrieving information about types. Compilers store type information as metadata, and the common language runtime uses this information to provide services during execution; the runtime can manage the execution of multilanguage applications because all type information is stored and retrieved in the same way, regardless of the language the code was written in.
Managed code benefits from the runtime's support for language interoperability in the following ways:
- Types can inherit implementation from other types, pass objects to another type's methods, and call methods defined on other types, regardless of the language the types are implemented in.
- Debuggers, profilers, or other tools are required to understand only one environment—the Microsoft intermediate language (MSIL) and metadata for the common language runtime—and they can support any programming language that targets the runtime.
- Exception handling is consistent across languages. Your code can throw an exception in one language and that exception can be caught and understood by an object written in another language.
To ensure that your managed code is accessible to developers using any programming language, the .NET Framework provides the Common Language Specification Writing CLS-Compliant Code. (CLS), which describes a fundamental set of language features and defines rules for how those features are used.
No comments:
Post a Comment