Tutorial Document
Tutorial Document
Welcome
.NET Guide
Get Started with .NET
Tour of .NET
.NET Microservices: Architecture for Containerized .NET Applications
.NET Architectural Components
.NET Standard
Target Frameworks
.NET Glossary
Choosing between .NET Core and .NET Framework for server apps
What is "managed code"?
Automatic Memory Management
Common Language Runtime (CLR)
Language Independence
Language Independence and Language-Independent Components
Framework Libraries
Class Library Overview
Base Types
.NET Class libraries
Portability Analyzer
Handling and throwing exceptions
.NET Assembly File Format
Garbage Collection
Generic types
Delegates and lambdas
LINQ
Common Type System & Common Language Specification
Asynchronous programming
Asynchronous programming in depth
Asynchronous Programming Patterns
Native interoperability
Collections and Data Structures
Numerics in .NET
Dates, times, and time zones
Events
Managed Execution Process
Metadata and Self-Describing Components
Building Console Applications
Parallel Processing and Concurrency
Application Essentials
File and Stream I/O
Globalization and Localization
Attributes
Framework Design Guidelines
XML Documents and Data
Threading
Parallel Programming
Security
Serialization
Developing for Multiple Platforms
.NET Core Guide
Get started
Get started with C# and Visual Studio Code
Build a C# Hello World app with .NET Core in Visual Studio 2017
Build a Visual Basic Hello World app with .NET Core in Visual Studio 2017
Build a class library with C# and .NET Core in Visual Studio 2017
Build a class library with Visual Basic and .NET Core in Visual Studio 2017
What's new in .NET Core
Windows Prerequisites
macOS Prerequisites
Linux Prerequisites
Tutorials
Building a complete .NET Core solution on Windows, using Visual Studio 2017
Get Started with C# and Visual Studio Code
Getting started with .NET Core on macOS
Getting started with .NET Core on macOS using Visual Studio for Mac
Building a complete .NET Core solution on macOS using Visual Studio for Mac
Getting started with .NET Core using the CLI tools
Developing Libraries with Cross Platform Tools
Developing ASP.NET Core applications
How to Manage Package Dependency Versions for .NET Core 1.0
Hosting .NET Core from native code
Create a custom template for dotnet new
Packages, Metapackages and Frameworks
Changes in CLI overview
Dependency management
Additions to the csproj format
Migration
Migration to csproj format
Mapping between project.json and csproj
Migrating from DNX
Application Deployment
Deploy apps with CLI tools
Deploy apps with Visual Studio
Creating a NuGet Package with Cross Platform Tools
Runtime package store
Docker
Building Docker Images for .NET Core Applications
Visual Studio Tools for Docker
Unit Testing
Unit testing with dotnet test and xUnit
Unit testing with dotnet test and MSTest
Running selective unit tests
Versioning
.NET Core Support
Runtime IDentifier catalog
.NET Core SDK Overview
.NET Core CLI Tools
Telemetry
Extensibility Model
Continuous Integration
Custom templates
dotnet
dotnet build
dotnet clean
dotnet help
dotnet install-script
dotnet migrate
dotnet msbuild
dotnet new
dotnet nuget delete
dotnet nuget locals
dotnet nuget push
dotnet pack
dotnet publish
dotnet restore
dotnet run
dotnet sln
dotnet store
dotnet test
dotnet vstest
Project modification commands
global.json
Porting from .NET Framework
Organizing projects for .NET Core
Analyzing third-party dependencies
Porting libraries
Build .NET Core from source
.NET Core distribution packaging
VS 2015/project.json docs
.NET Framework Guide
What's New
Get Started
Installation guide
Migration Guide
.NET Framework on Docker Guide
Running Console Apps in Containers
Development Guide
Application Domains and Assemblies
Resources in Desktop Apps
Accessibility
Data and Modeling
Client Applications
Service-Oriented Applications with WCF
Windows Workflow Foundation
Windows Service Applications
64-bit Applications
Web Applications with ASP.NET
Network Programming in the .NET Framework
Configuring Apps
Compiling Apps with .NET Native
Windows Identity Foundation
Debugging, Tracing, and Profiling
Deployment
Performance
Dynamic Programming
Managed Extensibility Framework (MEF)
Add-ins and Extensibility
Interoperating with Unmanaged Code
Unmanaged API Reference
XAML Services
Tools
Additional Class Libraries and APIs
C# Guide
Get Started
Tutorials
Tour of C#
What's new in C#
What's new in C# 7.1
What's new in C# 7
What's new in C# 6
Relationships between language and framework
C# Concepts
C# Type system
Namespaces
Basic Types
Classes
Structs
Tuples
Deconstructing tuples and other types
Interfaces
Methods
Properties
Indexers
Discards
Generics
Iterators
Delegates & events
Language Integrated Query (LINQ)
Asynchronous programming
Pattern Matching
Expression Trees
Native interoperability
Documenting your code
Versioning
C# Programming Guide
Language Reference
Walkthroughs
F# Guide
Tour of F#
Get Started
Get Started with Visual Studio
Get Started with Visual Studio for Mac
Get Started with Visual Studio Code and Ionide
Get Started with with the .NET Core CLI
Tutorials
F# Interactive
Type Providers
Introduction to Functional Programming
Functions as First-Class Values
Asynchronous and Concurrent Programming
Visual F# Development Environment Features
Configuring Projects
Targeting Older Versions of .NET
Using F# on Azure
Get started with Azure Blob storage using F#
Get started with Azure File storage using F#
Get started with Azure Queue storage using F#
Get started with Azure Table storage using F#
Package Management for F# Azure Dependencies
F# Language Reference
Keyword Reference
Symbol and Operator Reference
Functions
Values
Literals
F# Types
Type Inference
Primitive Types
Unit Type
Strings
Tuples
F# Collection Types
Lists
Options
Results
Sequences
Arrays
Generics
Records
Discriminated Unions
Enumerations
Reference Cells
Type Abbreviations
Classes
Structures
Inheritance
Interfaces
Abstract Classes
Members
Type Extensions
Parameters and Arguments
Operator Overloading
Flexible Types
Delegates
Object Expressions
Copy and Update Record Expressions
Casting and Conversions
Access Control
Conditional Expressions: if...then...else
Match Expressions
Pattern Matching
Active Patterns
Loops: for...to Expression
Loops: for...in Expression
Loops: while...do Expression
Assertions
Exception Handling
Attributes
Resource Management: the use Keyword
Namespaces
Modules
Import Declarations: The open Keyword
Signatures
Units of Measure
XML Documentation
Lazy Computations
Computation Expressions
Asynchronous Workflows
Query Expressions
Code Quotations
Fixed keyword
Compiler Directives
Compiler Options
Source Line, File, and Path Identifiers
Caller Information
Verbose Syntax
Code Formatting Guidelines
Visual Basic Guide
Get Started
What's New for Visual Basic
Visual Basic Breaking Changes in Visual Studio
Additional Resources for Visual Basic Programmers
Developing Applications
Programming in Visual Basic
Development with My
Accessing Data
Creating and Using Components
Printing and Reporting
Windows Forms Application Basics
Power Packs Controls
DataRepeater Control
Line and Shape Controls
Customizing Projects and Extending My with Visual Basic
Programming Concepts
Assemblies and the Global Assembly Cache
Asynchronous Programming with Async and Await
Attributes
Expression Trees
Iterators
Language-Integrated Query (LINQ)
Object-Oriented Programming
Reflection
Serialization
Threading
Program Structure and Code Conventions
Structure of a Program
Main Procedure
References and the Imports Statement
Namespaces
Naming Conventions
Coding Conventions
Conditional Compilation
How to: Break and Combine Statements in Code
How to: Collapse and Hide Sections of Code
How to: Label Statements
Special Characters in Code
Comments in Code
Keywords as Element Names in Code
Me, My, MyBase, and MyClass
Limitations
Language Features
Arrays
Collection Initializers
Constants and Enumerations
Control Flow
Data Types
Declared Elements
Delegates
Early and Late Binding
Error Types
Events
Interfaces
LINQ
Objects and Classes
Operators and Expressions
Procedures
Statements
Strings
Variables
XML
COM Interop
Introduction to COM Interop
How to: Reference COM Objects
How to: Work with ActiveX Controls
Walkthrough: Calling Windows APIs
How to: Call Windows APIs
How to: Call a Windows Function that Takes Unsigned Types
Walkthrough: Creating COM Objects
Troubleshooting Interoperability
COM Interoperability in .NET Framework Applications
Walkthrough: Implementing Inheritance with COM Objects
Language Reference
Typographic and Code Conventions
Visual Basic Runtime Library Members
Keywords
Attributes
Constants and Enumerations
Data Type Summary
Directives
Functions
Modifiers
Modules
Nothing
Objects
Operators
Properties
Queries
Statements
XML Comment Tags
XML Axis Properties
XML Literals
Error Messages
Reference
Command-Line Compiler
.NET Framework Reference Information
Language Specification
Sample Applications
Walkthroughs
Samples and Tutorials
Welcome to .NET
8/16/2017 • 1 min to read • Edit Online
See Getting Started with .NET Core to learn how to create .NET Core apps.
Build many types of apps with .NET, such as cloud, IoT, and games using free cross-platform tools. Your apps can
run on Android, iOS, Linux, macOS, and Windows. Deploy apps to servers or desktops and publish to app stores for
deployment on mobile devices. .NET is accessible to students and hobbyists, and all are welcome to participate in a
lively international developer community and make direct contributions to many of the .NET technologies.
News
.NET Core 2.0 Released!
Announcing .NET Core 2.0
Announcing .NET Standard 2.0
Announcing ASP.NET Core 2.0
Announcing Entity Framework Core 2.0
New for Visual Basic: .NET Standard Class Libraries and the dotnet CLI!
Visual Studio 2017 Version 15.3 Released
Introducing .NET Standard
Visual Studio for Mac: now generally available
Announcing Visual Studio 2017 General Availability
What's new for .NET Core and Visual Studio 2017 (video)
Announcing the .NET Framework 4.7
New Features in C# 7.0
Announcing F# 4.1 and the Visual F# Tools for Visual Studio 2017
Open Source Xamarin, Ready for you!
The week in .NET
Build 2017 on Channel 9 - Video on Microsoft's latest technologies and news!
Documentation
This documentation covers the breadth of .NET across platforms and languages. You can get started with .NET and
its languages in any of the following sections:
.NET Guide
.NET Core Guide
.NET Framework Guide
C# Guide
F# Guide
Visual Basic Guide
Additionally, you can browse the .NET API reference.
Open source
ihis documentation is completely open source. You can contribute in any way you like, from creating issues to
writing documentation. Additionally, much of .NET itself is open source:
.NET Core Home
.NET Libraries
.NET Core Runtime
Roslyn (C# and Visual Basic) Compiler Platform and IDE Tools
F# Compiler and IDE Tools
You can join other people who are already active in the .NET community to find out what's new or ask for help.
.NET Guide
7/29/2017 • 1 min to read • Edit Online
The .NET Guide provides a large amount of information about .NET. Depending on your familiarity with .NET, you
may wish to explore different sections of this guide and other sections of the .NET documentation.
New to .NET
If you're new to .NET, check out the Get Started article.
If you prefer to have a guided tour through major features of .NET, check out the Tour of .NET.
You can also read about .NET Architectural Components to get an overview of the various "pieces" of .NET and how
they fit together.
API Reference
Check out the .NET API Reference to see the breadth of APIs avaialable.
Get Started
8/14/2017 • 1 min to read • Edit Online
There are a number of ways to get started with .NET. Because .NET is a massive platform, there are multiple articles
in this documentation which show how you can get started with .NET, each from a different perspective.
.NET is a general purpose development platform. It has several key features, such as support for multiple
programming languages, asynchronous and concurrent programming models, and native interoperability, which
enable a wide range of scenarios across multiple platforms.
This article offers a guided tour through some of the key features of the .NET. See the .NET Architectural
Components topic to learn about the architectural pieces of .NET and what they're used for.
Programming languages
.NET supports multiple programming languages. The .NET implementations implement the Common Language
Infrastructure (CLI), which among other things specifies a language-independent runtime and language
interoperability. This means that you choose any .NET language to build apps and services on .NET.
Microsoft actively develops and supports three .NET languages: C#, F#, and Visual Basic (VB).
C# is simple, powerful, type-safe, and object-oriented, while retaining the expressiveness and elegance of C-
style languages. Anyone familiar with C and similar languages finds few problems in adapting to C#. Check
out the C# Guide to learn more about C#.
F# is a cross-platform, functional-first programming language that also supports traditional object-oriented
and imperative programming. Check out the F# Guide to learn more about F#.
Visual Basic is an easy language to learn that you use to build a variety of apps that run on .NET. Among the
.NET languages, the syntax of VB is the closest to ordinary human language, often making it easier for
people new to software development.
There's no analogous keyword to de-allocate memory, as de-allocation happens automatically when the garbage
collector reclaims the memory through its scheduled run.
The garbage collector is one of the services that help ensure memory safety. A program is memory safe if it
accesses only allocated memory. For instance, the runtime ensures that an app doesn't access unallocated memory
beyond the bounds of an array.
In the following example, the runtime throws an InvalidIndexException exception to enforce memory safety:
using System.IO;
Once the using block completes, the .NET runtime automatically calls the stream object's Dispose() method,
which releases the file handle. The runtime also does this if an exception causes control to leave the block.
For more details, see the following topics:
For C#, see the using Statement (C# Reference) topic.
For F#, see Resource Management: The use Keyword.
For VB, see the Using Statement (Visual Basic) topic.
Type safety
An object is an instance of a specific type. The only operations allowed for a given object are those of its type. A
Dog type may have Jump and WagTail methods but not a SumTotal method. A program only calls the methods
belonging to a given type. All other calls result in either a compile-time error or a run-time exception (in case of
using dynamic features or object ).
.NET languages are object-oriented with hierarchies of base and derived classes. The .NET runtime only allows
object casts and calls that align with the object hierarchy. Remember that every type defined in any .NET language
derives from the base Object type.
Type safety is also used to help enforce encapsulation by guaranteeing the fidelity of the accessor keywords.
Accessor keywords are artifacts which control access to members of a given type by other code. These are usually
used for various kinds of data within a type that are used to manage its behavior.
private Dog _nextDogToBeAdopted = AnimalShelter.AdoptDog()
C#, VB, and F# support local type inference. Type inference means that the compiler deduces the type of the
expression on the left-hand side from the expression on the right-hand side. This doesn't mean that the type safety
is broken or avoided. The resulting type does have a strong type with everything that implies. From the previous
example, dog and cat are rewritten to introduce type inference, and the remainder of the example is unchanged:
F# has even further type inference capabilities than the method-local type inference found in C# and VB. To learn
more, see Type Inference.
Generics
Generics allow the programmer to introduce a type parameter when designing their classes that allows the client
code (the users of the type) to specify the exact type to use in place of the type parameter.
Generics were added to help programmers implement generic data structures. Before their arrival in order for a
type such as the List type to be generic, it would have to work with elements that were of type object . This had
various performance and semantic problems, along with possible subtle runtime errors. The most notorious of the
latter is when a data structure contains, for instance, both integers and strings, and an InvalidCastException is
thrown on working with the list's members.
The following sample shows a basic program running using an instance of List<T> types:
using System;
using System.Collections.Generic;
namespace GenericsSampleShort
{
public static void Main(string[] args)
{
// List<string> is the client way of specifying the actual type for the type parameter T
List<string> listOfStrings = new List<string> { "First", "Second", "Third" };
For more information, see the Generic types (Generics) overview topic.
Async programming
Async programming is a first-class concept within .NET with async support in the runtime, framework libraries, and
.NET language constructs. Internally, they're based on objects (such as Task ), which take advantage of the
operating system to perform I/O-bound jobs as efficiently as possible.
To learn more about async programming in .NET, start with the Async overview topic.
Native interoperability
Every operating system includes an application programming interface (API) that provides system services. .NET
provides several ways to call those APIs.
The main way to do native interoperability is via "platform invoke" or P/Invoke for short, which is supported across
Linux and Windows platforms. A Windows-only way of doing native interoperability is known as "COM interop,"
which is used to work with COM components in managed code. It's built on top of the P/Invoke infrastructure, but
it works in subtly different ways.
Most of Mono's (and thus Xamarin's) interoperability support for Java and Objective-C are built similarly, that is,
they use the same principles.
Read more about it native interoperability in the Native interoperability topic.
Unsafe code
Depending on language support, the CLR lets you access native memory and do pointer arithmetic via unsafe
code. These operations are needed for certain algorithms and system interoperability. Although powerful, use of
unsafe code is discouraged unless it's necessary to interop with system APIs or implement the most efficient
algorithm. Unsafe code may not execute the same way in different environments and also loses the benefits of a
garbage collector and type safety. It's recommended to confine and centralize unsafe code as much as possible and
test that code thoroughly.
The following example is a modified version of the ToString() method from the StringBuilder class. It illustrates
how using unsafe code can efficiently implement an algorithm by moving around chunks of memory directly:
Next steps
If you're interested in a tour of C# features, check out Tour of C#.
If you're interested in a tour of F# features, see Tour of F#.
If you want to get started with writing code of your own, visit Getting Started.
To learn about important components of .NET, check out .NET Architectural Components.
7/29/2017 • 5 min to read • Edit Online
Editors:
Mike Pope
Steve Hoag
Introduction
Enterprises are increasingly realizing cost savings, solving deployment problems, and improving DevOps and
production operations by using containers. Microsoft has been releasing container innovations for Windows and
Linux by creating products like Azure Container Service and Azure Service Fabric, and by partnering with industry
leaders like Docker, Mesosphere, and Kubernetes. These products deliver container solutions that help companies
build and deploy applications at cloud speed and scale, whatever their choice of platform or tools.
Docker is becoming the de facto standard in the container industry, supported by the most significant vendors in
the Windows and Linux ecosystems. (Microsoft is one of the main cloud vendors supporting Docker.) In the future,
Docker will probably be ubiquitous in any datacenter in the cloud or on-premises.
In addition, the microservices architecture is emerging as an important approach for distributed mission-critical
applications. In a microservice-based architecture, the application is built on a collection of services that can be
developed, tested, deployed, and versioned independently.
NEXT
.NET architectural components
8/24/2017 • 4 min to read • Edit Online
A .NET app is developed for and runs in one or more implementations of .NET. Implementations of .NET include
the .NET Framework, .NET Core, and Mono. There is an API specification common to all implementations of .NET
that's called the .NET Standard. This article gives a brief introduction to each of these concepts.
.NET Standard
The .NET Standard is a set of APIs that are implemented by the Base Class Library of a .NET implementation. More
formally, it's a specification of .NET APIs that make up a uniform set of contracts that you compile your code
against. These contracts are implemented in each .NET implementation. This enables portability across different
.NET implementations, effectively allowing your code to run everywhere.
The .NET Standard is also a target framework. If your code targets a version of the .NET Standard, it can run on any
.NET implementation which supports that version of the .NET Standard.
To learn more about the .NET Standard and how to target it, see the .NET Standard topic.
.NET implementations
Each implementation of .NET includes the following components:
One or more runtimes. Examples: CLR for .NET Framework, CoreCLR and CoreRT for .NET Core.
A class library that implements the .NET Standard and may implement additional APIs. Examples: .NET
Framework Base Class Library, .NET Core Base Class Library.
Optionally, one or more application frameworks. Examples: ASP.NET, Windows Forms, and Windows
Presentation Foundation (WPF) are included in the .NET Framework.
Optionally, development tools. Some development tools are shared among multiple implementations.
There are four primary .NET implementations that Microsoft actively develops and maintains: .NET Core, .NET
Framework, Mono, and UWP.
.NET Core
.NET Core is a cross-platform implementation of .NET and designed to handle server and cloud workloads at scale.
It runs on Windows, macOS and Linux. It implements the .NET Standard, so code that targets the .NET Standard
can run on .NET Core. ASP.NET Core runs on .NET Core.
To learn more about .NET Core, see the .NET Core Guide and Choosing between .NET Core and .NET Framework
for server apps.
.NET Framework
The.NET Framework is the original .NET implementation that has existed since 2002. It's the same .NET Framework
that existing .NET developers have always used. Versions 4.5 and later implement the .NET Standard, so code that
targets the .NET Standard can run on those versions of the .NET Framework. It contains additional Windows-
specific APIs, such as APIs for Windows desktop development with Windows Forms and WPF. The .NET
Framework is optimized for building Windows desktop applications.
To learn more about the .NET Framework, see the .NET Framework Guide.
Mono
Mono is a .NET implementation that is mainly used when a small runtime is required. It is the runtime that powers
Xamarin applications on Android, Mac, iOS, tvOS and watchOS and is focused primarily on a small footprint.
It supports all of the currently published .NET Standard versions.
Historically, Mono implemented the larger API of the .NET Framework and emulated some of the most popular
capabilities on Unix. It is sometimes used to run .NET applications that rely on those capabilities on Unix.
Mono is typically used with a just-in-time compiler, but it also features a full static compiler (ahead-of-time
compilation) that is used on platforms like iOS.
To learn more about Mono, see the Mono documentation.
Universal Windows Platform (UWP)
UWP is an implementation of .NET that is used for building modern, touch-enabled Windows applications and
software for the Internet of Things (IoT). It's designed to unify the different types of devices that you may want to
target, including PCs, tablets, phablets, phones, and even the Xbox. UWP provides many services, such as a
centralized app store, an execution environment (AppContainer), and a set of Windows APIs to use instead of
Win32 (WinRT). Apps can be written in C++, C#, VB.NET, and JavaScript. When using C# and VB.NET, the .NET APIs
are provided by .NET Core.
To learn more about UWP, see Intro to the Universal Windows Platform.
.NET runtimes
A runtime is the execution environment for a managed program. The OS is part of the runtime environment but is
not part of the .NET runtime. Here are some examples of .NET runtimes:
Common Language Runtime (CLR) for the .NET Framework
Core Common Language Runtime (CoreCLR) for .NET Core
.NET Native for Universal Windows Platform
The Mono runtime for Xamarin.iOS, Xamarin.Android, Xamarin.Mac, and the Mono desktop framework
See also
Choosing between .NET Core and .NET Framework for server apps
.NET Standard
.NET Core Guide
.NET Framework Guide
C# Guide
F# Guide
VB.NET Guide
.NET Standard
8/15/2017 • 7 min to read • Edit Online
The .NET Standard is a formal specification of .NET APIs that are intended to be available on all .NET
implementations. The motivation behind the .NET Standard is establishing greater uniformity in the .NET
ecosystem. ECMA 335 continues to establish uniformity for .NET implementation behavior, but there is no
similar spec for the .NET Base Class Libraries (BCL) for .NET library implementations.
The .NET Standard enables the following key scenarios:
Defines uniform set of BCL APIs for all .NET implementations to implement, independent of workload.
Enables developers to produce portable libraries that are usable across .NET implementations, using this
same set of APIs.
Reduces or even eliminates conditional compilation of shared source due to .NET APIs, only for OS APIs.
The various .NET implementations target specific versions of .NET Standard. Each .NET implementation version
advertises the highest .NET Standard version it supports, a statement that means it also supports previous
versions. For example, the .NET Framework 4.6 implements .NET Standard 1.3, which means that it exposes all
APIs defined in .NET Standard versions 1.0 through 1.3. Similarly, the .NET Framework 4.6.1 implements .NET
Standard 1.4, while .NET Core 1.0 implements .NET Standard 1.6.
.NET
STANDAR
D 1.0 1.1 1.2 1.3 1.4 1.5 1.6 2.0
.NET Core 1.0 1.0 1.0 1.0 1.0 1.0 1.0 2.0
Windows 8.0
Phone
Silverlight
The columns represent .NET Standard versions. Each header cell is a link to a document that shows which
APIs got added in that version of .NET Standard.
The rows represent the different .NET implementations.
The version number in each cell indicates the minimum version of the implementation you'll need in order to
target that .NET Standard version.
To find the highest version of .NET Standard that you can target, do the following:
1. Find the row that indicate the .NET implementation you want to run on.
2. Find the column in that row that indicates your version starting from right to left.
3. The column header indicates the .NET Standard version that your target supports (and any lower .NET
Standard versions will also support it).
4. Repeat this process for each platform you want to target. If you have more than one target platform, you
should pick the smaller version among them. For example, if you want to run on .NET Framework 4.5 and
.NET Core 1.0, the highest .NET Standard version you can use is .NET Standard 1.1.
Which .NET Standard version to target
When choosing a .NET Standard version, you should consider this trade-off:
The higher the version, the more APIs are available to you.
The lower the version, the more platforms implement it.
In general, we recommend you to target the lowest version of .NET Standard possible. So, after you find the
highest .NET Standard version you can target, follow these steps:
1. Target the next lower version of .NET Standard and build your project.
2. If your project builds successfully, repeat step 1. Otherwise, retarget to the next higher version and that's the
version you should use.
.NET Standard versioning rules
There are two primary versioning rules:
Additive: .NET Standard versions are logically concentric circles: higher versions incorporate all APIs from
previous versions. There are no breaking changes between versions.
Immutable. Once shipped, .NET Standard versions are frozen. New APIs will first become available in specific
.NET implementations, such as .NET Core. If the .NET Standard review board believes the new APIs should be
made available everywhere, they'll be added in a new .NET Standard version.
Specification
The .NET Standard specification is a standardized set of APIs. The specification is maintained by .NET
implementors, specifically Microsoft (includes .NET Framework, .NET Core and Mono) and Unity. A public
feedback process is used as part of establishing new .NET Standard versions through GitHub.
Official artifacts
The official specification is a set of .cs files that define the APIs that are part of the standard. The ref directory in
the dotnet/standard repository defines the .NET Standard APIs.
The NETStandard.Library metapackage (source) describes the set of libraries that define (in part) one or more
.NET Standard versions.
A given component, like System.Runtime, describes:
Part of .NET Standard (just its scope).
Multiple versions of .NET Standard, for that scope.
Derivative artifacts are provided to enable more convenient reading and to enable certain developer scenarios
(for example, using a compiler).
API list in markdown
Reference assemblies, distributed as NuGet packages and referenced by the NETStandard.Library
metapackage.
Package representation
The primary distribution vehicle for the .NET Standard reference assemblies is NuGet packages.
Implementations will be delivered in a variety of ways, appropriate for each .NET implementation.
NuGet packages target one or more frameworks. The .NET Standard packages target the ".NET Standard"
framework. You can target the .NET Standard Framework using the netstandard compact TFM (for example,
netstandard1.4 ). Libraries that are intended to run on multiple runtimes should target this framework.
The NETStandard.Library metapackage references the complete set of NuGet packages that define .NET
Standard. The most common way to target netstandard is by referencing this metapackage. It describes and
provides access to the ~40 .NET libraries and associated APIs that define .NET Standard. You can reference
additional packages that target netstandard to get access to additional APIs.
Versioning
The specification is not singular, but an incrementally growing and linearly versioned set of APIs. The first
version of the standard establishes a baseline set of APIs. Subsequent versions add APIs and inherit APIs defined
by previous versions. There is no established provision for removing APIs from the standard.
.NET Standard is not specific to any one .NET implementation, nor does it match the versioning scheme of any of
those runtimes.
APIs added to any of the implementations (such as, .NET Framework, .NET Core and Mono) can be considered as
candidates to add to the specification, particularly if they are thought to be fundamental in nature. New versions
of .NET Standard are created based on .NET implementation releases, enabling you to target new APIs from a
.NET Standard PCL. The versioning mechanics are described in more detail in .NET Core Versioning.
.NET Standard versioning is important for usage. Given a .NET Standard version, you can use libraries that target
that same or lower version. The following approach describes the workflow for using .NET Standard PCLs,
specific to .NET Standard targeting.
Select a .NET Standard version to use for your PCL.
Use libraries that depend on the same .NET Standard version or lower.
If you find a library that depends on a higher .NET Standard version, you either need to adopt that same
version or decide not to use that library.
PCL compatibility
.NET Standard is compatible with a subset of PCL profiles. .NET Standard 1.0, 1.1 and 1.2 each overlap with a set
of PCL profiles. This overlap was created for two reasons:
Enable .NET Standard-based PCLs to reference profile-based PCLs.
Enable profile-based PCLs to be packaged as .NET Standard-based PCLs.
Profile-based PCL compatibility is provided by the Microsoft.NETCore.Portable.Compatibility NuGet package.
This dependency is required when referencing NuGet packages that contain profile-based PCLs.
Profile-based PCLs packaged as netstandard are easier to consume than typically packaged profile-based PCLs.
netstandard packaging is compatible with existing users.
You can see the set of PCL profiles that are compatible with the .NET Standard:
See also
.NET Standard Versions
Target frameworks
8/26/2017 • 4 min to read • Edit Online
When you target a framework in an app or library, you're specifying the set of APIs that you'd like to make
available to the app or library. You specify the target framework in your project file using Target Framework
Monikers (TFMs).
An app or library can target a version of .NET Standard. .NET Standard versions represent standardized sets of
APIs across all .NET implementations. For example, a library can target .NET Standard 1.6 and gain access to
APIs that function across .NET Core and .NET Framework using the same codebase.
An app or library can also target a specific .NET implementation to gain access to implementation-specific APIs.
For example, an app that targets Xamarin.iOS (for example, Xamarin.iOS10 ) gets access to Xamarin-provided
iOS API wrappers for iOS 10, or an app that targets the Universal Windows Platform (UWP, uap10.0 ) has
access to APIs that compile for devices that run Windows 10.
For some target frameworks (for example, the .NET Framework), the APIs are defined by the assemblies that the
framework installs on a system and may include application framework APIs (for example, ASP.NET).
For package-based target frameworks (for example, .NET Standard and .NET Core), the APIs are defined by the
packages included in the app or library. A metapackage is a NuGet package that has no content of its own but
is a list of dependencies (other packages). A NuGet package-based target framework implicitly specifies a
metapackage that references all the packages that together make up the framework.
Silverlight sl4
sl5
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp2.0</TargetFramework>
</PropertyGroup>
</Project>
When you specify multiple target frameworks, you may conditionally reference assemblies for each target
framework. In your code, you can conditionally compile against those assemblies by using preprocessor
symbols with if-then-else logic.
The following library project file targets APIs of .NET Standard ( netstandard1.4 ) and APIs of the .NET
Framework ( net40 and net45 ). Use the plural TargetFrameworks element with multiple target frameworks.
Note how the Condition attributes include implementation-specific packages when the library is compiled for
the two .NET Framework TFMs:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>netstandard1.4;net40;net45</TargetFrameworks>
</PropertyGroup>
<!-- Conditionally obtain references for the .NET Framework 4.0 target -->
<ItemGroup Condition=" '$(TargetFramework)' == 'net40' ">
<Reference Include="System.Net" />
</ItemGroup>
<!-- Conditionally obtain references for the .NET Framework 4.5 target -->
<ItemGroup Condition=" '$(TargetFramework)' == 'net45' ">
<Reference Include="System.Net.Http" />
<Reference Include="System.Threading.Tasks" />
</ItemGroup>
</Project>
Within your library or app, you write conditional code to compile for each target framework:
The build system is aware of preprocessor symbols representing the target frameworks shown in the
Supported target framework versions table. When using a symbol that represents a .NET Standard or .NET Core
TFM, replace the dot with an underscore and change lowercase letters to uppercase (for example, the symbol
for netstandard1.4 is NETSTANDARD1_4 ).
The complete list of preprocessor symbols for .NET Core target frameworks is:
TARGET FRAMEWORKS SYMBOLS
aspnet50 netcoreapp
aspnetcore50
dnxcore50
dnx
dnx45
dnx451
dnx452
dotnet netstandard
dotnet50
dotnet51
dotnet52
dotnet53
dotnet54
dotnet55
dotnet56
netcore50 uap10.0
win netcore45
win8 netcore45
win81 netcore451
win10 uap10.0
winrt netcore45
See also
Packages, Metapackages and Frameworks
Developing Libraries with Cross Platform Tools
.NET Standard
.NET Core Versioning
dotnet/standard GitHub repository
NuGet Tools GitHub Repository
Framework Profiles in .NET
.NET Glossary
8/14/2017 • 10 min to read • Edit Online
The primary goal of this glossary is to clarify meanings of selected terms and acronyms that appear frequently in
the .NET documentation without definitions.
AOT
Ahead-of-time compiler.
Similar to JIT, this compiler also translates IL to machine code. In contrast to JIT compilation, AOT compilation
happens before the application is executed and is usually performed on a different machine. Because AOT tool
chains don't compile at runtime, they don't have to minimize time spent compiling. That means they can spend
more time optimizing. Since the context of AOT is the entire application, the AOT compiler also performs cross-
module linking and whole-program analysis, which means that all references are followed and a single executable
is produced.
ASP.NET
The original ASP.NET implementation that ships with the .NET Framework.
Sometimes ASP.NET is an umbrella term that refers to both ASP.NET implementations including ASP.NET Core. The
meaning that the term carries in any given instance is determined by context.
See ASP.NET.
ASP.NET Core
A cross-platform, high-performance, open source implementation of ASP.NET built on .NET Core.
See ASP.NET Core.
assembly
A .dll file that contains a collection of APIs that can be called by apps or other assemblies.
A .NET assembly is a collection of types. An assembly includes interfaces, classes, structures, enumerations, and
delegates. Assemblies in a project's bin folder are sometimes referred to as binaries. See also library.
CLR
Common Language Runtime.
The exact meaning depends on the context, but this usually refers to the runtime of the .NET Framework. The CLR
handles memory allocation and management. The CLR is also a virtual machine that not only executes apps but
also generates and compiles code on-the-fly using a JIT compiler. The current Microsoft CLR implementation is
Windows only.
CoreCLR
.NET Core Common Language Runtime.
This CLR is built from the same code base as the CLR. Originally, CoreCLR was the runtime of Silverlight and was
designed to run on multiple platforms, specifically Windows and OS X. CoreCLR is now part of .NET Core and
represents a simplified version of the CLR. It's still a cross platform runtime, now including support for many Linux
distributions. CoreCLR is also a virtual machine with JIT and code execution capabilities.
CoreFX
.NET Core Base Class Library (BCL)
A set of libraries that comprise the System.* (and to a limited extent Microsoft.*) namespaces. The BCL is a general
purpose, lower-level framework that higher-level application frameworks, such as ASP.NET Core, build on. The
source code of the .NET Core BCL is contained in the CoreFX repository. However, the majority of the .NET Core
APIs are also available in the .NET Framework, so you can think of CoreFX as a fork of the .NET Framework BCL.
CoreRT
.NET Core runtime.
In contrast to the CLR/CoreCLR, CoreRT is not a virtual machine, which means it doesn't include the facilities to
generate and run code on-the-fly because it doesn't include a JIT. It does, however, include the GC and the ability
for runtime type identification (RTTI) and reflection. However, its type system is designed so that metadata for
reflection isn't required. This enables having an AOT tool chain that can link away superfluous metadata and (more
importantly) identify code that the app doesn't use. CoreRT is in development.
See Intro to .NET Native and CoreRT
ecosystem
All of the runtime software, development tools, and community resources that are used to build and run
applications for a given technology.
The term ".NET ecosystem" differs from similar terms such as ".NET stack" in its inclusion of third-party apps and
libraries. Here's an example in a sentence:
"The motivation behind the .NET Standard is to establish greater uniformity in the .NET ecosystem."
framework
In general, a comprehensive collection of APIs that facilitates development and deployment of applications that are
based on a particular technology. In this general sense, ASP.NET Core and Windows Forms are examples of
application frameworks. See also library.
The word "framework" has a more specific technical meaning in the following terms:
.NET Framework
target framework
TFM (target framework moniker)
In the existing documentation, "framework" sometimes refers to an implementation of .NET. For example, an article
may call .NET Core a framework. We plan to eliminate this confusing usage from the documentation.
GC
Garbage collector.
The garbage collector is an implementation of automatic memory management. The GC frees memory occupied by
objects that are no longer in use.
See Garbage Collection.
IL
Intermediate language.
Higher-level .NET languages, such as C#, compile down to a hardware-agnostic instruction set, which is called
Intermediate Language (IL). IL is sometimes referred to as MSIL (Microsoft IL) or CIL (Common IL).
JIT
Just-in-time compiler.
Similar to AOT, this compiler translates IL to machine code that the processor understands. Unlike AOT, JIT
compilation happens on demand and is performed on the same machine that the code needs to run on. Since JIT
compilation occurs during execution of the application, compile time is part of the run time. Thus, JIT compilers
have to balance time spent optimizing code against the savings that the resulting code can produce. But a JIT knows
the actual hardware and can free developers from having to ship different implementations.
implementation of .NET
An implementation of .NET includes the following:
One or more runtimes. Examples: CLR, CoreCLR, CoreRT.
A class library that implements a version of the .NET Standard and may include additional APIs. Examples: .NET
Framework Base Class Library, .NET Core Base Class Library.
Optionally, one or more application frameworks. Examples: ASP.NET, Windows Forms, and WPF are included in
the .NET Framework.
Optionally, development tools. Some development tools are shared among multiple implementations.
Examples of .NET implementations:
.NET Framework
.NET Core
Universal Windows Platform (UWP)
library
A collection of APIs that can be called by apps or other libraries. A .NET library is composed of one or more
assemblies.
The words library and framework are often used synonymously.
metapackage
A NuGet package that has no library of its own but is only a list of dependencies. The included packages can
optionally establish the API for a target framework.
See Packages, Metapackages and Frameworks
Mono
An open source alternative to the .NET Framework.
Mono started around the same time the .NET Framework was first released. Since the .NET Framework wasn't open
source, Mono was forced to start from scratch and is thus a complete re-implementation of the .NET Framework
with no shared code.
When .NET Core was released under the MIT license, Microsoft also released large chunks of the .NET Framework
under the MIT license as well. This enabled the Mono community to use the same code the .NET Framework uses in
order to close gaps and avoid behavioral differences.
Mono is primarily used to run .NET applications on Linux and macOS. There are ports of Mono to other platforms;
see Mono's Supported Platforms. Mono has implementations (though not necessarily complete) of WinForms,
ASP.NET, and System.Drawing .
.NET
The umbrella term for .NET Standard and all .NET implementations and workloads. Always capitalized, never ".Net".
See the .NET Guide
.NET Core
A cross-platform, high-performance, open source implementation of .NET. Includes the Core Common Language
Runtime (CoreCLR), the Core AOT Runtime (CoreRT, in development), the Core Base Class Library, and the Core
SDK.
See .NET Core.
.NET Framework
An implementation of .NET that runs only on Windows. Includes the Common Language Runtime (CLR), the Base
Class Library, and application framework libraries such as ASP.NET, Windows Forms, and WPF.
See .NET Framework Guide.
.NET Native
A compiler tool chain that produces native code ahead-of-time (AOT), as opposed to just-in-time (JIT).
Compilation happens on the developer's machine similar to the way a C++ compiler and linker works. It removes
unused code and spends more time optimizing it. It extracts code from libraries and merges them into the
executable. The result is a single module that represents the entire app.
UWP was the first application framework supported by .NET Native. Now, we support building native console apps
for Windows, macOS, and Linux.
See Intro to .NET Native and CoreRT
.NET Standard
A formal specification of .NET APIs that are available in each .NET implementation.
The .NET Standard specification is sometimes called a library in the documentation. Because a library includes API
implementations, not only specifications (interfaces), it's misleading to call .NET Standard a "library." We plan to
eliminate that usage from the documentation, except in reference to the name of the .NET Standard metapackage (
NETStandard.Library ).
NGEN
Native (image) generation.
You can think of this technology as a persistent JIT compiler. It usually compiles code on the machine where the
code is executed, but compilation typically occurs at install time.
package
A NuGet package — or just a package — is a .zip file with one or more assemblies of the same name along with
additional metadata such as the author name.
The .zip file has a .nupkg extension and may contain assets, such as .dll files and .xml files, for use with multiple
frameworks and versions. When installed in an app or library, the appropriate assets are selected based on the
target framework specified by the app or library. The assets that define the interface are in the ref folder, and the
assets that define the implementation are in the lib folder.
platform
An operating system and the hardware it runs on, such as Windows, macOS, Linux, iOS, and Android.
Here are examples of usage in sentences:
".NET Core is a cross-platform implementation of .NET."
"PCL profiles represent Microsoft platforms, while the .NET Standard is agnostic to platform."
The .NET documentation frequently uses ".NET platform" to mean either an implementation of .NET or the .NET
stack including all implementations. Both of these usages tend to get confused with the primary (OS/hardware)
meaning, so we plan to eliminate these usages from the documentation.
runtime
The execution environment for a managed program.
The OS is part of the runtime environment but is not part of the .NET runtime. Here are some examples of .NET
runtimes:
Common Language Runtime (CLR)
Core Common Language Runtime (CoreCLR)
.NET Native (for UWP)
Mono runtime
The .NET documentation sometimes uses "runtime" to mean an implementation of .NET. For example, in the
following sentences "runtime" should be replaced with "implementation":
"The various .NET runtimes implement specific versions of .NET Standard."
"Libraries that are intended to run on multiple runtimes should target this framework." (referring to .NET
Standard)
"The various .NET runtimes implement specific versions of .NET Standard. … Each .NET runtime version
advertises the highest .NET Standard version it supports …"
We plan to eliminate this inconsistent usage.
stack
A set of programming technologies that are used together to build and run applications.
"The .NET stack" refers to the .NET Standard and all .NET implementations. The phrase "a .NET stack" may refer to
one implementation of .NET.
target framework
The collection of APIs that a .NET app or library relies on.
An app or library can target a version of .NET Standard (for example, .NET Standard 2.0), which is specification for a
standardized set of APIs across all .NET implementations. An app or library can also target a version of a specific
.NET implementation, in which case it gets access to implementation-specific APIs. For example, an app that targets
Xamarin.iOS gets access to Xamarin-provided iOS API wrappers.
For some target frameworks (for example, the .NET Framework) the available APIs are defined by the assemblies
that a .NET implementation installs on a system, which may include application framework APIs (for example,
ASP.NET, WinForms). For package-based target frameworks (such as .NET Standard and .NET Core), the framework
APIs are defined by the packages installed in the app or library. In that case, the target framework implicitly
specifies a metapackage that references all the packages that together make up the framework.
See Target Frameworks.
TFM
Target framework moniker.
A standardized token format for specifying the target framework of a .NET app or library. Target frameworks are
typically referenced by a short name, such as net462 . Long-form TFMs (such as .NETFramework,Version=4.6.2)
exist but are not generally used to specify a target framework.
See Target Frameworks.
UWP
Universal Windows Platform.
An implementation of .NET that is used for building modern, touch-enabled Windows applications and software for
the Internet of Things (IoT). It's designed to unify the different types of devices that you may want to target,
including PCs, tablets, phablets, phones, and even the Xbox. UWP provides many services, such as a centralized app
store, an execution environment (AppContainer), and a set of Windows APIs to use instead of Win32 (WinRT). Apps
can be written in C++, C#, VB.NET, and JavaScript. When using C# and VB.NET, the .NET APIs are provided by .NET
Core.
See also
.NET Guide
.NET Framework Guide
.NET Core
ASP.NET Overview
ASP.NET Core Overview
Choosing between .NET Core and .NET Framework
for server apps
8/17/2017 • 6 min to read • Edit Online
There are two supported implementations for building server-side applications with .NET: .NET Framework and
.NET Core. Both share many of the same components and you can share code across the two. However, there are
fundamental differences between the two and your choice depends on what you want to accomplish. This article
provides guidance on when to use each.
Use .NET Core for your server application when:
You have cross-platform needs.
You are targeting microservices.
You are using Docker containers.
You need high-performance and scalable systems.
You need side-by-side .NET versions per application.
Use .NET Framework for your server application when:
Your app currently uses .NET Framework (recommendation is to extend instead of migrating).
Your app uses third-party .NET libraries or NuGet packages not available for .NET Core.
Your app uses .NET technologies that aren't available for .NET Core.
Your app uses a platform that doesn’t support .NET Core.
See also
Choose between ASP.NET and ASP.NET Core
.NET Core Guide
Porting from .NET Framework to .NET Core
.NET Framework on Docker Guide
.NET Components Overview
.NET Microservices. Architecture for Containerized .NET Applications
What is "managed code"?
8/5/2017 • 2 min to read • Edit Online
When working with .NET Framework, you will often encounter the term "managed code". This document will
explain what this term means and additional information around it.
To put it very simply, managed code is just that: code whose execution is managed by a runtime. In this case, the
runtime in question is called the Common Language Runtime or CLR, regardless of the implementation (Mono
or .NET Framework or .NET Core). CLR is in charge of taking the managed code, compiling it into machine code and
then executing it. On top of that, runtime provides several important services such as automatic memory
management, security boundaries, type safety etc.
Contrast this to the way you would run a C/C++ program, also called "unmanaged code". In the unmanaged world,
the programmer is in charge of pretty much everything. The actual program is, essentially, a binary that the
operating system (OS) loads into memory and starts. Everything else, from memory management to security
considerations are a burden of the programmer.
Managed code is written in one of the high-level languages that can be run on top of .NET, such as C#, Visual Basic,
F# and others. When you compile code written in those languages with their respective compiler, you don’t get
machine code. You get Intermediate Language code which the runtime then compiles and executes. C++ is the
one exception to this rule, as it can also produce native, unmanaged binaries that run on Windows.
More resources
.NET Framework Conceptual Overview
Unsafe Code and Pointers
Interoperability (C# Programming guide)
Automatic Memory Management
7/29/2017 • 7 min to read • Edit Online
Automatic memory management is one of the services that the Common Language Runtime provides during
Managed Execution. The Common Language Runtime's garbage collector manages the allocation and release of
memory for an application. For developers, this means that you do not have to write code to perform memory
management tasks when you develop managed applications. Automatic memory management can eliminate
common problems, such as forgetting to free an object and causing a memory leak, or attempting to access
memory for an object that has already been freed. This section describes how the garbage collector allocates and
releases memory.
Allocating Memory
When you initialize a new process, the runtime reserves a contiguous region of address space for the process. This
reserved address space is called the managed heap. The managed heap maintains a pointer to the address where
the next object in the heap will be allocated. Initially, this pointer is set to the managed heap's base address. All
reference types are allocated on the managed heap. When an application creates the first reference type, memory is
allocated for the type at the base address of the managed heap. When the application creates the next object, the
garbage collector allocates memory for it in the address space immediately following the first object. As long as
address space is available, the garbage collector continues to allocate space for new objects in this manner.
Allocating memory from the managed heap is faster than unmanaged memory allocation. Because the runtime
allocates memory for an object by adding a value to a pointer, it is almost as fast as allocating memory from the
stack. In addition, because new objects that are allocated consecutively are stored contiguously in the managed
heap, an application can access the objects very quickly.
Releasing Memory
The garbage collector's optimizing engine determines the best time to perform a collection based on the
allocations being made. When the garbage collector performs a collection, it releases the memory for objects that
are no longer being used by the application. It determines which objects are no longer being used by examining the
application's roots. Every application has a set of roots. Each root either refers to an object on the managed heap or
is set to null. An application's roots include static fields, local variables and parameters on a thread's stack, and CPU
registers. The garbage collector has access to the list of active roots that the just-in-time (JIT) compiler and the
runtime maintain. Using this list, it examines an application's roots, and in the process creates a graph that contains
all the objects that are reachable from the roots.
Objects that are not in the graph are unreachable from the application's roots. The garbage collector considers
unreachable objects garbage and will release the memory allocated for them. During a collection, the garbage
collector examines the managed heap, looking for the blocks of address space occupied by unreachable objects. As
it discovers each unreachable object, it uses a memory-copying function to compact the reachable objects in
memory, freeing up the blocks of address spaces allocated to unreachable objects. Once the memory for the
reachable objects has been compacted, the garbage collector makes the necessary pointer corrections so that the
application's roots point to the objects in their new locations. It also positions the managed heap's pointer after the
last reachable object. Note that memory is compacted only if a collection discovers a significant number of
unreachable objects. If all the objects in the managed heap survive a collection, then there is no need for memory
compaction.
To improve performance, the runtime allocates memory for large objects in a separate heap. The garbage collector
automatically releases the memory for large objects. However, to avoid moving large objects in memory, this
memory is not compacted.
See Also
GC
Garbage Collection
Managed Execution Process
Common Language Runtime (CLR)
7/29/2017 • 4 min to read • Edit Online
The .NET Framework provides a run-time environment called the common language runtime, which runs the code
and provides services that make the development process easier.
Compilers and tools expose the common language 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.
NOTE
Compilers and tools are able to produce output that the common language runtime can consume because the type system,
the format of metadata, and the runtime environment (the virtual execution system) are all defined by a public standard, the
ECMA Common Language Infrastructure specification. For more information, see ECMA C# and Common Language
Infrastructure Specifications.
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. Instead, 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. The runtime provides the following benefits:
Performance improvements.
The ability to easily use components developed in other languages.
Extensible types provided by a class library.
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.
Support for custom attributes.
Garbage collection.
Use of delegates instead of function pointers for increased type safety and security. For more information
about delegates, see Common Type System.
1.0 1.0
1.1 1.1
2.0 2.0
3.0 2.0
3.5 2.0
4 4
4.7 4
Related Topics
TITLE DESCRIPTION
Managed Execution Process Describes the steps required to take advantage of the
common language runtime.
Automatic Memory Management Describes how the garbage collector allocates and releases
memory.
TITLE DESCRIPTION
NIB: Overview of the .NET Framework Describes key .NET Framework concepts such as the common
type system, cross-language interoperability, managed
execution, application domains, and assemblies.
Common Type System Describes how types are declared, used, and managed in the
runtime in support of cross-language integration.
See Also
Versions and Dependencies
Language independence and language-independent
components
8/5/2017 • 68 min to read • Edit Online
.NET is language independent. This means that, as a developer, you can develop in one of the many languages that
target .NET implementations, such as C#, F#, and Visual Basic. You can access the types and members of class
libraries developed for .NET implementations without having to know the language in which they were originally
written and without having to follow any of the original language's conventions. If you are a component developer,
your component can be accessed by any .NET app regardless of its language.
NOTE
This first part of this article discusses creating language-independent components - that is, components that can be
consumed by apps that are written in any language. You can also create a single component or app from source code written
in multiple languages; see Cross-Language Interoperability in the second part of this article.
To fully interact with other objects written in any language, objects must expose to callers only those features that
are common to all languages. This common set of features is defined by the Common Language Specification
(CLS), which is a set of rules that apply to generated assemblies. The Common Language Specification is defined in
Partition I, Clauses 7 through 11 of the ECMA-335 Standard: Common Language Infrastructure.
If your component conforms to the Common Language Specification, it is guaranteed to be CLS-compliant and can
be accessed from code in assemblies written in any programming language that supports the CLS. You can
determine whether your component conforms to the Common Language Specification at compile time by applying
the CLSCompliantAttribute attribute to your source code. For more information, see The CLSCompliantAttribute
attribute.
In this article:
CLS compliance rules
Types and type member signatures
Naming conventions
Type conversion
Arrays
Interfaces
Enumerations
Type members in general
Member accessibility
Generic types and members
Constructors
Properties
Events
Overloads
Exceptions
Attributes
CLSCompliantAttribute attribute
Cross-Language Interoperability
NOTE
The Common Language Specification discusses each rule for CLS compliance as it applies to consumers (developers who are
programmatically accessing a component that is CLS-compliant), frameworks (developers who are using a language compiler
to create CLS-compliant libraries), and extenders (developers who are creating a tool such as a language compiler or a code
parser that creates CLS-compliant components). This article focuses on the rules as they apply to frameworks. Note, though,
that some of the rules that apply to extenders may also apply to assemblies that are created using Reflection.Emit.
To design a component that is language independent, you only need to apply the rules for CLS compliance to your
component's public interface. Your private implementation does not have to conform to the specification.
IMPORTANT
The rules for CLS compliance apply only to a component's public interface, not to its private implementation.
For example, unsigned integers other than Byte are not CLS-compliant. Because the Person class in the following
example exposes an Age property of type UInt16, the following code displays a compiler warning.
using System;
[assembly: CLSCompliant(true)]
You can make the Person class CLS-compliant by changing the type of Age property from UInt16 to Int16, which
is a CLS-compliant, 16-bit signed integer. You do not have to change the type of the private personAge field.
using System;
[assembly: CLSCompliant(true)]
<Assembly: CLSCompliant(True)>
Types Types and type member Boxed value types are not 3
signatures CLS-compliant.
[assembly: CLSCompliant(true)]
[CLSCompliant(false)]
public class Counter
{
UInt32 ctr;
public Counter()
{
ctr = 0;
}
<CLSCompliant(False)> _
Public Class Counter
Dim ctr As UInt32
All types that appear in member signatures, including a method's return type or a property type, must be CLS-
compliant. In addition, for generic types:
All types that compose an instantiated generic type must be CLS-compliant.
All types used as constraints on generic parameters must be CLS-compliant.
The .NET common type system includes a number of built-in types that are supported directly by the common
language runtime and are specially encoded in an assembly's metadata. Of these intrinsic types, the types listed in
the following table are CLS-compliant.
The intrinsic types listed in the following table are not CLS-Compliant.
The .NET Framework Class Library or any other class library may include other types that aren't CLS-compliant; for
example:
Boxed value types. The following C# example creates a class that has a public property of type int * named
Value . Because an int * is a boxed value type, the compiler flags it as non-CLS-compliant.
using System;
[assembly:CLSCompliant(true)]
Typed references, which are special constructs that contain a reference to an object and a reference to a type.
If a type is not CLS-compliant, you should apply the CLSCompliantAttribute attribute with an isCompliant
parameter with a value of false to it. For more information, see the CLSCompliantAttribute attribute section.
The following example illustrates the problem of CLS compliance in a method signature and in generic type
instantiation. It defines an InvoiceItem class with a property of type UInt32, a property of type Nullable(Of UInt32),
and a constructor with parameters of type UInt32 and Nullable(Of UInt32) . You get four compiler warnings when
you try to compile this example.
using System;
[assembly: CLSCompliant(true)]
To eliminate the compiler warnings, replace the non-CLS-compliant types in the InvoiceItem public interface with
compliant types:
using System;
[assembly: CLSCompliant(true)]
qty = quantity;
}
In addition to the specific types listed, some categories of types are not CLS compliant. These include unmanaged
pointer types and function pointer types. The following example generates a compiler warning because it uses a
pointer to an integer to create an array of integers.
using System;
[assembly: CLSCompliant(true)]
[assembly: CLSCompliant(true)]
For CLS-compliant abstract classes (that is, classes marked as abstract in C#), all members of the class must also
be CLS-compliant.
Naming conventions
Because some programming languages are case-insensitive, identifiers (such as the names of namespaces, types,
and members) must differ by more than case. Two identifiers are considered equivalent if their lowercase
mappings are the same. The following C# example defines two public classes, Person and person . Because they
differ only by case, the C# compiler flags them as not CLS-compliant.
using System;
[assembly: CLSCompliant(true)]
}
// Compilation produces a compiler warning like the following:
// Naming1.cs(11,14): warning CS3005: Identifier 'person' differing
// only in case is not CLS-compliant
// Naming1.cs(6,14): (Location of symbol related to previous warning)
Programming language identifiers, such as the names of namespaces, types, and members, must conform to the
Unicode Standard 3.0, Technical Report 15, Annex 7. This means that:
The first character of an identifier can be any Unicode uppercase letter, lowercase letter, title case letter,
modifier letter, other letter, or letter number. For information on Unicode character categories, see the
System.Globalization.UnicodeCategory enumeration.
Subsequent characters can be from any of the categories as the first character, and can also include non-
spacing marks, spacing combining marks, decimal numbers, connector punctuations, and formatting codes.
Before you compare identifiers, you should filter out formatting codes and convert the identifiers to Unicode
Normalization Form C, because a single character can be represented by multiple UTF-16-encoded code units.
Character sequences that produce the same code units in Unicode Normalization Form C are not CLS-compliant.
The following example defines a property named Å , which consists of the character ANGSTROM SIGN (U+212B),
and a second property named Å which consists of the character LATIN CAPITAL LETTER A WITH RING ABOVE
(U+00C5). The C# compiler flags the source code as non-CLS-compliant.
public double Å
{
get { return a1; }
set { a1 = value; }
}
public double Å
{
get { return a2; }
set { a2 = value; }
}
}
// Compilation produces a compiler warning like the following:
// Naming2a.cs(16,18): warning CS3005: Identifier 'Size.Å' differing only in case is not
// CLS-compliant
// Naming2a.cs(10,18): (Location of symbol related to previous warning)
// Naming2a.cs(18,8): warning CS3005: Identifier 'Size.Å.get' differing only in case is not
// CLS-compliant
// Naming2a.cs(12,8): (Location of symbol related to previous warning)
// Naming2a.cs(19,8): warning CS3005: Identifier 'Size.Å.set' differing only in case is not
// CLS-compliant
// Naming2a.cs(13,8): (Location of symbol related to previous warning)
<Assembly: CLSCompliant(True)>
Public Class Size
Private a1 As Double
Private a2 As Double
Member names within a particular scope (such as the namespaces within an assembly, the types within a
namespace, or the members within a type) must be unique except for names that are resolved through
overloading. This requirement is more stringent than that of the common type system, which allows multiple
members within a scope to have identical names as long as they are different kinds of members (for example, one
is a method and one is a field). In particular, for type members:
Fields and nested types are distinguished by name alone.
Methods, properties, and events that have the same name must differ by more than just return type.
The following example illustrates the requirement that member names must be unique within their scope. It defines
a class named Converter that includes four members named Conversion . Three are methods, and one is a
property. The method that includes an Int64 parameter is uniquely named, but the two methods with an Int32
parameter are not, because return value is not considered a part of a member's signature. The Conversion property
also violates this requirement, because properties cannot have the same name as overloaded methods.
using System;
[assembly: CLSCompliant(true)]
Individual languages include unique keywords, so languages that target the common language runtime must also
provide some mechanism for referencing identifiers (such as type names) that coincide with keywords. For
example, case is a keyword in both C# and Visual Basic. However, the following Visual Basic example is able to
disambiguate a class named case from the case keyword by using opening and closing braces. Otherwise, the
example would produce the error message, "Keyword is not valid as an identifier," and fail to compile.
The following C# example is able to instantiate the case class by using the @ symbol to disambiguate the
identifier from the language keyword. Without it, the C# compiler would display two error messages, "Type
expected" and "Invalid expression term 'case'."
using System;
Type conversion
The Common Language Specification defines two conversion operators:
op_Implicit, which is used for widening conversions that do not result in loss of data or precision. For
example, the Decimal structure includes an overloaded op_Implicit operator to convert values of integral
types and Char values to Decimal values.
op_Explicit , which is used for narrowing conversions that can result in loss of magnitude (a value is
converted to a value that has a smaller range) or precision. For example, the Decimal structure includes an
overloaded op_Explicit operator to convert Double and Single values to Decimal and to convert Decimal
values to integral values, Double , Single , and Char .
However, not all languages support operator overloading or the definition of custom operators. If you choose to
implement these conversion operators, you should also provide an alternate way to perform the conversion. We
recommend that you provide From Xxx and To Xxx methods.
The following example defines CLS-compliant implicit and explicit conversions. It creates a UDouble class that
represents an signed double-precision, floating-point number. It provides for implicit conversions from UDouble to
Double and for explicit conversions from UDouble to Single , Double to UDouble , and Single to UDouble . It also
defines a ToDouble method as an alternative to the implicit conversion operator and the ToSingle , FromDouble ,
and FromSingle methods as alternatives to the explicit conversion operators.
using System;
number = value;
}
number = value;
}
Arrays
CLS-compliant arrays conform to the following rules:
All dimensions of an array must have a lower bound of zero. The following example creates a non-CLS-
compliant array with a lower bound of one. Note that, despite the presence of the CLSCompliantAttribute
attribute, the compiler does not detect that the array returned by the Numbers.GetTenPrimes method is not
CLS-compliant.
[assembly: CLSCompliant(true)]
return arr;
}
}
<Assembly: CLSCompliant(True)>
All array elements must consist of CLS-compliant types. The following example defines two methods that
return non-CLS-compliant arrays. The first returns an array of UInt32 values. The second returns an Object
array that includes Int32 and UInt32 values. Although the compiler identifies the first array as non-
compliant because of its UInt32 type, it fails to recognize that the second array includes non-CLS-compliant
elements.
using System;
[assembly: CLSCompliant(true)]
<Assembly: CLSCompliant(True)>
Overload resolution for methods that have array parameters is based on the fact that they are arrays and on
their element type. For this reason, the following definition of an overloaded GetSquares method is CLS-
compliant.
using System;
using System.Numerics;
[assembly: CLSCompliant(true)]
}
return numbersOut;
}
return numbersOut;
}
}
Imports System.Numerics
<Assembly: CLSCompliant(True)>
Interfaces
CLS-compliant interfaces can define properties, events, and virtual methods (methods with no implementation). A
CLS-compliant interface cannot have any of the following:
Static methods or static fields. The C# compiler generatse compiler errors if you define a static member in an
interface.
Fields. The C# acompiler generates compiler errors if you define a field in an interface.
Methods that are not CLS-compliant. For example, the following interface definition includes a method,
INumber.GetUnsigned , that is marked as non-CLS-compliant. This example generates a compiler warning.
using System;
[assembly:CLSCompliant(true)]
<Assembly: CLSCompliant(True)>
Because of this rule, CLS-compliant types are not required to implement non-CLS-compliant members. If a
CLS-compliant framework does expose a class that implements a non-CLS compliant interface, it should also
provide concrete implementations of all non-CLS-compliant members.
CLS-compliant language compilers must also allow a class to provide separate implementations of members that
have the same name and signature in multiple interfaces. C# supports explicit interface implementations to provide
different implementations of identically named methods. The following example illustrates this scenario by defining
a Temperature class that implements the ICelsius and IFahrenheit interfaces as explicit interface
implementations.
using System;
[assembly: CLSCompliant(true)]
decimal IFahrenheit.GetTemperature()
{
return _value * 9 / 5 + 32;
}
decimal ICelsius.GetTemperature()
{
return _value;
}
}
public class Example
{
public static void Main()
{
Temperature temp = new Temperature(100.0m);
ICelsius cTemp = temp;
IFahrenheit fTemp = temp;
Console.WriteLine("Temperature in Celsius: {0} degrees",
cTemp.GetTemperature());
Console.WriteLine("Temperature in Fahrenheit: {0} degrees",
fTemp.GetTemperature());
}
}
// The example displays the following output:
// Temperature in Celsius: 100.0 degrees
// Temperature in Fahrenheit: 212.0 degrees
Assembly: CLSCompliant(True)>
Module Example
Public Sub Main()
Dim temp As New Temperature(100.0d)
Console.WriteLine("Temperature in Celsius: {0} degrees",
temp.GetCelsius())
Console.WriteLine("Temperature in Fahrenheit: {0} degrees",
temp.GetFahrenheit())
End Sub
End Module
' The example displays the following output:
' Temperature in Celsius: 100.0 degrees
' Temperature in Fahrenheit: 212.0 degrees
Enumerations
CLS-compliant enumerations must follow these rules:
The underlying type of the enumeration must be an intrinsic CLS-compliant integer (Byte, Int16, Int32, or
Int64). For example, the following code tries to define an enumeration whose underlying type is UInt32 and
generates a compiler warning.
using System;
[assembly: CLSCompliant(true)]
<Assembly: CLSCompliant(True)>
An enumeration type must have a single instance field named Value__ that is marked with the
FieldAttributes.RTSpecialName attribute. This enables you to reference the field value implicitly.
An enumeration includes literal static fields whose types match the type of the enumeration itself. For
example, if you define a State enumeration with values of State.On and State.Off , State.On and
State.Off are both literal static fields whose type is State .
[assembly: CLSCompliant(true)]
Types in the signature of a member must be accessible whenever that member is accessible. For example, this
means that a public member cannot include a parameter whose type is private, protected, or internal. The following
example illustrates the compiler error that results when a StringWrapper class constructor exposes an internal
StringOperationType enumeration value that determines how a string value should be wrapped.
using System;
using System.Text;
Imports System.Text
<Assembly:CLSCompliant(True)>
using System;
[assembly:CLSCompliant(true)]
Generic type names are encoded in the form name'n, where name is the type name, ` is a character literal, and n is
the number of parameters declared on the type, or, for nested generic types, the number of newly introduced type
parameters. This encoding of generic type names is primarily of interest to developers who use reflection to access
CLS-complaint generic types in a library.
If constraints are applied to a generic type, any types used as constraints must also be CLS-compliant. The following
example defines a class named BaseClass that is not CLS-compliant and a generic class named BaseCollection
whose type parameter must derive from BaseClass . But because BaseClass is not CLS-compliant, the compiler
emits a warning.
using System;
[assembly:CLSCompliant(true)]
Assembly: CLSCompliant(True)>
If a generic type is derived from a generic base type, it must redeclare any constraints so that it can guarantee that
constraints on the base type are also satisfied. The following example defines a Number<T> that can represent any
numeric type. It also defines a FloatingPoint<T> class that represents a floating point value. However, the source
code fails to compile, because it does not apply the constraint on Number<T> (that T must be a value type) to
FloatingPoint<T> .
using System;
[assembly:CLSCompliant(true)]
The example compiles successfully if the constraint is added to the FloatingPoint<T> class.
using System;
[assembly:CLSCompliant(true)]
The Common Language Specification imposes a conservative per-instantiation model for nested types and
protected members. Open generic types cannot expose fields or members with signatures that contain a specific
instantiation of a nested, protected generic type. Non-generic types that extend a specific instantiation of a generic
base class or interface cannot expose fields or members with signatures that contain a different instantiation of a
nested, protected generic type.
The following example defines a generic type, C1<T> , and a protected class, C1<T>.N . C1<T> has two methods, M1
and M2 . However, M1 is not CLS-compliant because it tries to return a C1<int>.N object from C1<T> . A second
class, C2 , is derived from C1<long> . It has two methods, M3 and M4 . M3 is not CLS-compliant because it tries to
return a C1<int>.N object from a subclass of C1<long> . Note that language compilers can be even more restrictive.
In this example, Visual Basic displays an error when it tries to compile M4 .
using System;
[assembly:CLSCompliant(true)]
Protected Sub M1(n As C1(Of Integer).N) ' Not CLS-compliant - C1<int>.N not
' accessible from within C1(Of T) in all
End Sub ' languages
Protected Sub M2(n As C1(Of T).N) ' CLS-compliant – C1(Of T).N accessible
End Sub ' inside C1(Of T)
End Class
Constructors
Constructors in CLS-compliant classes and structures must follow these rules:
A constructor of a derived class must call the instance constructor of its base class before it accesses
inherited instance data. This requirement is due to the fact that base class constructors are not inherited by
their derived classes. This rule does not apply to structures, which do not support direct inheritance.
Typically, compilers enforce this rule independently of CLS compliance, as the following example shows. It
creates a Doctor class that is derived from a Person class, but the Doctor class fails to call the Person
class constructor to initialize inherited instance fields.
using System;
[assembly: CLSCompliant(true)]
fName = firstName;
lName = lastName;
_id = id;
}
public string Id
{
get { return _id; }
}
fName = firstName
lName = lastName
_id = id
End Sub
An object constructor cannot be called except to create an object. In addition, an object cannot be initialized
twice. For example, this means that Object.MemberwiseClone must not call constructors.
Properties
Properties in CLS-compliant types must follow these rules:
A property must have a setter, a getter, or both. In an assembly, these are implemented as special methods,
which means that they will appear as separate methods (the getter is named get _propertyname and the
setter is set*\_*propertyname*) marked as SpecialName` in the assembly's metadata. The C# compiler
enforces this rule automatically without the need to apply the CLSCompliantAttribute attribute.
A property's type is the return type of the property getter and the last argument of the setter. These types
must be CLS compliant, and arguments cannot be assigned to the property by reference (that is, they cannot
be managed pointers).
If a property has both a getter and a setter, they must both be virtual, both static, or both instance. The C#
compiler automatically enforces this rule through property definition syntax.
Events
An event is defined by its name and its type. The event type is a delegate that is used to indicate the event. For
example, the DbConnection.StateChange event is of type StateChangeEventHandler . In addition to the event itself,
three methods with names based on the event name provide the event's implementation and are marked as
SpecialName in the assembly's metadata:
A method for adding an event handler, named add _EventName. For example, the event subscription
method for the DbConnection.StateChange event is named add_StateChange .
A method for removing an event handler, named remove _EventName. For example, the removal method for
the DbConnection.StateChange event is named remove_StateChange .
A method for indicating that the event has occurred, named raise _EventName.
NOTE
Most of the Common Language Specification's rules regarding events are implemented by language compilers and are
transparent to component developers.
The methods for adding, removing, and raising the event must have the same accessibility. They must also all be
static, instance, or virtual. The methods for adding and removing an event have one parameter whose type is the
event delegate type. The add and remove methods must both be present or both be absent.
The following example defines a CLS-compliant class named Temperature that raises a TemperatureChanged event if
the change in temperature between two readings equals or exceeds a threshold value. The Temperature class
explicitly defines a raise_TemperatureChanged method so that it can selectively execute event handlers.
using System;
using System.Collections;
using System.Collections.Generic;
[assembly: CLSCompliant(true)]
public Example()
{
temp = new Temperature(65, 3);
temp.TemperatureChanged += this.TemperatureNotification;
RecordTemperatures();
Example ex = new Example(temp);
ex.RecordTemperatures();
}
public Example(Temperature t)
{
temp = t;
RecordTemperatures();
}
Imports System.Collections
Imports System.Collections.Generic
<Assembly: CLSCompliant(True)>
End Sub
Overloads
The Common Language Specification imposes the following requirements on overloaded members:
Members can be overloaded based on the number of parameters and the type of any parameter. Calling
convention, return type, custom modifiers applied to the method or its parameter, and whether parameters
are passed by value or by reference are not considered when differentiating between overloads. For an
example, see the code for the requirement that names must be unique within a scope in the Naming
conventions section.
Only properties and methods can be overloaded. Fields and events cannot be overloaded.
Generic methods can be overloaded based on the number of their generic parameters.
NOTE
The op_Explicit and op_Implicit operators are exceptions to the rule that return value is not considered part of a
method signature for overload resolution. These two operators can be overloaded based on both their parameters and their
return value.
Exceptions
Exception objects must derive from System.Exception or from another type derived from System.Exception . The
following example illustrates the compiler error that results when a custom class named ErrorClass is used for
exception handling.
using System;
[assembly: CLSCompliant(true)]
<Assembly: CLSCompliant(True)>
To correct this error, the ErrorClass class must inherit from System.Exception . In addition, the Message property
must be overridden. The following example corrects these errors to define an ErrorClass class that is CLS-
compliant.
using System;
[assembly: CLSCompliant(true)]
Imports System.Runtime.CompilerServices
<Assembly: CLSCompliant(True)>
Attributes
In.NET Framework assemblies, custom attributes provide an extensible mechanism for storing custom attributes
and retrieving metadata about programming objects, such as assemblies, types, members, and method parameters.
Custom attributes must derive from System.Attribute or from a type derived from System.Attribute .
The following example violates this rule. It defines a NumericAttribute class that does not derive from
System.Attribute . Note that a compiler error results only when the non-CLS-compliant attribute is applied, not
when the class is defined.
using System;
[assembly: CLSCompliant(true)]
[AttributeUsageAttribute(AttributeTargets.Class | AttributeTargets.Struct)]
public class NumericAttribute
{
private bool _isNumeric;
<Assembly: CLSCompliant(True)>
<AttributeUsageAttribute(AttributeTargets.Class Or AttributeTargets.Struct)> _
Public Class NumericAttribute
Private _isNumeric As Boolean
The following example defines a DescriptionAttribute class that derives from Attribute. The class constructor has a
parameter of type Descriptor , so the class is not CLS-compliant. Note that the C# compiler emits a warning but
compiles successfully.
using System;
[assembly:CLSCompliantAttribute(true)]
[AttributeUsage(AttributeTargets.All)]
public class DescriptionAttribute : Attribute
{
private Descriptor desc;
public DescriptionAttribute(Descriptor d)
{
desc = d;
}
<AttributeUsage(AttributeTargets.All)> _
Public Class DescriptionAttribute : Inherits Attribute
Private desc As Descriptor
WARNING
In some cases, language compilers enforce CLS-compliant rules regardless of whether the CLSCompliantAttribute attribute
is used. For example, defining a *static member in an interface violates a CLS rule. However, if you define a *static
member in an interface, the C# compiler displays an error message and fails to compile the app.
The CLSCompliantAttribute attribute is marked with an AttributeUsageAttribute attribute that has a value of
AttributeTargets.All . This value allows you to apply the CLSCompliantAttribute attribute to any program element,
including assemblies, modules, types (classes, structures, enumerations, interfaces, and delegates), type members
(constructors, methods, properties, fields, and events), parameters, generic parameters, and return values. However,
in practice, you should apply the attribute only to assemblies, types, and type members. Otherwise, compilers
ignore the attribute and continue to generate compiler warnings whenever they encounter a non-compliant
parameter, generic parameter, or return value in your library's public interface.
The value of the CLSCompliantAttribute attribute is inherited by contained program elements. For example, if an
assembly is marked as CLS-compliant, its types are also CLS-compliant. If a type is marked as CLS-compliant, its
nested types and members are also CLS-compliant.
You can explicitly override the inherited compliance by applying the CLSCompliantAttribute attribute to a contained
program element. For example, you can use the CLSCompliantAttribute attribute with an isCompliant value of
false to define a non-compliant type in a compliant assembly, and you can use the attribute with an isComplian
value of true to define a compliant type in a non-compliant assembly. You can also define non-compliant
members in a compliant type. However, a non-compliant type cannot have compliant members, so you cannot use
the attribute with an isCompliant value of true to override inheritance from a non-compliant type.
When you are developing components, you should always use the CLSCompliantAttribute attribute to indicate
whether your assembly, its types, and its members are CLS-compliant.
To create CLS-compliant components:
1. Use the CLSCompliantAttribute to mark you assembly as CLS-compliant.
2. Mark any publicly exposed types in the assembly that are not CLS-compliant as non-compliant.
3. Mark any publicly exposed members in CLS-compliant types as non-compliant.
4. Provide a CLS-compliant alternative for non-CLS-compliant members.
If you've successfully marked all your non-compliant types and members, your compiler should not emit any non-
compliance warnings. However, you should indicate which members are not CLS-compliant and list their CLS-
compliant alternatives in your product documentation.
The following example uses the CLSCompliantAttribute attribute to define a CLS-compliant assembly and a type,
CharacterUtilities , that has two non-CLS-compliant members. Because both members are tagged with the
CLSCompliant(false) attribute, the compiler produces no warnings. The class also provides a CLS-compliant
alternative for both methods. Ordinarily, we would just add two overloads to the ToUTF16 method to provide CLS-
compliant alternatives. However, because methods cannot be overloaded based on return value, the names of the
CLS-compliant methods are different from the names of the non-compliant methods.
using System;
using System.Text;
[assembly:CLSCompliant(true)]
if (chars.Length == 2) {
if (! Char.IsSurrogatePair(chars[0], chars[1]))
throw new ArgumentException("The array must contain a low and a high surrogate.");
else
return Char.ConvertToUtf32(chars[0], chars[1]);
}
else {
return Char.ConvertToUtf32(chars.ToString(), 0);
}
}
}
Imports System.Text
<Assembly:CLSCompliant(True)>
If you are developing an app rather than a library (that is, if you aren't exposing types or members that can be
consumed by other app developers), the CLS compliance of the program elements that your app consumes are of
interest only if your language does not support them. In that case, your language compiler will generate an error
when you try to use a non-CLS-compliant element.
Cross-Language Interoperability
Language independence has a number of possible meanings. One meaning involves seamlessly consuming types
written in one language from an app written in another language. A second meaning, which is the focus of this
article, involves combining code written in multiple languages into a single .NET Framework assembly.
The following example illustrates cross-language interoperability by creating a class library named Utilities.dll that
includes two classes, NumericLib and StringLib . The NumericLib class is written in C#, and the StringLib class is
written in Visual Basic. Here's the source code for StringUtil.vb , which includes a single member, ToTitleCase , in
its StringLib class.
Imports System.Collections.Generic
Imports System.Runtime.CompilerServices
Sub New()
Dim words() As String = { "a", "an", "and", "of", "the" }
exclusions = New List(Of String)
exclusions.AddRange(words)
End Sub
<Extension()> _
Public Function ToTitleCase(title As String) As String
Dim words() As String = title.Split()
Dim result As String = String.Empty
Here's the source code for NumberUtil.cs, which defines a NumericLib class that has two members, IsEven and
NearZero .
using System;
To package the two classes in a single assembly, you must compile them into modules. To compile the Visual Basic
source code file into a module, use this command:
To compile the C# source code file into a module, use this command:
You then use the Link tool (Link.exe) to compile the two modules into an assembly:
The following example then calls the NumericLib.NearZero and StringLib.ToTitleCase methods. Note that both the
Visual Basic code and the C# code are able to access the methods in both classes.
using System;
To compile with C#, change the name of the compiler from vbc to csc, and change the file extension from .vb to .cs:
The .NET Framework is language independent. This means that, as a developer, you can develop in one of the
many languages that target the .NET Framework, such as C#, C++/CLI, Eiffel, F#, IronPython, IronRuby,
PowerBuilder, Visual Basic, Visual COBOL, and Windows PowerShell. You can access the types and members of
class libraries developed for the .NET Framework without having to know the language in which they were
originally written and without having to follow any of the original language's conventions. If you are a component
developer, your component can be accessed by any .NET Framework app regardless of its language.
NOTE
This first part of this article discusses creating language-independent components—that is, components that can be
consumed by apps that are written in any language. You can also create a single component or app from source code
written in multiple languages; see Cross-Language Interoperability in the second part of this article.
To fully interact with other objects written in any language, objects must expose to callers only those features that
are common to all languages. This common set of features is defined by the Common Language Specification
(CLS), which is a set of rules that apply to generated assemblies. The Common Language Specification is defined in
Partition I, Clauses 7 through 11 of the ECMA-335 Standard: Common Language Infrastructure.
If your component conforms to the Common Language Specification, it is guaranteed to be CLS-compliant and can
be accessed from code in assemblies written in any programming language that supports the CLS. You can
determine whether your component conforms to the Common Language Specification at compile time by
applying the CLSCompliantAttribute attribute to your source code. For more information, see The
CLSCompliantAttribute attribute.
In this article:
CLS compliance rules
Types and type member signatures
Naming conventions
Type conversion
Arrays
Interfaces
Enumerations
Type members in general
Member accessibility
Generic types and members
Constructors
Properties
Events
Overloads
Exceptions
Attributes
The CLSCompliantAttribute attribute
Cross-Language Interoperability
NOTE
The Common Language Specification discusses each rule for CLS compliance as it applies to consumers (developers who are
programmatically accessing a component that is CLS-compliant), frameworks (developers who are using a language compiler
to create CLS-compliant libraries), and extenders (developers who are creating a tool such as a language compiler or a code
parser that creates CLS-compliant components). This article focuses on the rules as they apply to frameworks. Note, though,
that some of the rules that apply to extenders may also apply to assemblies that are created using Reflection.Emit.
To design a component that is language independent, you only need to apply the rules for CLS compliance to your
component's public interface. Your private implementation does not have to conform to the specification.
IMPORTANT
The rules for CLS compliance apply only to a component's public interface, not to its private implementation.
For example, unsigned integers other than Byte are not CLS-compliant. Because the Person class in the following
example exposes an Age property of type UInt16, the following code displays a compiler warning.
using System;
[assembly: CLSCompliant(true)]
You can make the Person class CLS-compliant by changing the type of Age property from UInt16 to Int16, which
is a CLS-compliant, 16-bit signed integer. You do not have to change the type of the private personAge field.
using System;
[assembly: CLSCompliant(true)]
<Assembly: CLSCompliant(True)>
Types Type and type member Boxed value types are not 3
signatures CLS-compliant.
[assembly: CLSCompliant(true)]
[CLSCompliant(false)]
public class Counter
{
UInt32 ctr;
public Counter()
{
ctr = 0;
}
<CLSCompliant(False)> _
Public Class Counter
Dim ctr As UInt32
All types that appear in member signatures, including a method's return type or a property type, must be CLS-
compliant. In addition, for generic types:
All types that compose an instantiated generic type must be CLS-compliant.
All types used as constraints on generic parameters must be CLS-compliant.
The .NET Framework common type system includes a number of built-in types that are supported directly by the
common language runtime and are specially encoded in an assembly's metadata. Of these intrinsic types, the
types listed in the following table are CLS-compliant.
The intrinsic types listed in the following table are not CLS-Compliant.
The .NET Framework Class Library or any other class library may include other types that aren't CLS-compliant; for
example:
Boxed value types. The following C# example creates a class that has a public property of type int* named
Value . Because an int* is a boxed value type, the compiler flags it as non-CLS-compliant.
using System;
[assembly:CLSCompliant(true)]
Typed references, which are special constructs that contain a reference to an object and a reference to a
type. Typed references are represented in the .NET Framework by the TypedReference class.
If a type is not CLS-compliant, you should apply the CLSCompliantAttribute attribute with an isCompliant value of
false to it. For more information, see the The CLSCompliantAttribute attribute section.
The following example illustrates the problem of CLS compliance in a method signature and in generic type
instantiation. It defines an InvoiceItem class with a property of type UInt32, a property of type
Nullable(Of UInt32) , and a constructor with parameters of type UInt32 and Nullable(Of UInt32) . You get four
compiler warnings when you try to compile this example.
using System;
[assembly: CLSCompliant(true)]
To eliminate the compiler warnings, replace the non-CLS-compliant types in the InvoiceItem public interface with
compliant types:
using System;
[assembly: CLSCompliant(true)]
qty = quantity;
}
In addition to the specific types listed, some categories of types are not CLS compliant. These include unmanaged
pointer types and function pointer types. The following example generates a compiler warning because it uses a
pointer to an integer to create an array of integers.
using System;
[assembly: CLSCompliant(true)]
For CLS-compliant abstract classes (that is, classes marked as abstract in C# or as MustInherit in Visual Basic),
all members of the class must also be CLS-compliant.
Naming conventions
Because some programming languages are case-insensitive, identifiers (such as the names of namespaces, types,
and members) must differ by more than case. Two identifiers are considered equivalent if their lowercase
mappings are the same. The following C# example defines two public classes, Person and person . Because they
differ only by case, the C# compiler flags them as not CLS-compliant.
using System;
[assembly: CLSCompliant(true)]
}
// Compilation produces a compiler warning like the following:
// Naming1.cs(11,14): warning CS3005: Identifier 'person' differing
// only in case is not CLS-compliant
// Naming1.cs(6,14): (Location of symbol related to previous warning)
Programming language identifiers, such as the names of namespaces, types, and members, must conform to the
Unicode Standard 3.0, Technical Report 15, Annex 7. This means that:
The first character of an identifier can be any Unicode uppercase letter, lowercase letter, title case letter,
modifier letter, other letter, or letter number. For information on Unicode character categories, see the
System.Globalization.UnicodeCategory enumeration.
Subsequent characters can be from any of the categories as the first character, and can also include non-
spacing marks, spacing combining marks, decimal numbers, connector punctuations, and formatting codes.
Before you compare identifiers, you should filter out formatting codes and convert the identifiers to Unicode
Normalization Form C, because a single character can be represented by multiple UTF-16-encoded code units.
Character sequences that produce the same code units in Unicode Normalization Form C are not CLS-compliant.
The following example defines a property named Å , which consists of the character ANGSTROM SIGN (U+212B),
and a second property named Å , which consists of the character LATIN CAPITAL LETTER A WITH RING ABOVE
(U+00C5). Both the C# and Visual Basic compilers flag the source code as non-CLS-compliant.
public class Size
{
private double a1;
private double a2;
public double Å
{
get { return a1; }
set { a1 = value; }
}
public double Å
{
get { return a2; }
set { a2 = value; }
}
}
// Compilation produces a compiler warning like the following:
// Naming2a.cs(16,18): warning CS3005: Identifier 'Size.Å' differing only in case is not
// CLS-compliant
// Naming2a.cs(10,18): (Location of symbol related to previous warning)
// Naming2a.cs(18,8): warning CS3005: Identifier 'Size.Å.get' differing only in case is not
// CLS-compliant
// Naming2a.cs(12,8): (Location of symbol related to previous warning)
// Naming2a.cs(19,8): warning CS3005: Identifier 'Size.Å.set' differing only in case is not
// CLS-compliant
// Naming2a.cs(13,8): (Location of symbol related to previous warning)
<Assembly: CLSCompliant(True)>
Public Class Size
Private a1 As Double
Private a2 As Double
Member names within a particular scope (such as the namespaces within an assembly, the types within a
namespace, or the members within a type) must be unique except for names that are resolved through
overloading. This requirement is more stringent than that of the common type system, which allows multiple
members within a scope to have identical names as long as they are different kinds of members (for example, one
is a method and one is a field). In particular, for type members:
Fields and nested types are distinguished by name alone.
Methods, properties, and events that have the same name must differ by more than just return type.
The following example illustrates the requirement that member names must be unique within their scope. It
defines a class named Converter that includes four members named Conversion . Three are methods, and one is a
property. The method that includes an Int64 parameter is uniquely named, but the two methods with an Int32
parameter are not, because return value is not considered a part of a member's signature. The Conversion
property also violates this requirement, because properties cannot have the same name as overloaded methods.
using System;
[assembly: CLSCompliant(true)]
Individual languages include unique keywords, so languages that target the common language runtime must also
provide some mechanism for referencing identifiers (such as type names) that coincide with keywords. For
example, case is a keyword in both C# and Visual Basic. However, the following Visual Basic example is able to
disambiguate a class named case from the case keyword by using opening and closing braces. Otherwise, the
example would produce the error message, "Keyword is not valid as an identifier," and fail to compile.
The following C# example is able to instantiate the case class by using the @ symbol to disambiguate the
identifier from the language keyword. Without it, the C# compiler would display two error messages, "Type
expected" and "Invalid expression term 'case'."
using System;
Type conversion
The Common Language Specification defines two conversion operators:
op_Implicit, which is used for widening conversions that do not result in loss of data or precision. For
example, the Decimal structure includes an overloaded op_Implicit operator to convert values of integral
types and Char values to Decimal values.
op_Explicit , which is used for narrowing conversions that can result in loss of magnitude (a value is
converted to a value that has a smaller range) or precision. For example, the Decimal structure includes an
overloaded op_Explicit operator to convert Double and Single values to Decimal and to convert Decimal
values to integral values, Double, Single, and Char.
However, not all languages support operator overloading or the definition of custom operators. If you choose to
implement these conversion operators, you should also provide an alternate way to perform the conversion. We
recommend that you provide From Xxx and To Xxx methods.
The following example defines CLS-compliant implicit and explicit conversions. It creates a UDouble class that
represents an signed double-precision, floating-point number. It provides for implicit conversions from UDouble
to Double and for explicit conversions from UDouble to Single, Double to UDouble , and Single to UDouble . It also
defines a ToDouble method as an alternative to the implicit conversion operator and the ToSingle , FromDouble ,
and FromSingle methods as alternatives to the explicit conversion operators.
using System;
number = value;
}
number = value;
}
Arrays
CLS-compliant arrays conform to the following rules:
All dimensions of an array must have a lower bound of zero. The following example creates a non-CLS-
compliant array with a lower bound of one. Note that, despite the presence of the CLSCompliantAttribute
attribute, the compiler does not detect that the array returned by the Numbers.GetTenPrimes method is not
CLS-compliant.
[assembly: CLSCompliant(true)]
return arr;
}
}
<Assembly: CLSCompliant(True)>
Return arr
End Function
End Class
All array elements must consist of CLS-compliant types. The following example defines two methods that
return non-CLS-compliant arrays. The first returns an array of UInt32 values. The second returns an Object
array that includes Int32 and UInt32 values. Although the compiler identifies the first array as non-
compliant because of its UInt32 type, it fails to recognize that the second array includes non-CLS-compliant
elements.
using System;
[assembly: CLSCompliant(true)]
<Assembly: CLSCompliant(True)>
Overload resolution for methods that have array parameters is based on the fact that they are arrays and on
their element type. For this reason, the following definition of an overloaded GetSquares method is CLS-
compliant.
using System;
using System.Numerics;
[assembly: CLSCompliant(true)]
}
return numbersOut;
}
return numbersOut;
}
}
Imports System.Numerics
<Assembly: CLSCompliant(True)>
Interfaces
CLS-compliant interfaces can define properties, events, and virtual methods (methods with no implementation). A
CLS-compliant interface cannot have any of the following:
Static methods or static fields. Both the C# and Visual Basic compilers generate compiler errors if you define
a static member in an interface.
Fields. Both the C# and Visual Basic compilers generate compiler errors if you define a field in an interface.
Methods that are not CLS-compliant. For example, the following interface definition includes a method,
INumber.GetUnsigned , that is marked as non-CLS-compliant. This example generates a compiler warning.
using System;
[assembly:CLSCompliant(true)]
<Assembly: CLSCompliant(True)>
Because of this rule, CLS-compliant types are not required to implement non-CLS-compliant members. If a
CLS-compliant framework does expose a class that implements a non-CLS compliant interface, it should
also provide concrete implementations of all non-CLS-compliant members.
CLS-compliant language compilers must also allow a class to provide separate implementations of members that
have the same name and signature in multiple interfaces. Both C# and Visual Basic support explicit interface
implementations to provide different implementations of identically named methods. Visual Basic also supports
the Implements keyword, which enables you to explicitly designate which interface and member a particular
member implements. The following example illustrates this scenario by defining a Temperature class that
implements the ICelsius and IFahrenheit interfaces as explicit interface implementations.
using System;
[assembly: CLSCompliant(true)]
decimal IFahrenheit.GetTemperature()
{
return _value * 9 / 5 + 32;
}
decimal ICelsius.GetTemperature()
{
return _value;
}
}
public class Example
{
public static void Main()
{
Temperature temp = new Temperature(100.0m);
ICelsius cTemp = temp;
IFahrenheit fTemp = temp;
Console.WriteLine("Temperature in Celsius: {0} degrees",
cTemp.GetTemperature());
Console.WriteLine("Temperature in Fahrenheit: {0} degrees",
fTemp.GetTemperature());
}
}
// The example displays the following output:
// Temperature in Celsius: 100.0 degrees
// Temperature in Fahrenheit: 212.0 degrees
<Assembly: CLSCompliant(True)>
Module Example
Public Sub Main()
Dim temp As New Temperature(100.0d)
Console.WriteLine("Temperature in Celsius: {0} degrees",
temp.GetCelsius())
Console.WriteLine("Temperature in Fahrenheit: {0} degrees",
temp.GetFahrenheit())
End Sub
End Module
' The example displays the following output:
' Temperature in Celsius: 100.0 degrees
' Temperature in Fahrenheit: 212.0 degrees
Enumerations
CLS-compliant enumerations must follow these rules:
The underlying type of the enumeration must be an intrinsic CLS-compliant integer (Byte, Int16, Int32, or
Int64). For example, the following code tries to define an enumeration whose underlying type is UInt32 and
generates a compiler warning.
using System;
[assembly: CLSCompliant(true)]
<Assembly: CLSCompliant(True)>
An enumeration type must have a single instance field named Value__ that is marked with the
System.Reflection.FieldAttributes.RTSpecialName attribute. This enables you to reference the field value
implicitly.
An enumeration includes literal static fields whose types match the type of the enumeration itself. For
example, if you define a State enumeration with values of State.On and State.Off , State.On and
State.Off are both literal static fields whose type is State .
[assembly: CLSCompliant(true)]
Types in the signature of a member must be accessible whenever that member is accessible. For example, this
means that a public member cannot include a parameter whose type is private, protected, or internal. The
following example illustrates the compiler error that results when a StringWrapper class constructor exposes an
internal StringOperationType enumeration value that determines how a string value should be wrapped.
using System;
using System.Text;
Imports System.Text
<Assembly:CLSCompliant(True)>
using System;
[assembly:CLSCompliant(true)]
Generic type names are encoded in the form name`n, where name is the type name, ` is a character literal, and n is
the number of parameters declared on the type, or, for nested generic types, the number of newly introduced type
parameters. This encoding of generic type names is primarily of interest to developers who use reflection to access
CLS-complaint generic types in a library.
If constraints are applied to a generic type, any types used as constraints must also be CLS-compliant. The
following example defines a class named BaseClass that is not CLS-compliant and a generic class named
BaseCollection whose type parameter must derive from BaseClass . But because BaseClass is not CLS-compliant,
the compiler emits a warning.
using System;
[assembly:CLSCompliant(true)]
<Assembly: CLSCompliant(True)>
If a generic type is derived from a generic base type, it must redeclare any constraints so that it can guarantee that
constraints on the base type are also satisfied. The following example defines a Number<T> that can represent any
numeric type. It also defines a FloatingPoint<T> class that represents a floating point value. However, the source
code fails to compile, because it does not apply the constraint on Number<T> (that T must be a value type) to
FloatingPoint<T> .
using System;
[assembly:CLSCompliant(true)]
The example compiles successfully if the constraint is added to the FloatingPoint<T> class.
using System;
[assembly:CLSCompliant(true)]
The Common Language Specification imposes a conservative per-instantiation model for nested types and
protected members. Open generic types cannot expose fields or members with signatures that contain a specific
instantiation of a nested, protected generic type. Non-generic types that extend a specific instantiation of a generic
base class or interface cannot expose fields or members with signatures that contain a different instantiation of a
nested, protected generic type.
The following example defines a generic type, C1<T> (or C1(Of T) in Visual Basic), and a protected class, C1<T>.N
(or C1(Of T).N in Visual Basic). C1<T> has two methods, M1 and M2 . However, M1 is not CLS-compliant
because it tries to return a C1<int>.N (or C1(Of Integer).N ) object from C1<T> (or C1(Of T) ). A second class,
C2 , is derived from C1<long> (or C1(Of Long) ). It has two methods, M3 and M4 . M3 is not CLS-compliant
because it tries to return a C1<int>.N (or C1(Of Integer).N ) object from a subclass of C1<long> . Note that
language compilers can be even more restrictive. In this example, Visual Basic displays an error when it tries to
compile M4 .
using System;
[assembly:CLSCompliant(true)]
Protected Sub M1(n As C1(Of Integer).N) ' Not CLS-compliant - C1<int>.N not
' accessible from within C1(Of T) in all
End Sub ' languages
Protected Sub M2(n As C1(Of T).N) ' CLS-compliant – C1(Of T).N accessible
End Sub ' inside C1(Of T)
End Class
Constructors
Constructors in CLS-compliant classes and structures must follow these rules:
A constructor of a derived class must call the instance constructor of its base class before it accesses
inherited instance data. This requirement is due to the fact that base class constructors are not inherited by
their derived classes. This rule does not apply to structures, which do not support direct inheritance.
Typically, compilers enforce this rule independently of CLS compliance, as the following example shows. It
creates a Doctor class that is derived from a Person class, but the Doctor class fails to call the Person
class constructor to initialize inherited instance fields.
using System;
[assembly: CLSCompliant(true)]
fName = firstName;
lName = lastName;
_id = id;
}
public string Id
{
get { return _id; }
}
fName = firstName
lName = lastName
_id = id
End Sub
An object constructor cannot be called except to create an object. In addition, an object cannot be initialized
twice. For example, this means that System.Object.MemberwiseClone and deserialization methods such as
System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize must not call constructors.
Properties
Properties in CLS-compliant types must follow these rules:
A property must have a setter, a getter, or both. In an assembly, these are implemented as special methods,
which means that they will appear as separate methods (the getter is named get_ propertyname and the
setter is set_ propertyname) marked as SpecialName in the assembly's metadata. The C# and Visual Basic
compilers enforce this rule automatically without the need to apply the CLSCompliantAttribute attribute.
A property's type is the return type of the property getter and the last argument of the setter. These types
must be CLS compliant, and arguments cannot be assigned to the property by reference (that is, they
cannot be managed pointers).
If a property has both a getter and a setter, they must both be virtual, both static, or both instance. The C#
and Visual Basic compilers automatically enforce this rule through their property definition syntax.
Events
An event is defined by its name and its type. The event type is a delegate that is used to indicate the event. For
example, the System.AppDomain.AssemblyResolve event is of type ResolveEventHandler. In addition to the event
itself, three methods with names based on the event name provide the event's implementation and are marked as
SpecialName in the assembly's metadata:
A method for adding an event handler, named add_ EventName. For example, the event subscription
method for the System.AppDomain.AssemblyResolve event is named add_AssemblyResolve .
A method for removing an event handler, named remove_ EventName. For example, the removal method
for the System.AppDomain.AssemblyResolve event is named remove_AssemblyResolve .
A method for indicating that the event has occurred, named raise_ EventName.
NOTE
Most of the Common Language Specification's rules regarding events are implemented by language compilers and are
transparent to component developers.
The methods for adding, removing, and raising the event must have the same accessibility. They must also all be
static, instance, or virtual. The methods for adding and removing an event have one parameter whose type is the
event delegate type. The add and remove methods must both be present or both be absent.
The following example defines a CLS-compliant class named Temperature that raises a TemperatureChanged event
if the change in temperature between two readings equals or exceeds a threshold value. The Temperature class
explicitly defines a raise_TemperatureChanged method so that it can selectively execute event handlers.
using System;
using System.Collections;
using System.Collections.Generic;
[assembly: CLSCompliant(true)]
public Example()
{
temp = new Temperature(65, 3);
temp.TemperatureChanged += this.TemperatureNotification;
RecordTemperatures();
Example ex = new Example(temp);
ex.RecordTemperatures();
}
public Example(Temperature t)
{
temp = t;
RecordTemperatures();
}
Imports System.Collections
Imports System.Collections.Generic
<Assembly: CLSCompliant(True)>
End Sub
Overloads
The Common Language Specification imposes the following requirements on overloaded members:
Members can be overloaded based on the number of parameters and the type of any parameter. Calling
convention, return type, custom modifiers applied to the method or its parameter, and whether parameters
are passed by value or by reference are not considered when differentiating between overloads. For an
example, see the code for the requirement that names must be unique within a scope in the Naming
conventions section.
Only properties and methods can be overloaded. Fields and events cannot be overloaded.
Generic methods can be overloaded based on the number of their generic parameters.
NOTE
The op_Explicit and op_Implicit operators are exceptions to the rule that return value is not considered part of a
method signature for overload resolution. These two operators can be overloaded based on both their parameters and their
return value.
Exceptions
Exception objects must derive from System.Exception or from another type derived from System.Exception. The
following example illustrates the compiler error that results when a custom class named ErrorClass is used for
exception handling.
using System;
[assembly: CLSCompliant(true)]
<Assembly: CLSCompliant(True)>
To correct this error, the ErrorClass class must inherit from System.Exception. In addition, the Message property
must be overridden. The following example corrects these errors to define an ErrorClass class that is CLS-
compliant.
using System;
[assembly: CLSCompliant(true)]
Imports System.Runtime.CompilerServices
<Assembly: CLSCompliant(True)>
Attributes
In.NET Framework assemblies, custom attributes provide an extensible mechanism for storing custom attributes
and retrieving metadata about programming objects, such as assemblies, types, members, and method
parameters. Custom attributes must derive from System.Attribute or from a type derived from System.Attribute.
The following example violates this rule. It defines a NumericAttribute class that does not derive from
System.Attribute. Note that a compiler error results only when the non-CLS-compliant attribute is applied, not
when the class is defined.
using System;
[assembly: CLSCompliant(true)]
[AttributeUsageAttribute(AttributeTargets.Class | AttributeTargets.Struct)]
public class NumericAttribute
{
private bool _isNumeric;
<Assembly: CLSCompliant(True)>
<AttributeUsageAttribute(AttributeTargets.Class Or AttributeTargets.Struct)> _
Public Class NumericAttribute
Private _isNumeric As Boolean
using System;
[assembly:CLSCompliantAttribute(true)]
[AttributeUsage(AttributeTargets.All)]
public class DescriptionAttribute : Attribute
{
private Descriptor desc;
public DescriptionAttribute(Descriptor d)
{
desc = d;
}
<AttributeUsage(AttributeTargets.All)> _
Public Class DescriptionAttribute : Inherits Attribute
Private desc As Descriptor
WARNING
In some cases, language compilers enforce CLS-compliant rules regardless of whether the CLSCompliantAttribute attribute is
used. For example, defining a static member in an interface violates a CLS rule. However, if you define a static (in C#) or
Shared (in Visual Basic) member in an interface, both the C# and Visual Basic compilers display an error message and fail to
compile the app.
The CLSCompliantAttribute attribute is marked with an AttributeUsageAttribute attribute that has a value of
System.AttributeTargets.All. This value allows you to apply the CLSCompliantAttribute attribute to any program
element, including assemblies, modules, types (classes, structures, enumerations, interfaces, and delegates), type
members (constructors, methods, properties, fields, and events), parameters, generic parameters, and return
values. However, in practice, you should apply the attribute only to assemblies, types, and type members.
Otherwise, compilers ignore the attribute and continue to generate compiler warnings whenever they encounter a
non-compliant parameter, generic parameter, or return value in your library's public interface.
The value of the CLSCompliantAttribute attribute is inherited by contained program elements. For example, if an
assembly is marked as CLS-compliant, its types are also CLS-compliant. If a type is marked as CLS-compliant, its
nested types and members are also CLS-compliant.
You can explicitly override the inherited compliance by applying the CLSCompliantAttribute attribute to a
contained program element. For example, you can use the CLSCompliantAttribute attribute with an isCompliant
value of false to define a non-compliant type in a compliant assembly, and you can use the attribute with an
isCompliant value of true to define a compliant type in a non-compliant assembly. You can also define non-
compliant members in a compliant type. However, a non-compliant type cannot have compliant members, so you
cannot use the attribute with an isCompliant value of true to override inheritance from a non-compliant type.
When you are developing components, you should always use the CLSCompliantAttribute attribute to indicate
whether your assembly, its types, and its members are CLS-compliant.
To create CLS-compliant components:
1. Use the CLSCompliantAttribute to mark you assembly as CLS-compliant.
2. Mark any publicly exposed types in the assembly that are not CLS-compliant as non-compliant.
3. Mark any publicly exposed members in CLS-compliant types as non-compliant.
4. Provide a CLS-compliant alternative for non-CLS-compliant members.
If you've successfully marked all your non-compliant types and members, your compiler should not emit any non-
compliance warnings. However, you should indicate which members are not CLS-compliant and list their CLS-
compliant alternatives in your product documentation.
The following example uses the CLSCompliantAttribute attribute to define a CLS-compliant assembly and a type,
CharacterUtilities , that has two non-CLS-compliant members. Because both members are tagged with the
CLSCompliant(false) attribute, the compiler produces no warnings. The class also provides a CLS-compliant
alternative for both methods. Ordinarily, we would just add two overloads to the ToUTF16 method to provide CLS-
compliant alternatives. However, because methods cannot be overloaded based on return value, the names of the
CLS-compliant methods are different from the names of the non-compliant methods.
using System;
using System.Text;
[assembly:CLSCompliant(true)]
if (chars.Length == 2) {
if (! Char.IsSurrogatePair(chars[0], chars[1]))
throw new ArgumentException("The array must contain a low and a high surrogate.");
else
return Char.ConvertToUtf32(chars[0], chars[1]);
}
else {
return Char.ConvertToUtf32(chars.ToString(), 0);
}
}
}
Imports System.Text
<Assembly:CLSCompliant(True)>
If you are developing an app rather than a library (that is, if you aren't exposing types or members that can be
consumed by other app developers), the CLS compliance of the program elements that your app consumes are of
interest only if your language does not support them. In that case, your language compiler will generate an error
when you try to use a non-CLS-compliant element.
Cross-Language Interoperability
Language independence has a number of possible meanings. One meaning, which is discussed in the article
Language Independence and Language-Independent Components, involves seamlessly consuming types written in
one language from an app written in another language. A second meaning, which is the focus of this article,
involves combining code written in multiple languages into a single .NET Framework assembly.
The following example illustrates cross-language interoperability by creating a class library named Utilities.dll that
includes two classes, NumericLib and StringLib . The NumericLib class is written in C#, and the StringLib class is
written in Visual Basic. Here's the source code for StringUtil.vb, which includes a single member, ToTitleCase , in
its StringLib class.
Imports System.Collections.Generic
Imports System.Runtime.CompilerServices
Sub New()
Dim words() As String = { "a", "an", "and", "of", "the" }
exclusions = New List(Of String)
exclusions.AddRange(words)
End Sub
<Extension()> _
Public Function ToTitleCase(title As String) As String
Dim words() As String = title.Split()
Dim result As String = String.Empty
Here's the source code for NumberUtil.cs, which defines a NumericLib class that has two members, IsEven and
NearZero .
using System;
To package the two classes in a single assembly, you must compile them into modules. To compile the Visual Basic
source code file into a module, use this command:
For more information about the command-line syntax of the Visual Basic compiler, see Building from the
Command Line.
To compile the C# source code file into a module, use this command:
For more information about the command-line syntax of the C# compiler, see Command-line Building With
csc.exe.
You then use the Link tool (Link.exe) to compile the two modules into an assembly:
The following example then calls the NumericLib.NearZero and StringLib.ToTitleCase methods. Note that both the
Visual Basic code and the C# code are able to access the methods in both classes.
using System;
Module Example
Public Sub Main()
Dim dbl As Double = 0.0 - Double.Epsilon
Console.WriteLine(NumericLib.NearZero(dbl))
To compile with C#, change the name of the compiler from vbc to csc, and change the file extension from .vb to
.cs:
See Also
CLSCompliantAttribute
Framework Libraries
8/10/2017 • 2 min to read • Edit Online
.NET has an expansive standard set of class libraries, referred to as either the base class libraries (core set) or
framework class libraries (complete set). These libraries provide implementations for many general and app-
specific types, algorithms and utility functionality. Both commercial and community libraries build on top of the
framework class libraries, providing easy to use off-the-shelf libraries for a wide set of computing tasks.
A subset of these libraries are provided with each .NET implementation. Base Class Library (BCL) APIs are expected
with any .NET implementation, both because developers will want them and because popular libraries will need
them to run. App-specific libraries above the BCL, such as ASP.NET, will not be available on all .NET
implementations.
Primitive Types
.NET includes a set of primitive types, which are used (to varying degrees) in all programs. These types contain
data, such as numbers, strings, bytes and arbitrary objects. The C# language includes keywords for these types. A
sample set of these types is listed below, with the matching C# keywords.
System.Object (object) - The ultimate base class in the CLR type system. It is the root of the type hierarchy.
System.Int16 (short) - A 16-bit signed integer type. The unsigned UInt16 also exists.
System.Int32 (int) - A 32-bit signed integer type. The unsigned UInt32 also exists.
System.Single (float) - A 32-bit floating-point type.
System.Decimal (decimal) - A 128-bit decimal type.
System.Byte (byte) - An unsigned 8-bit integer that represents a byte of memory.
System.Boolean (bool) - A boolean type that represents true or false .
System.Char (char) - A 16-bit numeric type that represents a Unicode character.
System.String (string) - Represents a series of characters. Different than a char[] , but enables indexing into
each individual char in the string .
Data Structures
.NET includes a set of data structures that are the workhorses of almost any .NET apps. These are mostly collections,
but also include other types.
Array - Represents an array of strongly types objects that can be accessed by index. Has a fixed size, per its
construction.
List<T> - Represents a strongly typed list of objects that can be accessed by index. Is automatically resized as
needed.
Dictionary<TKey,TValue> - Represents a collection of values that are indexed by a key. Values can be accessed
via key. Is automatically resized as needed.
Uri - Provides an object representation of a uniform resource identifier (URI) and easy access to the parts of the
URI.
DateTime - Represents an instant in time, typically expressed as a date and time of day.
Utility APIs
.NET includes a set of utility APIs that provide functionality for many important tasks.
HttpClient - An API for sending HTTP requests and receiving HTTP responses from a resource identified by a
URI.
XDocument - An API for loading, and querying XML documents with LINQ.
StreamReader - An API for reading files (StringWriter) Can be used to write files.
App-Model APIs
There are many app-models that can be used with .NET, provided by several companies.
ASP.NET - Provides a web framework for building Web sites and services. Supported on Windows, Linux and
macOS (depends on ASP.NET version).
.NET Framework Class Library Overview
7/29/2017 • 4 min to read • Edit Online
The .NET Framework includes classes, interfaces, and value types that expedite and optimize the development
process and provide access to system functionality. To facilitate interoperability between languages, most .NET
Framework types are CLS-compliant and can therefore be used from any programming language whose compiler
conforms to the common language specification (CLS).
The .NET Framework types are the foundation on which .NET applications, components, and controls are built. The
.NET Framework includes types that perform the following functions:
Represent base data types and exceptions.
Encapsulate data structures.
Perform I/O.
Access information about loaded types.
Invoke .NET Framework security checks.
Provide data access, rich client-side GUI, and server-controlled, client-side GUI.
The .NET Framework provides a rich set of interfaces, as well as abstract and concrete (non-abstract) classes. You
can use the concrete classes as is or, in many cases, derive your own classes from them. To use the functionality of
an interface, you can either create a class that implements the interface or derive a class from one of the .NET
Framework classes that implements the interface.
Naming Conventions
.NET Framework types use a dot syntax naming scheme that connotes a hierarchy. This technique groups related
types into namespaces so they can be searched and referenced more easily. The first part of the full name — up to
the rightmost dot — is the namespace name. The last part of the name is the type name. For example,
System.Collections.ArrayList represents the ArrayList type, which belongs to the System.Collections
namespace. The types in System.Collections can be used to manipulate collections of objects.
This naming scheme makes it easy for library developers extending the .NET Framework to create hierarchical
groups of types and name them in a consistent, informative manner. It also allows types to be unambiguously
identified by their full name (that is, by their namespace and type name), which prevents type name collisions.
Library developers are expected to use the following convention when creating names for their namespaces:
CompanyName.TechnologyName
For example, the namespace Microsoft.Word conforms to this guideline.
The use of naming patterns to group related types into namespaces is a very useful way to build and document
class libraries. However, this naming scheme has no effect on visibility, member access, inheritance, security, or
binding. A namespace can be partitioned across multiple assemblies and a single assembly can contain types from
multiple namespaces. The assembly provides the formal structure for versioning, deployment, security, loading, and
visibility in the common language runtime.
For more information on namespaces and type names, see Common Type System.
System Namespace
The System namespace is the root namespace for fundamental types in the .NET Framework. This namespace
includes classes that represent the base data types used by all applications: Object (the root of the inheritance
hierarchy), Byte, Char, Array, Int32, String, and so on. Many of these types correspond to the primitive data types
that your programming language uses. When you write code using .NET Framework types, you can use your
language's corresponding keyword when a .NET Framework base data type is expected.
The following table lists the base types that the .NET Framework supplies, briefly describes each type, and indicates
the corresponding type in Visual Basic, C#, C++, and JScript.
long
Not CLS-
compliant.
Not CLS-
compliant.
VISUAL BASIC JSCRIPT DATA
CATEGORY CLASS NAME DESCRIPTION DATA TYPE C# DATA TYPE C++ DATA TYPE TYPE
Not CLS-
compliant.
In addition to the base data types, the System namespace contains over 100 classes, ranging from classes that
handle exceptions to classes that deal with core runtime concepts, such as application domains and the garbage
collector. The System namespace also contains many second-level namespaces.
For more information about namespaces, browse the .NET Framework Class Library. The reference documentation
provides a brief overview of each namespace as well as a formal description of each type and its members.
See Also
Common Type System
.NET Framework Class Library
Overview
Working with Base Types in .NET
7/29/2017 • 1 min to read • Edit Online
This section describes .NET base type operations, including formatting, conversion, and common operations.
In This Section
Type Conversion in the .NET Framework
Describes how to convert from one type to another.
Formatting Types
Describes how to format strings using the string format specifiers.
Manipulating Strings
Describes how to manipulate and format strings.
Parsing Strings
Describes how to convert strings into .NET Framework types.
Related Sections
Common Type System
Describes types used by the .NET Framework.
Dates, Times, and Time Zones
Describes how to work with time zones and time zone conversions in time zone-aware applications.
.NET Class Libraries
8/5/2017 • 3 min to read • Edit Online
Class libraries are the shared library concept for .NET. They enable you to componentize useful functionality into
modules that can be used by multiple applications. They can also be used as a means of loading functionality that is
not needed or not known at application startup. Class libraries are described using the .NET Assembly file format.
There are three types of class libraries that you can use:
Platform-specific class libraries have access to all the APIs in a given platform (for example, .NET Framework,
Xamarin iOS), but can only be used by apps and libraries that target that platform.
Portable class libraries have access to a subset of APIs, and can be used by apps and libraries that target
multiple platforms.
.NET Core class libraries are a merger of the platform-specific and portable library concept into a single model
that provides the best of both.
Want to make your libraries multi-platform? Want to see how much work is required to make your application
compatible with other .NET implementations? The .NET Portability Analyzer is a tool that provides you with a
detailed report on how flexible your program is across .NET implementations by analyzing assemblies. The
Portability Analyzer is offered as a Visual Studio Extension and as a console app.
New targets
.NET Core: Has a modular design, employs side-by-side, and targets cross-platform scenarios. Side-by-side
allows you to adopt new .NET Core versions without breaking other apps.
ASP.NET Core: is a modern web-framework built on .NET Core thus giving developers the same benefits.
Universal Windows Platform: Improve performance of your Windows Store apps that run on x64 and ARM
machines by using .NET Native’s static compilation.
.NET Core + Platform Extensions: Includes the .NET Core APIs in addition to other APIs in the .NET ecosystem
such as WCF, ASP.NET Core, FSharp, and Azure.
.NET Standard + Platform Extensions: Includes the .NET Standard APIs in addition to other .NET ecosystem such
as WCF, ASP.NET Core, FSharp, and Azure.
After running the analysis, you will see your .NET Portability Report. Only types that are unsupported by a target
platform appear in the list and you can review recommendations in the Messages tab in the Error List. You can
also jump to problem areas directly from the Messages tab.
Don’t want to use Visual Studio? You can also use the Portability Analyzer from the command prompt. Just
download the API Portability Analyzer.
Type the following command to analyze the current directory: \...\ApiPort.exe analyze -f .
To analyze a specific list of .dll files, type the following command:
\...\ApiPort.exe analyze -f first.dll -f second.dll -f third.dll
Your .NET Portability Report is saved as an Excel file (.xlsx) in your current directory. The Details tab in the Excel
Workbook contains more information.
For more information on the .NET Portability Analyzer, visit the GitHub documentation and A Brief Look at the .NET
Portability Analyzer Channel 9 video.
Handling and throwing exceptions in .NET
7/29/2017 • 2 min to read • Edit Online
Applications must be able to handle errors that occur during execution in a consistent manner. .NET provides a
model for notifying applications of errors in a uniform way: .NET operations indicate failure by throwing exceptions.
Exceptions
An exception is any error condition or unexpected behavior that is encountered by an executing program.
Exceptions can be thrown because of a fault in your code or in code that you call (such as a shared library),
unavailable operating system resources, unexpected conditions that the runtime encounters (such as code that
cannot be verified), and so on. Your application can recover from some of these conditions, but not from others.
Although you can recover from most application exceptions, you cannot recover from most runtime exceptions.
In .NET, an exception is an object that inherits from the System.Exception class. An exception is thrown from an area
of code where a problem has occurred. The exception is passed up the stack until the application handles it or the
program terminates.
Common Exceptions
The following table lists some common exceptions with examples of what can cause them.
Exception Object Base class for all exceptions. None (use a derived class of
this exception).
IndexOutOfRangeException Exception Thrown by the runtime only Indexing an array outside its
when an array is indexed valid range:
improperly. arr[arr.Length+1]
EXCEPTION TYPE BASE TYPE DESCRIPTION EXAMPLE
ArgumentException Exception Base class for all argument None (use a derived class of
exceptions. this exception).
See Also
Exception Class and Properties
How to: Use the Try-Catch Block to Catch Exceptions
How to: Use Specific Exceptions in a Catch Block
How to: Explicitly Throw Exceptions
How to: Create User-Defined Exceptions
Using User-Filtered Exception Handlers
How to: Use Finally Blocks
Handling COM Interop Exceptions
Best Practices for Exceptions
To learn more about how exceptions work in .NET, see What Every Dev needs to Know About Exceptions in the
Runtime.
.NET Assembly File Format
8/10/2017 • 2 min to read • Edit Online
.NET defines a binary file format - "assembly" - that is used to fully-describe and contain .NET programs.
Assemblies are used for the programs themselves as well as any dependent libraries. A .NET program can be
executed as one of more assemblies, with no other required artifacts, beyond the appropriate .NET implementation.
Native dependencies, including operating system APIs, are a separate concern and are not contained within the
.NET assembly format, although are sometimes described with this format (for example, WinRT).
Each CLI component carries the metadata for declarations, implementations, and references specific to that
component. Therefore, the component-specific metadata is referred to as component metadata, and the
resulting component is said to be self-describing – from ECMA 335 I.9.1, Components and assemblies.
The format is fully specified and standardized as ECMA 335. All .NET compilers and runtimes use this format. The
presence of a documented and infrequently updated binary format has been a major benefit (arguably a
requirement) for interoperatibility. The format was last updated in a substantive way in 2005 (.NET 2.0) to
accommodate generics and processor architecture.
The format is CPU- and OS-agnostic. It has been used as part of .NET implementations that target many chips and
CPUs. While the format itself has Windows heritage, it is implementable on any operating system. It’s arguably
most significant choice for OS interoperability is that most values are stored in little-endian format. It doesn’t have
a specific affinity to machine pointer size (for example, 32-bit, 64-bit).
The .NET assembly format is also very descriptive about the structure of a given program or library. It describes the
internal components of an assembly, specifically: assembly references and types defined and their internal
structure. Tools or APIs can read and process this information for display or to make programmatic decisions.
Format
The .NET binary format is based on the Windows PE file format. In fact, .NET class libraries are conformant
Windows PEs, and appear on first glance to be Windows dynamic link libraries (DLLs) or application executables
(EXEs). This is a very useful characteristic on Windows, where they can masquerade as native executable binaries
and get some of the same treatment (for example, OS load, PE tools).
Assembly Headers from ECMA 335 II.25.1, Structure of the runtime file format.
This section of the documentation provides information about managing memory in .NET.
In This Section
Cleaning Up Unmanaged Resources
Describes how to properly manage and clean up unmanaged resources..
Garbage Collection
Provides information about the .NET garbage collector.
Related Sections
Development Guide
Generic Types (Generics) Overview
8/10/2017 • 3 min to read • Edit Online
We use generics all the time in C#, whether implicitly or explicitly. When you use LINQ in C#, did you ever notice
that you are working with IEnumerable? Or if you ever saw an online sample of a "generic repository" for talking to
databases using Entity Framework, did you see that most methods return IQueryable? You may have wondered
what the T is in these examples and why is it in there?
First introduced to the .NET Framework 2.0, generics involved changes to both the C# language and the Common
Language Runtime (CLR). Generics are essentially a "code template" that allows developers to define type-safe
data structures without committing to an actual data type. For example, List<T> is a Generic Collection that can be
declared and used with any type: List<int> , List<string> , List<Person> , etc.
So, what’s the point? Why are generics useful? In order to understand this, we need to take a look at a specific class
before and after adding generics. Let’s look at the ArrayList . In C# 1.0, the ArrayList elements were of type
object . This meant that any element that was added was silently converted into an object ; same thing happens
on reading the elements from the list (this process is known as boxing and unboxing respectively). Boxing and
unboxing have an impact of performance. More than that, however, there is no way to tell at compile time what is
the actual type of the data in the list. This makes for some fragile code. Generics solve this problem by providing
additional information the type of data each instance of list will contain. Put simply, you can only add integers to
List<int> and only add Persons to List<Person> , etc.
Generics are also available at runtime, or reified. This means the runtime knows what type of data structure you
are using and can store it in memory more efficiently.
Here is a small program that illustrates the efficiency of knowing the data structure type at runtime:
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
namespace GenericsExample {
class Program {
static void Main(string[] args) {
//generic list
List<int> ListGeneric = new List<int> { 5, 9, 1, 4 };
//non-generic list
ArrayList ListNonGeneric = new ArrayList { 5, 9, 1, 4 };
// timer for generic list sort
Stopwatch s = Stopwatch.StartNew();
ListGeneric.Sort();
s.Stop();
Console.WriteLine($"Generic Sort: {ListGeneric} \n Time taken: {s.Elapsed.TotalMilliseconds}ms");
The first thing you notice here is that sorting the generic list is significantly faster than for the non-generic list. You
might also notice that the type for the generic list is distinct ([System.Int32]) whereas the type for the non-generic
list is generalized. Because the runtime knows the generic List<int> is of type int, it can store the list elements in
an underlying integer array in memory while the non-generic ArrayList has to cast each list element as an object
as stored in an object array in memory. As shown through this example, the extra castings take up time and slow
down the list sort.
The last useful thing about the runtime knowing the type of your generic is a better debugging experience. When
you are debugging a generic in C#, you know what type each element is in your data structure. Without generics,
you would have no idea what type each element was.
Delegates define a type, which specify a particular method signature. A method (static or instance) that satisfies this
signature can be assigned to a variable of that type, then called directly (with the appropriate arguments) or passed
as an argument itself to another method and then called. The following example demonstrates delegate use.
Console.WriteLine(rev("a string"));
}
}
On line 4 we create a delegate type of a certain signature, in this case a method that takes a string parameter
and then returns a string parameter.
On line 6, we define the implementation of the delegate by providing a method that has the exact same
signature.
On line 13, the method is assigned to a type that conforms to the Reverse delegate.
Finally, on line 15 we invoke the delegate passing a string to be reversed.
In order to streamline the development process, .NET includes a set of delegate types that programmers can reuse
and not have to create new types. These are Func<> , Action<> and Predicate<> , and they can be used in various
places throughout the .NET APIs without the need to define new delegate types. Of course, there are some
differences between the three as you will see in their signatures which mostly have to do with the way they were
meant to be used:
Action<> is used when there is a need to perform an action using the arguments of the delegate.
Func<> is used usually when you have a transformation on hand, that is, you need to transform the arguments
of the delegate into a different result. Projections are a prime example of this.
Predicate<> is used when you need to determine if the argument satisfies the condition of the delegate. It can
also be written as a Func<T, bool> .
We can now take our example above and rewrite it using the Func<> delegate instead of a custom type. The
program will continue running exactly the same.
public class Program
{
Console.WriteLine(rev("a string"));
}
}
For this simple example, having a method defined outside of the Main() method seems a bit superfluous. It is
because of this that .NET Framework 2.0 introduced the concept of anonymous delegates. With their support you
are able to create "inline" delegates without having to specify any additional type or method. You simply inline the
definition of the delegate where you need it.
For an example, we are going to switch it up and use our anonymous delegate to filter out a list of only even
numbers and then print them to the console.
Notice the highlighted lines. As you can see, the body of the delegate is just a set of expressions, as any other
delegate. But instead of it being a separate definition, we’ve introduced it ad hoc in our call to the FindAll()
method of the List<T> type.
However, even with this approach, there is still much code that we can throw away. This is where lambda
expressions come into play.
Lambda expressions, or just "lambdas" for short, were introduced first in C# 3.0, as one of the core building blocks
of Language Integrated Query (LINQ). They are just a more convenient syntax for using delegates. They declare a
signature and a method body, but don’t have an formal identity of their own, unless they are assigned to a
delegate. Unlike delegates, they can be directly assigned as the left-hand side of event registration or in various
Linq clauses and methods.
Since a lambda expression is just another way of specifying a delegate, we should be able to rewrite the above
sample to use a lambda expression instead of an anonymous delegate.
If you take a look at the highlighted lines, you can see how a lambda expression looks like. Again, it is just a very
convenient syntax for using delegates, so what happens under the covers is similar to what happens with the
anonymous delegate.
Again, lambdas are just delegates, which means that they can be used as an event handler without any problems,
as the following code snippet illustrates.
public MainWindow()
{
InitializeComponent();
What is it?
LINQ provides language-level querying capabilities and a higher-order function API to C# and VB as a way to write
expressive, declarative code.
Language-level query syntax:
LINQ is Expressive
Imagine you have a list of pets, but want to convert it into a dictionary where you can access a pet directly by its
RFID value.
The intention behind the code is not to create a new Dictionary<int, Pet> and add to it via a loop, it is to convert
an existing list into a dictionary! LINQ preserves the intention whereas the imperative code does not.
Equivalent LINQ expression:
The code using LINQ is valuable because it evens the playing field between intent and code when reasoning as a
programmer. Another bonus is code brevity. Imagine reducing large portions of a codebase by 1/3 as done above.
Pretty sweet deal, right?
Writing code to manually traverse the XML document to perform this task would be far more challenging.
Interacting with XML isn’t the only thing you can do with LINQ Providers. Linq to SQL is a fairly bare-bones Object-
Relational Mapper (ORM) for an MSSQL Server Database. The JSON.NET library provides efficient JSON Document
traversal via LINQ. Furthermore, if there isn’t a library which does what you need, you can also write your own
LINQ Provider!
Isn’t the API syntax just a more concise way to do the query syntax?
No. The query syntax allows for the use the let clause, which allows you to introduce and bind a variable within the
scope of the expression, using it in subsequent pieces of the expression. Reproducing the same code with only the
API syntax can be done, but will most likely lead to code which is hard to read.
So this begs the question, should you just use the query syntax?
The answer to this question is yes if...
Your existing codebase already uses the query syntax
You need to scope variables within your queries due to complexity
You prefer the query syntax and it won’t distract from your codebase
The answer to this question is no if...
Your existing codebase already uses the API syntax
You have no need to scope variables within your queries
You prefer the API syntax and it won’t distract from your codebase
Essential Samples
For a truly comprehensive list of LINQ samples, visit 101 LINQ Samples.
The following is a quick demonstration of some of the essential pieces of LINQ. This is in no way comprehensive, as
LINQ provides significantly more functionality than what is showcased here.
The bread and butter - Where , Select , and Aggregate :
// Filtering a list
var germanShepards = dogs.Where(dog => dog.Breed == DogBreed.GermanShepard);
...
Ordering:
// Get driving directions, ordering by if it's toll-free before estimated driving time.
var results = DirectionsProcessor.GetDirections(start, end)
.OrderBy(direction => direction.HasNoTolls)
.ThenBy(direction => direction.EstimatedTime);
Finally, a more advanced sample: determining if the values of the properties of two instances of the same type
are equal (Borrowed and modified from this StackOverflow post):
public static bool PublicInstancePropertiesEqual<T>(this T self, T to, params string[] ignore) where T : class
{
if (self != null && to != null)
{
var type = typeof(T);
var ignoreList = new List<string>(ignore);
// Selects the properties which have unequal values into a sequence of those properties.
var unequalProperties = from pi in type.GetProperties(BindingFlags.Public | BindingFlags.Instance)
where !ignoreList.Contains(pi.Name)
let selfValue = type.GetProperty(pi.Name).GetValue(self, null)
let toValue = type.GetProperty(pi.Name).GetValue(to, null)
where selfValue != toValue && (selfValue == null ||
!selfValue.Equals(toValue))
select new { Prop = pi.Name, selfValue, toValue };
return !unequalProperties.Any();
}
PLINQ
PLINQ, or Parallel LINQ, is a parallel execution engine for LINQ expressions. In other words, a regular LINQ
expressions can be trivially parallelized across any number of threads. This is accomplished via a call to
AsParallel() preceding the expression.
return facebookUsers.AsParallel()
.Aggregate(seed, threadAccumulator, threadResultAccumulator, resultSelector);
}
This code will partition facebookUsers across system threads as necessary, sum up the total likes on each thread in
parallel, sum the results computed by each thread, and project that result into a nice string.
In diagram form:
Parallelizable CPU-bound jobs which can be easily expressed via LINQ (in other words, are pure functions and have
no side effects) are a great candidate for PLINQ. For jobs which do have a side effect, consider using the Task
Parallel Library.
Further Resources:
101 LINQ Samples
Linqpad, a playground environment and Database querying engine for C#/F#/VB
EduLinq, an e-book for learning how LINQ-to-objects is implemented
Common Type System & Common Language
Specification
8/5/2017 • 2 min to read • Edit Online
Again, two terms that are freely used in the .NET world, they actually are crucial to understand how a .NET
implementation enables multi-language development and to understand how it works.
CTS defines two main kinds of types that should be supported: reference and value types. Their names point to
their definitions.
Reference types’ objects are represented by a reference to the object’s actual value; a reference here is similar to a
pointer in C/C++. It simply refers to a memory location where the objects’ values are. This has a profound impact
on how these types are used. If you assign a reference type to a variable and then pass that variable into a method,
for instance, any changes to the object will be reflected on the main object; there is no copying.
Value types are the opposite, where the objects are represented by their values. If you assign a value type to a
variable, you are essentially copying a value of the object.
CTS defines several categories of types, each with their specific semantics and usage:
Classes
Structures
Enums
Interfaces
Delegates
CTS also defines all other properties of the types, such as access modifiers, what are valid type members, how
inheritance and overloading works and so on. Unfortunately, going deep into any of those is beyond the scope of
an introductory article such as this, but you can consult More resources section at the end for links to more in-
depth content that covers these topics.
More resources
Common Type System
Common Language Specification
Async Overview
7/29/2017 • 1 min to read • Edit Online
Not so long ago, apps got faster simply by buying a newer PC or server and then that trend stopped. In fact, it
reversed. Mobile phones appeared with 1ghz single core ARM chips and server workloads transitioned to VMs.
Users still want responsive UI and business owners want servers that scale with their business. The transition to
mobile and cloud and an internet-connected population of >3B users has resulted in a new set of software
patterns.
Client applications are expected to be always-on, always-connected and constantly responsive to user
interaction (for example, touch) with high app store ratings!
Services are expected to handle spikes in traffic by gracefully scaling up and down.
Async programming is a key technique that makes it straightforward to handle blocking I/O and concurrent
operations on multiple cores. .NET provides the capability for apps and services to be responsive and elastic with
easy-to-use, language-level asynchronous programming models in C#, VB, and F#.
What's next?
For a deep dive into async concepts and programming, see Async in depth and Task-based asynchronous
programming.
Async in depth
8/29/2017 • 9 min to read • Edit Online
Writing I/O- and CPU-bound asynchronous code is straightforward using the .NET Task-based async model. The
model is exposed by the Task and Task<T> types and the async and await keywords in C# and Visual Basic.
(Language-specific resources are found in the See also section.) This article explains how to use .NET async and
provides insight into the async framework used under the covers.
return client.GetStringAsync("http://www.dotnetfoundation.org");
}
The second example adds the use of the async and await keywords to operate on the task.
public async Task<string> GetFirstCharactersCountAsync(string url, int count)
{
// Execution is synchronous here
var client = new HttpClient();
The call to GetStringAsync() calls through lower-level .NET libraries (perhaps calling other async methods) until it
reaches a P/Invoke interop call into a native networking library. The native library may subsequently call into a
System API call (such as write() to a socket on Linux). A task object will be created at the native/managed
boundary, possibly using TaskCompletionSource. The task object will be passed up through the layers, possibly
operated on or directly returned, eventually returned to the initial caller.
In the second example above, a Task<T> object will be returned from GetStringAsync . The use of the await
keyword causes the method to return a newly created task object. Control returns to the caller from this location in
the GetFirstCharactersCountAsync method. The methods and properties of the Task<T> object enable callers to
monitor the progress of the task, which will complete when the remaining code in GetFirstCharactersCountAsync
has executed.
After the System API call, the request is now in kernel space, making its way to the networking subsystem of the
OS (such as /net in the Linux Kernel). Here the OS will handle the networking request asynchronously. Details
may be different depending on the OS used (the device driver call may be scheduled as a signal sent back to the
runtime, or a device driver call may be made and then a signal sent back), but eventually the runtime will be
informed that the networking request is in progress. At this time, the work for the device driver will either be
scheduled, in-progress, or already finished (the request is already out "over the wire") - but because this is all
happening asynchronously, the device driver is able to immediately handle something else!
For example, in Windows an OS thread makes a call to the network device driver and asks it to perform the
networking operation via an Interrupt Request Packet (IRP) which represents the operation. The device driver
receives the IRP, makes the call to the network, marks the IRP as "pending", and returns back to the OS. Because
the OS thread now knows that the IRP is "pending", it doesn't have any more work to do for this job and "returns"
back so that it can be used to perform other work.
When the request is fulfilled and data comes back through the device driver, it notifies the CPU of new data
received via an interrupt. How this interrupt gets handled will vary depending on the OS, but eventually the data
will be passed through the OS until it reaches a system interop call (for example, in Linux an interrupt handler will
schedule the bottom half of the IRQ to pass the data up through the OS asynchronously). Note that this also
happens asynchronously! The result is queued up until the next available thread is able execute the async method
and "unwrap" the result of the completed task.
Throughout this entire process, a key takeaway is that no thread is dedicated to running the task. Although
work is executed in some context (that is, the OS does have to pass data to a device driver and respond to an
interrupt), there is no thread dedicated to waiting for data from the request to come back. This allows the system
to handle a much larger volume of work rather than waiting for some I/O call to finish.
Although the above may seem like a lot of work to be done, when measured in terms of wall clock time, it’s
miniscule compared to the time it takes to do the actual I/O work. Although not at all precise, a potential timeline
for such a call would look like this:
0-1
————————————————————————————————————————————————–2-
3
Time spent from points 0 to 1 is everything up until an async method yields control to its caller.
Time spent from points 1 to 2 is the time spent on I/O, with no CPU cost.
Finally, time spent from points 2 to 3 is passing control back (and potentially a value) to the async method, at
which point it is executing again.
What does this mean for a server scenario?
This model works well with a typical server scenario workload. Because there are no threads dedicated to blocking
on unfinished tasks, the server threadpool can service a much higher volume of web requests.
Consider two servers: one that runs async code, and one that does not. For the purpose of this example, each
server only has 5 threads available to service requests. Note that these numbers are imaginarily small and serve
only in a demonstrative context.
Assume both servers receive 6 concurrent requests. Each request performs an I/O operation. The server without
async code has to queue up the 6th request until one of the 5 threads have finished the I/O-bound work and
written a response. At the point that the 20th request comes in, the server might start to slow down, because the
queue is getting too long.
The server with async code running on it still queues up the 6th request, but because it uses async and await ,
each of its threads are freed up when the I/O-bound work starts, rather than when it finishes. By the time the 20th
request comes in, the queue for incoming requests will be far smaller (if it has anything in it at all), and the server
won't slow down.
Although this is a contrived example, it works in a very similar fashion in the real world. In fact, you can expect a
server to be able to handle an order of magnitude more requests using async and await than if it were
dedicating a thread for each request it receives.
What does this mean for client scenario?
The biggest gain for using async and await for a client app is an increase in responsiveness. Although you can
make an app responsive by spawning threads manually, the act of spawning a thread is an expensive operation
relative to just using async and await . Especially for something like a mobile game, impacting the UI thread as
little as possible where I/O is concerned is crucial.
More importantly, because I/O-bound work spends virtually no time on the CPU, dedicating an entire CPU thread
to perform barely any useful work would be a poor use of resources.
Additionally, dispatching work to the UI thread (such as updating a UI) is very simple with async methods, and
does not require extra work (such as calling a thread-safe delegate).
// Note that at this point, you can do some other work concurrently,
// as CalculateResult() is still executing!
return result;
}
CalculateResult() executes on the thread it was called on. When it calls Task.Run , it queues the expensive CPU-
bound operation, DoExpensiveCalculation() , on the thread pool and receives a Task<int> handle.
DoExpensiveCalculation() is eventually run concurrently on the next available thread, likely on another CPU core.
It's possible to do concurrent work while DoExpensiveCalculation() is busy on another thread, because the thread
which called CalculateResult() is still executing.
Once await is encountered, the execution of CalculateResult() is yielded to its caller, allowing other work to be
done with the current thread while DoExpensiveCalculation() is churning out a result. Once it has finished, the
result is queued up to run on the main thread. Eventually, the main thread will return to executing
CalculateResult() , at which point it will have the result of DoExpensiveCalculation() .
See also
Asynchronous programming in C#
Async Programming in F#
Asynchronous Programming with Async and Await (Visual Basic)
Asynchronous Programming Patterns
7/29/2017 • 2 min to read • Edit Online
The .NET Framework provides three patterns for performing asynchronous operations:
Asynchronous Programming Model (APM) pattern (also called the IAsyncResult pattern), where
asynchronous operations require Begin and End methods (for example, BeginWrite and EndWrite for
asynchronous write operations). This pattern is no longer recommended for new development. For more
information, see Asynchronous Programming Model (APM).
Event-based Asynchronous Pattern (EAP), which requires a method that has the Async suffix, and also
requires one or more events, event handler delegate types, and EventArg -derived types. EAP was
introduced in the .NET Framework 2.0. It is no longer recommended for new development. For more
information, see Event-based Asynchronous Pattern (EAP).
Task-based Asynchronous Pattern (TAP), which uses a single method to represent the initiation and
completion of an asynchronous operation. TAP was introduced in the .NET Framework 4 and is the
recommended approach to asynchronous programming in the .NET Framework. The async and await
keywords in C# and the Async and Await operators in Visual Basic Language add language support for TAP.
For more information, see Task-based Asynchronous Pattern (TAP).
Comparing Patterns
For a quick comparison of how the three patterns model asynchronous operations, consider a Read method that
reads a specified amount of data into a provided buffer starting at a specified offset:
The APM counterpart of this method would expose the BeginRead and EndRead methods:
The EAP counterpart would expose the following set of types and members:
The TAP counterpart would expose the following single ReadAsync method:
public class MyClass
{
public Task<int> ReadAsync(byte [] buffer, int offset, int count);
}
For a comprehensive discussion of TAP, APM, and EAP, see the links provided in the next section.
Related topics
TITLE DESCRIPTION
Asynchronous Programming Model (APM) Describes the legacy model that uses the IAsyncResult
interface to provide asynchronous behavior. This model is no
longer recommended for new development.
Event-based Asynchronous Pattern (EAP) Describes the event-based legacy model for providing
asynchronous behavior. This model is no longer recommended
for new development.
Task-based Asynchronous Pattern (TAP) Describes the new asynchronous pattern based on the
System.Threading.Tasks namespace. This model is the
recommended approach to asynchronous programming in the
.NET Framework 4 and later versions.
See also
Asynchronous programming in C#
Async Programming in F#
Asynchronous Programming with Async and Await (Visual Basic)
Native Interoperability
8/5/2017 • 10 min to read • Edit Online
In this document, we will dive a little bit deeper into all three ways of doing "native interoperability" that are
available using .NET.
There are a few of reasons why you would want to call into native code:
Operating Systems come with a large volume of APIs that are not present in the managed class libraries. A
prime example for this would be access to hardware or operating system management functions.
Communicating with other components that have or can produce C-style ABIs (native ABIs). This covers, for
example, Java code that is exposed via Java Native Interface (JNI) or any other managed language that could
produce a native component.
On Windows, most of the software that gets installed, such as Microsoft Office suite, registers COM
components that represent their programs and allow developers to automate them or use them. This also
requires native interoperability.
Of course, the list above does not cover all of the potential situations and scenarios in which the developer would
want/like/need to interface with native components. .NET class library, for instance, uses the native interoperability
support to implement a fair number of its APIs, like console support and manipulation, file system access and
others. However, it is important to note that there is an option, should one need it.
NOTE
Most of the examples in this document will be presented for all three supported platforms for .NET Core (Windows, Linux
and macOS). However, for some short and illustrative examples, just one sample is shown that uses Windows filenames and
extensions (that is, "dll" for libraries). This does not mean that those features are not available on Linux or macOS, it was
done merely for convenience sake.
The example above is pretty simple, but it does show off what is needed to invoke unmanaged functions from
managed code. Let’s step through the example:
Line #1 shows the using statement for the System.Runtime.InteropServices which is the namespace that holds
all of the items we need.
Line #5 introduces the DllImport attribute. This attribute is crucial, as it tells the runtime that it should load the
unmanaged DLL. This is the DLL into which we wish to invoke.
Line #6 is the crux of the P/Invoke work. It defines a managed method that has the exact same signature as
the unmanaged one. The declaration has a new keyword that you can notice, extern , which tells the runtime
this is an external method, and that when you invoke it, the runtime should find it in the DLL specified in
DllImport attribute.
The rest of the example is just invoking the method as you would any other managed method.
The sample is similar for macOS. One thing that needs to change is, of course, the name of the library in the
DllImport attribute, as macOS has a different scheme of naming dynamic libraries. The sample below uses the
getpid(2) function to get the process ID of the application and print it out to the console.
using System;
using System.Runtime.InteropServices;
namespace PInvokeSamples {
public static class Program {
// Import the libc and define the method corresponding to the native function.
[DllImport("libSystem.dylib")]
private static extern int getpid();
It is similar on Linux, of course. The function name is same, since getpid(2) is POSIX system call.
using System;
using System.Runtime.InteropServices;
namespace PInvokeSamples {
public static class Program {
// Import the libc and define the method corresponding to the native function.
[DllImport("libc.so.6")]
private static extern int getpid();
using System;
using System.Runtime.InteropServices;
namespace ConsoleApplication1 {
class Program {
// Define the implementation of the delegate; here, we simply output the window handle.
static bool OutputWindow(IntPtr hwnd, IntPtr lParam) {
Console.WriteLine(hwnd.ToInt64());
return true;
}
Before we walk through our example, it is good to go over the signatures of the unmanaged functions we need to
work with. The function we want to call to enumerate all of the windows has the following signature:
BOOL EnumWindows (WNDENUMPROC lpEnumFunc, LPARAM lParam);
The first parameter is a callback. The said callback has the following signature:
BOOL CALLBACK EnumWindowsProc (HWND hwnd, LPARAM lParam);
With this in mind, let’s walk through the example:
Line #8 in the example defines a delegate that matches the signature of the callback from unmanaged code.
Notice how the LPARAM and HWND types are represented using IntPtr in the managed code.
Lines #10 and #11 introduce the EnumWindows function from the user32.dll library.
Lines #13 - 16 implement the delegate. For this simple example, we just want to output the handle to the
console.
Finally, in line #19 we invoke the external method and pass in the delegate.
The Linux and macOS examples are shown below. For them, we use the ftw function that can be found in libc ,
the C library. This function is used to traverse directory hierarchies and it takes a pointer to a function as one of its
parameters. The said function has the following signature:
int (*fn) (const char *fpath, const struct stat *sb, int typeflag) .
using System;
using System.Runtime.InteropServices;
namespace PInvokeSamples {
public static class Program {
// Define a delegate that has the same signature as the native function.
delegate int DirClbk(string fName, StatClass stat, int typeFlag);
// Import the libc and define the method to represent the native function.
[DllImport("libc.so.6")]
static extern int ftw(string dirpath, DirClbk cl, int descriptors);
macOS example uses the same function, and the only difference is the argument to the DllImport attribute, as
macOS keeps libc in a different place.
using System;
using System.Runtime.InteropServices;
namespace PInvokeSamples {
public static class Program {
// Define a delegate that has the same signature as the native function.
delegate int DirClbk(string fName, StatClass stat, int typeFlag);
// Import the libc and define the method to represent the native function.
[DllImport("libSystem.dylib")]
static extern int ftw(string dirpath, DirClbk cl, int descriptors);
Both of the above examples depend on parameters, and in both cases, the parameters are given as managed types.
Runtime does the "right thing" and processes these into its equivalents on the other side. Since this process is
really important to writing quality native interop code, let’s take a look at what happens when the runtime
marshals the types.
Type marshalling
Marshalling is the process of transforming types when they need to cross the managed boundary into native and
vice versa.
The reason marshalling is needed is because the types in the managed and unmanaged code are different. In
managed code, for instance, you have a String , while in the unmanaged world strings can be Unicode ("wide"),
non-Unicode, null-terminated, ASCII, etc. By default, the P/Invoke subsystem will try to do the Right Thing based on
the default behavior which you can see on MSDN. However, for those situations where you need extra control, you
can employ the MarshalAs attribute to specify what is the expected type on the unmanaged side. For instance, if
we want the string to be sent as a null-terminated ANSI string, we could do it like this:
[DllImport("somenativelibrary.dll")]
static extern int MethodA([MarshalAs(UnmanagedType.LPStr)] string parameter);
[DllImport("kernel32.dll")]
static extern void GetSystemTime(SystemTime systemTime);
[StructLayout(LayoutKind.Sequential)]
class SystemTime {
public ushort Year;
public ushort Month;
public ushort DayOfWeek;
public ushort Day;
public ushort Hour;
public ushort Minute;
public ushort Second;
public ushort Milsecond;
}
The example above shows off a simple example of calling into GetSystemTime() function. The interesting bit is on
line 4. The attribute specifies that the fields of the class should be mapped sequentially to the struct on the other
(unmanaged) side. This means that the naming of the fields is not important, only their order is important, as it
needs to correspond to the unmanaged struct, shown below:
We already saw the Linux and macOS example for this in the previous example. It is shown again below.
[StructLayout(LayoutKind.Sequential)]
public class StatClass {
public uint DeviceID;
public uint InodeNumber;
public uint Mode;
public uint HardLinks;
public uint UserID;
public uint GroupID;
public uint SpecialDeviceID;
public ulong Size;
public ulong BlockSize;
public uint Blocks;
public long TimeLastAccess;
public long TimeLastModification;
public long TimeLastStatusChange;
}
The StatClass class represents a structure that is returned by the stat system call on UNIX systems. It represents
information about a given file. The class above is the stat struct representation in managed code. Again, the fields
in the class have to be in the same order as the native struct (you can find these by perusing man pages on your
favorite UNIX implementation) and they have to be of the same underlying type.
More resources
PInvoke.net wiki an excellent Wiki with information on common Win32 APIs and how to call them.
P/Invoke on MSDN
Mono documentation on P/Invoke
Collections and Data Structures
7/29/2017 • 5 min to read • Edit Online
Similar data can often be handled more efficiently when stored and manipulated as a collection. You can use the
System.Array class or the classes in the System.Collections, System.Collections.Generic,
System.Collections.Concurrent, System.Collections.Immutable namespaces to add, remove, and modify either
individual elements or a range of elements in a collection.
There are two main types of collections; generic collections and non-generic collections. Generic collections were
added in the .NET Framework 2.0 and provide collections that are type-safe at compile time. Because of this,
generic collections typically offer better performance. Generic collections accept a type parameter when they are
constructed and do not require that you cast to and from the Object type when you add or remove items from the
collection. In addition, most generic collections are supported in Windows Store apps. Non-generic collections
store items as Object, require casting, and most are not supported for Windows Store app development. However,
you may see non-generic collections in older code.
Starting with the .NET Framework 4, the collections in the System.Collections.Concurrent namespace provide
efficient thread-safe operations for accessing collection items from multiple threads. The immutable collection
classes in the System.Collections.Immutable namespace (NuGet package) are inherently thread-safe because
operations are performed on a copy of the original collection and the original collection cannot be modified.
Choosing a collection
In general, you should use generic collections. The following table describes some common collection scenarios
and the collection classes you can use for those scenarios. If you are new to generic collections, this table will help
you choose the generic collection that works the best for your task.
ImmutableDictionary(TKey,
TValue) Class
ImmutableQueue(T) Class
ImmutableStack(T) Class
GENERIC COLLECTION NON-GENERIC COLLECTION THREAD-SAFE OR IMMUTABLE
I WANT TO… OPTION(S) OPTION(S) COLLECTION OPTION(S)
ImmutableSortedSet(T)
Class
System.Collections.Generic.S ImmutableSortedSet(T)
Class
ortedSet<T>
Related Topics
TITLE DESCRIPTION
Selecting a Collection Class Describes the different collections and helps you select one for
your scenario.
Commonly Used Collection Types Describes commonly used generic and nongeneric collection
types such as System.Array,
System.Collections.Generic.List<T>, and
System.Collections.Generic.Dictionary<TKey,TValue>.
When to Use Generic Collections Discusses the use of generic collection types.
Comparisons and Sorts Within Collections Discusses the use of equality comparisons and sorting
comparisons in collections.
Hashtable and Dictionary Collection Types Describes the features of generic and non-generic hash-based
dictionary types.
The .NET Framework supports the standard numeric integral and floating-point primitives, as well as BigInteger, an
integral type with no theoretical upper or lower bound, Complex, a type that represents complex numbers, and a
set of SIMD-enabled vector types in the System.Numerics namespace.
In addition, System.Numerics.Vectors, the SIMD-enabled library of vectory types, was released as a NuGet package.
Integral types
The .NET Framework supports both signed and unsigned integers ranging from one byte to eight bytes in length.
The following table lists the integral types and their size, indicates whether they are signed or unsigned, and
documents their range. All integers are value types.
Each integral type supports a standard set of arithmetic, comparison, equality, explicit conversion, and implicit
conversion operators. Each integer also includes methods to perform equality comparisons and relative
comparisons, to convert the string representation of a number to that integer, and to convert an integer to its string
representation. Some additional mathematical operations beyond those handled by the standard operators, such as
rounding and identifying the smaller or larger value of two integers, are available from the Math class. You can also
work with the individual bits in an integer value by using the BitConverter class.
Note that the unsigned integral types are not CLS-compliant. For more information, see Language Independence
and Language-Independent Components.
Floating-point types
The .NET Framework includes three primitive floating point types, which are listed in the following table.
TYPE SIZE (IN BYTES) MINIMUM MAXIMUM
System.Decimal 16 - 79,228,162,514,264,337,593
79,228,162,514,264,337,59 ,543,950,335
3,543,950,335
Each floating-point type supports a standard set of arithmetic, comparison, equality, explicit conversion, and
implicit conversion operators. Each also includes methods to perform equality comparisons and relative
comparisons, to convert the string representation of a floating-point number, and to convert a floating-point
number to its string representation. Some additional mathematical, algebraic, and trigonometric operations are
available from the Math class. You can also work with the individual bits in Double and Single values by using the
BitConverter class. The System.Decimal structure has its own methods, System.Decimal.GetBits and
System.Decimal.Decimal(Int32[]), for working with a decimal value's individual bits, as well as its own set of
methods for performing some additional mathematical operations.
The Double and Single types are intended to be used for values that by their nature are imprecise (such as the
distance between two stars in the solar system) and for applications in which a high degree of precision and small
rounding error is not required. You should use the System.Decimal type for cases in which greater precision is
required and rounding error is undesirable,
BigInteger
System.Numerics.BigInteger is an immutable type that represents an arbitrarily large integer whose value in theory
has no upper or lower bounds. The methods of the BigInteger type closely parallel those of the other integral types.
Complex
The Complex type represents a complex number, that is, a number with a real number part and an imaginary
number part. It supports a standard set of arithmetic, comparison, equality, explicit conversion, and implicit
conversion operators, as well as mathematical, algebraic, and trigonometric methods.
See Also
Application Essentials
Dates, times, and time zones
7/29/2017 • 2 min to read • Edit Online
In addition to the basic DateTime structure, .NET provides the following classes that support working with time
zones:
TimeZone
Use this class to work with the system's local time zone and the Coordinated Universal Time (UTC) zone.The
functionality of the TimeZone class is largely superseded by the TimeZoneInfo class.
TimeZoneInfo
Use this class to work with any time zone that is predefined on a system, to create new time zones, and to
easily convert dates and times from one time zone to another. For new development, use the TimeZoneInfo
class instead of the TimeZone class.
DateTimeOffset
Use this structure to work with dates and times whose offset (or difference) from UTC is known. The
DateTimeOffset structure combines a date and time value with that time's offset from UTC. Because of its
relationship to UTC, an individual date and time value unambiguously identifies a single point in time. This
makes a DateTimeOffset value more portable from one computer to another than a DateTime value.
This section of the documentation provides the information that you need to work with time zones and to create
time zone-aware applications that can convert dates and times from one time zone to another.
In this section
Time zone overview Discusses the terminology, concepts, and issues involved in creating time zone-aware
applications.
Choosing between DateTime, DateTimeOffset, TimeSpan, and TimeZoneInfo Discusses when to use the DateTime,
DateTimeOffset, and TimeZoneInfo types when working with date and time data.
Finding the time zones defined on a local system Describes how to enumerate the time zones found on a local
system.
How to: Enumerate time zones present on a computer Provides examples that enumerate the time zones defined in
a computer's registry and that let users select a predefined time zone from a list.
How to: Access the predefined UTC and local time zone objects Describes how to access Coordinated Universal
Time and the local time zone.
How to: Instantiate a TimeZoneInfo object Describes how to instantiate a TimeZoneInfo object from the local
system registry.
Instantiating a DateTimeOffset object Discusses the ways in which a DateTimeOffset object can be instantiated, and
the ways in which a DateTime value can be converted to a DateTimeOffset value.
How to: Create time zones without adjustment rules Describes how to create a custom time zone that does not
support the transition to and from daylight saving time.
How to: Create time zones with adjustment rules Describes how to create a custom time zone that supports one or
more transitions to and from daylight saving time.
Saving and restoring time zones Describes TimeZoneInfo support for serialization and deserialization of time zone
data and illustrates some of the scenarios in which these features can be used.
How to: Save time zones to an embedded resource Describes how to create a custom time zone and save its
information in a resource file.
How to: Restore time zones from an embedded resource Describes how to instantiate custom time zones that have
been saved to an embedded resource file.
Performing arithmetic operations with dates and times Discusses the issues involved in adding, subtracting, and
comparing DateTime and DateTimeOffset values.
How to: Use time zones in date and time arithmetic Discusses how to perform date and time arithmetic that reflects
a time zone's adjustment rules.
Converting between DateTime and DateTimeOffset Describes how to convert between DateTime and
DateTimeOffset values.
Converting times between time zones Describes how to convert times from one time zone to another.
How to: Resolve ambiguous times Describes how to resolve an ambiguous time by mapping it to the time zone's
standard time.
How to: Let users resolve ambiguous times Describes how to let a user determine the mapping between an
ambiguous local time and Coordinated Universal Time.
Reference
System.TimeZoneInfo
Handling and Raising Events
7/29/2017 • 7 min to read • Edit Online
Events in the .NET Framework are based on the delegate model. The delegate model follows the observer design
pattern, which enables a subscriber to register with, and receive notifications from, a provider. An event sender
pushes a notification that an event has happened, and an event receiver receives that notification and defines a
response to it. This article describes the major components of the delegate model, how to consume events in
applications, and how to implement events in your code.
For information about handling events in Windows 8.x Store apps, see Events and routed events overview
(Windows store apps).
Events
An event is a message sent by an object to signal the occurrence of an action. The action could be caused by user
interaction, such as a button click, or it could be raised by some other program logic, such as changing a property’s
value. The object that raises the event is called the event sender. The event sender doesn't know which object or
method will receive (handle) the events it raises. The event is typically a member of the event sender; for example,
the Click event is a member of the Button class, and the PropertyChanged event is a member of the class that
implements the INotifyPropertyChanged interface.
To define an event, you use the event (in C#) or Event (in Visual Basic) keyword in the signature of your event
class, and specify the type of delegate for the event. Delegates are described in the next section.
Typically, to raise an event, you add a method that is marked as protected and virtual (in C#) or Protected and
Overridable (in Visual Basic). Name this method On EventName; for example, OnDataReceived . The method
should take one parameter that specifies an event data object. You provide this method to enable derived classes
to override the logic for raising the event. A derived class should always call the On EventName method of the
base class to ensure that registered delegates receive the event.
The following example shows how to declare an event named ThresholdReached . The event is associated with the
EventHandler delegate and raised in a method named OnThresholdReached .
class Counter
{
public event EventHandler ThresholdReached;
Delegates
A delegate is a type that holds a reference to a method. A delegate is declared with a signature that shows the
return type and parameters for the methods it references, and can hold references only to methods that match its
signature. A delegate is thus equivalent to a type-safe function pointer or a callback. A delegate declaration is
sufficient to define a delegate class.
Delegates have many uses in the .NET Framework. In the context of events, a delegate is an intermediary (or
pointer-like mechanism) between the event source and the code that handles the event. You associate a delegate
with an event by including the delegate type in the event declaration, as shown in the example in the previous
section. For more information about delegates, see the Delegate class.
The .NET Framework provides the EventHandler and EventHandler<TEventArgs> delegates to support most event
scenarios. Use the EventHandler delegate for all events that do not include event data. Use the
EventHandler<TEventArgs> delegate for events that include data about the event. These delegates have no return
type value and take two parameters (an object for the source of the event and an object for event data).
Delegates are multicast, which means that they can hold references to more than one event-handling method. For
details, see the Delegate reference page. Delegates provide flexibility and fine-grained control in event handling. A
delegate acts as an event dispatcher for the class that raises the event by maintaining a list of registered event
handlers for the event.
For scenarios where the EventHandler and EventHandler<TEventArgs> delegates do not work, you can define a
delegate. Scenarios that require you to define a delegate are very rare, such as when you must work with code that
does not recognize generics. You mark a delegate with the delegate in (C#) and Delegate (in Visual Basic)
keyword in the declaration. The following example shows how to declare a delegate named
ThresholdReachedEventHandler .
Event Data
Data that is associated with an event can be provided through an event data class. The .NET Framework provides
many event data classes that you can use in your applications. For example, the SerialDataReceivedEventArgs class
is the event data class for the System.IO.Ports.SerialPort.DataReceived event. The .NET Framework follows a
naming pattern of ending all event data classes with EventArgs . You determine which event data class is
associated with an event by looking at the delegate for the event. For example, the
SerialDataReceivedEventHandler delegate includes the SerialDataReceivedEventArgs class as one of its parameters.
The EventArgs class is the base type for all event data classes. EventArgs is also the class you use when an event
does not have any data associated with it. When you create an event that is only meant to notify other classes that
something happened and does not need to pass any data, include the EventArgs class as the second parameter in
the delegate. You can pass the System.EventArgs.Empty value when no data is provided. The EventHandler
delegate includes the EventArgs class as a parameter.
When you want to create a customized event data class, create a class that derives from EventArgs, and then
provide any members needed to pass data that is related to the event. Typically, you should use the same naming
pattern as the .NET Framework and end your event data class name with EventArgs .
The following example shows an event data class named ThresholdReachedEventArgs . It contains properties that are
specific to the event being raised.
Event Handlers
To respond to an event, you define an event handler method in the event receiver. This method must match the
signature of the delegate for the event you are handling. In the event handler, you perform the actions that are
required when the event is raised, such as collecting user input after the user clicks a button. To receive
notifications when the event occurs, your event handler method must subscribe to the event.
The following example shows an event handler method named c_ThresholdReached that matches the signature for
the EventHandler delegate. The method subscribes to the ThresholdReached event.
class Program
{
static void Main(string[] args)
{
Counter c = new Counter();
c.ThresholdReached += c_ThresholdReached;
Sub Main()
Dim c As Counter = New Counter()
AddHandler c.ThresholdReached, AddressOf c_ThresholdReached
Related Topics
TITLE DESCRIPTION
How to: Raise and Consume Events Contains examples of raising and consuming events.
How to: Handle Multiple Events Using Event Properties Shows how to use event properties to handle multiple events.
Observer Design Pattern Describes the design pattern that enables a subscriber to
register with, and receive notifications from, a provider.
How to: Consume Events in a Web Forms Application Shows how to handle an event that is raised by a Web Forms
control.
See Also
EventHandler
EventHandler<TEventArgs>
EventArgs
Delegate
Events and routed events overview (Windows store apps)
Events (Visual Basic)
Events (C# Programming Guide)
Managed Execution Process
7/29/2017 • 7 min to read • Edit Online
The managed execution process includes the following steps, which are discussed in detail later in this topic:
1. Choosing a compiler.
To obtain the benefits provided by the common language runtime, you must use one or more language
compilers that target the runtime.
2. Compiling your code to MSIL.
Compiling translates your source code into Microsoft intermediate language (MSIL) and generates the
required metadata.
3. Compiling MSIL to native code.
At execution time, a just-in-time (JIT) compiler translates the MSIL into native code. During this compilation,
code must pass a verification process that examines the MSIL and metadata to find out whether the code
can be determined to be type safe.
4. Running code.
The common language runtime provides the infrastructure that enables execution to take place and
services that can be used during execution.
Choosing a Compiler
To obtain the benefits provided by the common language runtime (CLR), you must use one or more language
compilers that target the runtime, such as Visual Basic, C#, Visual C++, F#, or one of many third-party compilers
such as an Eiffel, Perl, or COBOL compiler.
Because it is a multilanguage execution environment, the runtime supports a wide variety of data types and
language features. The language compiler you use determines which runtime features are available, and you
design your code using those features. Your compiler, not the runtime, establishes the syntax your code must use.
If your component must be completely usable by components written in other languages, your component's
exported types must expose only language features that are included in the Language Independence and
Language-Independent Components (CLS). You can use the CLSCompliantAttribute attribute to ensure that your
code is CLS-compliant. For more information, see Language Independence and Language-Independent
Components.
Back to top
Compiling to MSIL
When compiling to managed code, the compiler translates your source code into Microsoft intermediate language
(MSIL), which is a CPU-independent set of instructions that can be efficiently converted to native code. MSIL
includes instructions for loading, storing, initializing, and calling methods on objects, as well as instructions for
arithmetic and logical operations, control flow, direct memory access, exception handling, and other operations.
Before code can be run, MSIL must be converted to CPU-specific code, usually by a just-in-time (JIT) compiler.
Because the common language runtime supplies one or more JIT compilers for each computer architecture it
supports, the same set of MSIL can be JIT-compiled and run on any supported architecture.
When a compiler produces MSIL, it also produces metadata. Metadata describes the types in your code, including
the definition of each type, the signatures of each type's members, the members that your code references, and
other data that the runtime uses at execution time. The MSIL and metadata are contained in a portable executable
(PE) file that is based on and that extends the published Microsoft PE and common object file format (COFF) used
historically for executable content. This file format, which accommodates MSIL or native code as well as metadata,
enables the operating system to recognize common language runtime images. The presence of metadata in the
file together with MSIL enables your code to describe itself, which means that there is no need for type libraries or
Interface Definition Language (IDL). The runtime locates and extracts the metadata from the file as needed during
execution.
Back to top
Running Code
The common language runtime provides the infrastructure that enables managed execution to take place and
services that can be used during execution. Before a method can be run, it must be compiled to processor-specific
code. Each method for which MSIL has been generated is JIT-compiled when it is called for the first time, and then
run. The next time the method is run, the existing JIT-compiled native code is run. The process of JIT-compiling and
then running the code is repeated until execution is complete.
During execution, managed code receives services such as garbage collection, security, interoperability with
unmanaged code, cross-language debugging support, and enhanced deployment and versioning support.
In Microsoft Windows XP and Windows Vista, the operating system loader checks for managed modules by
examining a bit in the COFF header. The bit being set denotes a managed module. If the loader detects managed
modules, it loads mscoree.dll, and _CorValidateImage and _CorImageUnloading notify the loader when the
managed module images are loaded and unloaded. _CorValidateImage performs the following actions:
1. Ensures that the code is valid managed code.
2. Changes the entry point in the image to an entry point in the runtime.
On 64-bit Windows, _CorValidateImage modifies the image that is in memory by transforming it from PE32 to
PE32+ format.
Back to top
See Also
Overview
Language Independence and Language-Independent Components
Metadata and Self-Describing Components
Ilasm.exe (IL Assembler)
Security
Interoperating with Unmanaged Code
Deployment
Assemblies in the Common Language Runtime
Application Domains
Metadata and Self-Describing Components
7/29/2017 • 8 min to read • Edit Online
In the past, a software component (.exe or .dll) that was written in one language could not easily use a software
component that was written in another language. COM provided a step towards solving this problem. The .NET
Framework makes component interoperation even easier by allowing compilers to emit additional declarative
information into all modules and assemblies. This information, called metadata, helps components to interact
seamlessly.
Metadata is binary information describing your program that is stored either in a common language runtime
portable executable (PE) file or in memory. When you compile your code into a PE file, metadata is inserted into
one portion of the file, and your code is converted to Microsoft intermediate language (MSIL) and inserted into
another portion of the file. Every type and member that is defined and referenced in a module or assembly is
described within metadata. When code is executed, the runtime loads metadata into memory and references it to
discover information about your code's classes, members, inheritance, and so on.
Metadata describes every type and member defined in your code in a language-neutral manner. Metadata stores
the following information:
Description of the assembly.
Identity (name, version, culture, public key).
The types that are exported.
Other assemblies that this assembly depends on.
Security permissions needed to run.
Description of types.
Name, visibility, base class, and interfaces implemented.
Members (methods, fields, properties, events, nested types).
Attributes.
Additional descriptive elements that modify types and members.
Benefits of Metadata
Metadata is the key to a simpler programming model, and eliminates the need for Interface Definition Language
(IDL) files, header files, or any external method of component reference. Metadata enables .NET Framework
languages to describe themselves automatically in a language-neutral manner, unseen by both the developer and
the user. Additionally, metadata is extensible through the use of attributes. Metadata provides the following major
benefits:
Self-describing files.
Common language runtime modules and assemblies are self-describing. A module's metadata contains
everything needed to interact with another module. Metadata automatically provides the functionality of IDL
in COM, so you can use one file for both definition and implementation. Runtime modules and assemblies
do not even require registration with the operating system. As a result, the descriptions used by the runtime
always reflect the actual code in your compiled file, which increases application reliability.
Language interoperability and easier component-based design.
Metadata provides all the information required about compiled code for you to inherit a class from a PE file
written in a different language. You can create an instance of any class written in any managed language
(any language that targets the common language runtime) without worrying about explicit marshaling or
using custom interoperability code.
Attributes.
The .NET Framework lets you declare specific kinds of metadata, called attributes, in your compiled file.
Attributes can be found throughout the .NET Framework and are used to control in more detail how your
program behaves at run time. Additionally, you can emit your own custom metadata into .NET Framework
files through user-defined custom attributes. For more information, see Attributes.
0x06000004
The top byte ( 0x06 ) indicates that this is a MethodDef token. The lower three bytes ( 000004 ) tells the common
language runtime to look in the fourth row of the MethodDef table for the information that describes this method
definition.
Metadata within a PE File
When a program is compiled for the common language runtime, it is converted to a PE file that consists of three
parts. The following table describes the contents of each part.
PE header The index of the PE file's main sections and the address of the
entry point.
Metadata Metadata tables and heaps. The runtime uses this section to
record information about every type and member in your
code. This section also includes custom attributes and security
information.
using System;
public class MyApp
{
public static int Main()
{
int ValueOne = 10;
int ValueTwo = 20;
Console.WriteLine("The Value is: {0}", Add(ValueOne, ValueTwo));
return 0;
}
public static int Add(int One, int Two)
{
return (One + Two);
}
}
When the code runs, the runtime loads the module into memory and consults the metadata for this class. Once
loaded, the runtime performs extensive analysis of the method's Microsoft intermediate language (MSIL) stream to
convert it to fast native machine instructions. The runtime uses a just-in-time (JIT) compiler to convert the MSIL
instructions to native machine code one method at a time as needed.
The following example shows part of the MSIL produced from the previous code's Main function. You can view the
MSIL and metadata from any .NET Framework application using the MSIL Disassembler (Ildasm.exe).
.entrypoint
.maxstack 3
.locals ([0] int32 ValueOne,
[1] int32 ValueTwo,
[2] int32 V_2,
[3] int32 V_3)
IL_0000: ldc.i4.s 10
IL_0002: stloc.0
IL_0003: ldc.i4.s 20
IL_0005: stloc.1
IL_0006: ldstr "The Value is: {0}"
IL_000b: ldloc.0
IL_000c: ldloc.1
IL_000d: call int32 ConsoleApplication.MyApp::Add(int32,int32) /* 06000003 */
The JIT compiler reads the MSIL for the whole method, analyzes it thoroughly, and generates efficient native
instructions for the method. At IL_000d , a metadata token for the Add method ( /* 06000003 */ ) is encountered
and the runtime uses the token to consult the third row of the MethodDef table.
The following table shows part of the MethodDef table referenced by the metadata token that describes the Add
method. While other metadata tables exist in this assembly and have their own unique values, only this table is
discussed.
NAME
SIGNATURE
RELATIVE VIRTUAL (POINTS TO (POINTS TO BLOB
ROW ADDRESS (RVA) IMPLFLAGS FLAGS STRING HEAP.) HEAP.)
Managed ReuseSlot
SpecialName
RTSpecialName
.ctor
Managed Static
ReuseSlot
Managed Static
ReuseSlot
Each column of the table contains important information about your code. The RVA column allows the runtime to
calculate the starting memory address of the MSIL that defines this method. The ImplFlags and Flags columns
contain bitmasks that describe the method (for example, whether the method is public or private). The Name
column indexes the name of the method from the string heap. The Signature column indexes the definition of the
method's signature in the blob heap.
The runtime calculates the desired offset address from the RVA column in the third row and returns this address to
the JIT compiler, which then proceeds to the new address. The JIT compiler continues to process MSIL at the new
address until it encounters another metadata token and the process is repeated.
Using metadata, the runtime has access to all the information it needs to load your code and process it into native
machine instructions. In this manner, metadata enables self-describing files and, together with the common type
system, cross-language inheritance.
Related Topics
TITLE DESCRIPTION
Applications in the .NET Framework can use the System.Console class to read characters from and write characters
to the console. Data from the console is read from the standard input stream, data to the console is written to the
standard output stream, and error data to the console is written to the standard error output stream. These streams
are automatically associated with the console when the application starts and are presented as the In, Out, and
Error properties, respectively.
The value of the System.Console.In property is a System.IO.TextReader object, whereas the values of the
System.Console.Out and System.Console.Error properties are System.IO.TextWriter objects. You can associate these
properties with streams that do not represent the console, making it possible for you to point the stream to a
different location for input or output. For example, you can redirect the output to a file by setting the
System.Console.Out property to a System.IO.StreamWriter, which encapsulates a System.IO.FileStream by means of
the System.Console.SetOut method. The System.Console.In and System.Console.Out properties do not need to refer
to the same stream.
NOTE
For more information about building console applications, including examples in C#, Visual Basic, and C++, see the
documentation for the Console class.
If the console does not exist, as in a Windows-based application, output written to the standard output stream will
not be visible, because there is no console to write the information to. Writing information to an inaccessible
console does not cause an exception to be raised.
Alternately, to enable the console for reading and writing within a Windows-based application that is developed
using Visual Studio, open the project's Properties dialog box, click the Application tab, and set the Application
type to Console Application.
Console applications lack a message pump that starts by default. Therefore, console calls to Microsoft Win32 timers
might fail.
The System.Console class has methods that can read individual characters or entire lines from the console. Other
methods convert data and format strings, and then write the formatted strings to the console. For more
information on formatting strings, see Formatting Types.
See Also
System.Console
Formatting Types
Parallel Processing and Concurrency in the .NET
Framework
7/29/2017 • 1 min to read • Edit Online
The .NET Framework provides several ways for you to use multiple threads of execution to keep your application
responsive to your user while maximizing the performance of your user's computer.
In This Section
Threading
Describes the basic concurrency and synchronization mechanisms provided by the .NET Framework.
Asynchronous Programming Patterns
Provides a brief overview of the three asynchronous programming patterns supported in the .NET Framework:
Asynchronous Programming Model (APM) (legacy)
Event-based Asynchronous Pattern (EAP) (legacy)
Task-based Asynchronous Pattern (TAP) (recommended for new development)
Parallel Programming
Describes a task-based programming model that simplifies parallel development, enabling you to write efficient,
fine-grained, and scalable parallel code in a natural idiom without having to work directly with threads or the
thread pool.
See Also
Development Guide
.NET Framework Application Essentials
8/4/2017 • 1 min to read • Edit Online
This section of the .NET Framework documentation provides information about basic application development
tasks in the .NET Framework.
In This Section
Base Types
Discusses formatting and parsing base data types and using regular expressions to process text.
Collections and Data Structures
Discusses the various collection types available in the .NET Framework, including stacks, queues, lists, arrays, and
structs.
Generics
Describes the Generics feature, including the generic collections, delegates, and interfaces provided by the .NET
Framework. Provides links to feature documentation for C#, Visual Basic and Visual C++, and to supporting
technologies such as Reflection.
Numerics
Describes the numeric types in the .NET Framework.
Events
Provides an overview of the event model in the .NET Framework.
Exceptions
Describes error handling provided by the .NET Framework and the fundamentals of handling exceptions.
File and Stream I-O
Explains how you can perform synchronous and asynchronous file and data stream access and how to use to
isolated storage.
Dates, Times, and Time Zones
Describes how to work with time zones and time zone conversions in time zone-aware applications.
Application Domains and Assemblies
Describes how to create and work with assemblies and application domains.
Serialization
Discusses the process of converting the state of an object into a form that can be persisted or transported.
Resources in Desktop Apps
Describes the .NET Framework support for creating and storing resources. This section also describes support for
localized resources and the satellite assembly resource model for packaging and deploying those localized
resources.
Globalization and Localization
Provides information to help you design and develop world-ready applications.
Accessibility
Provides information about Microsoft UI Automation, which is an accessibility framework that addresses the needs
of assistive technology products and automated test frameworks by providing programmatic access to information
about the user interface (UI).
Attributes
Describes how you can use attributes to customize metadata.
64-bit Applications
Discusses issues relevant to developing applications that will run on a Windows 64-bit operating system.
Related Sections
Development Guide
Provides a guide to all key technology areas and tasks for application development, including creating, configuring,
debugging, securing, and deploying your application, and information about dynamic programming,
interoperability, extensibility, memory management, and threading.
Security
Provides information about the classes and services in the common language runtime and the .NET Framework
that facilitate secure application development.
File and Stream I/O
7/29/2017 • 7 min to read • Edit Online
File and stream I/O (input/output) refers to the transfer of data either to or from a storage medium. In the .NET
Framework, the System.IO namespaces contain types that enable reading and writing, both synchronously and
asynchronously, on data streams and files. These namespaces also contain types that perform compression and
decompression on files, and types that enable communication through pipes and serial ports.
A file is an ordered and named collection of bytes that has persistent storage. When you work with files, you work
with directory paths, disk storage, and file and directory names. In contrast, a stream is a sequence of bytes that
you can use to read from and write to a backing store, which can be one of several storage mediums (for example,
disks or memory). Just as there are several backing stores other than disks, there are several kinds of streams other
than file streams, such as network, memory, and pipe streams.
Streams
The abstract base class Stream supports reading and writing bytes. All classes that represent streams inherit from
the Stream class. The Stream class and its derived classes provide a common view of data sources and repositories,
and isolate the programmer from the specific details of the operating system and underlying devices.
Streams involve three fundamental operations:
Reading - transferring data from a stream into a data structure, such as an array of bytes.
Writing - transferring data to a stream from a data source.
Seeking - querying and modifying the current position within a stream.
Depending on the underlying data source or repository, a stream might support only some of these capabilities.
For example, the PipeStream class does not support seeking. The CanRead, CanWrite, and CanSeek properties of a
stream specify the operations that the stream supports.
Here are some commonly used stream classes:
FileStream – for reading and writing to a file.
IsolatedStorageFileStream – for reading and writing to a file in isolated storage.
MemoryStream – for reading and writing to memory as the backing store.
BufferedStream – for improving performance of read and write operations.
NetworkStream – for reading and writing over network sockets.
PipeStream – for reading and writing over anonymous and named pipes.
CryptoStream – for linking data streams to cryptographic transformations.
For an example of working with streams asynchronously, see Asynchronous File I/O.
Compression
Compression refers to the process of reducing the size of a file for storage. Decompression is the process of
extracting the contents of a compressed file so they are in a usable format. The System.IO.Compression namespace
contains types for compressing and decompressing files and streams.
The following classes are frequently used when compressing and decompressing files and streams:
ZipArchive – for creating and retrieving entries in the zip archive.
ZipArchiveEntry – for representing a compressed file.
ZipFile – for creating, extracting, and opening a compressed package.
ZipFileExtensions – for creating and extracting entries in a compressed package.
DeflateStream – for compressing and decompressing streams using the Deflate algorithm.
GZipStream – for compressing and decompressing streams in gzip data format.
See How to: Compress and Extract Files.
Isolated Storage
Isolated storage is a data storage mechanism that provides isolation and safety by defining standardized ways of
associating code with saved data. The storage provides a virtual file system that is isolated by user, assembly, and
(optionally) domain. Isolated storage is particularly useful when your application does not have permission to
access user files. You can save settings or files for your application in a manner that is controlled by the computer's
security policy.
Isolated storage is not available for Windows 8.x Store apps; instead, use application data classes in the
Windows.Storage namespace. For more information, see Application data in the Windows Dev Center.
The following classes are frequently used when implementing isolated storage:
IsolatedStorage – provides the base class for isolated storage implementations.
IsolatedStorageFile – provides an isolated storage area that contains files and directories.
IsolatedStorageFileStream - exposes a file within isolated storage.
See Isolated Storage.
Related Topics
Common I/O Tasks
Provides a list of I/O tasks associated with files, directories, and streams, and links to relevant content and examples
for each task.
Asynchronous File I/O
Describes the performance advantages and basic operation of asynchronous I/O.
Isolated Storage
Describes a data storage mechanism that provides isolation and safety by defining standardized ways of
associating code with saved data.
Pipes
Describes anonymous and named pipe operations in the .NET Framework.
Memory-Mapped Files
Describes memory-mapped files, which contain the contents of files on disk in virtual memory. You can use
memory-mapped files to edit very large files and to create shared memory for interprocess communication.
Globalizing and Localizing .NET Framework
Applications
7/29/2017 • 2 min to read • Edit Online
Developing a world-ready application, including an application that can be localized into one or more languages,
involves three steps: globalization, localizability review, and localization.
Globalization
This step involves designing and coding an application that is culture-neutral and language-neutral, and that
supports localized user interfaces and regional data for all users. It involves making design and programming
decisions that are not based on culture-specific assumptions. While a globalized application is not localized, it
nevertheless is designed and written so that it can be subsequently localized into one or more languages with
relative ease.
Localizability Review
This step involves reviewing an application's code and design to ensure that it can be localized easily and to
identify potential roadblocks for localization, and verifying that the application's executable code is separated from
its resources. If the globalization stage was effective, the localizability review will confirm the design and coding
choices made during globalization. The localizability stage may also identify any remaining issues so that an
application's source code doesn't have to be modified during the localization stage.
Localization
This step involves customizing an application for specific cultures or regions. If the globalization and localizability
steps have been performed correctly, localization consists primarily of translating the user interface.
Following these three steps provides two advantages:
It frees you from having to retrofit an application that is designed to support a single culture, such as U.S.
English, to support additional cultures.
It results in localized applications that are more stable and have fewer bugs.
The .NET Framework provides extensive support for the development of world-ready and localized applications. In
particular, many type members in the .NET Framework class library aid globalization by returning values that
reflect the conventions of either the current user's culture or a specified culture. Also, the .NET Framework supports
satellite assemblies, which facilitate the process of localizing an application.
For additional information, see the Go Global Developer Center.
In This Section
Globalization
Discusses the first stage of creating a world-ready application, which involves designing and coding an application
that is culture-neutral and language-neutral.
Localizability Review
Discusses the second stage of creating a localized application, which involves identifying potential roadblocks to
localization.
Localization
Discusses the final stage of creating a localized application, which involves customizing an application's user
interface for specific regions or cultures.
Culture-Insensitive String Operations
Describes how to use .NET Framework methods and classes that are culture-sensitive by default to obtain culture-
insensitive results.
Best Practices for Developing World-Ready Applications
Describes the best practices to follow for globalization, localization, and developing world-ready ASP.NET
applications.
Reference
System.Globalization namespace
Contains classes that define culture-related information, including the language, the country/region, the calendars
in use, the format patterns for dates, currency, and numbers, and the sort order for strings.
System.Resources namespace
Provides classes for creating, manipulating, and using resources.
System.Text namespace
Contains classes representing ASCII, ANSI, Unicode, and other character encodings.
Resgen.exe (Resource File Generator)
Describes how to use Resgen.exe to convert .txt files and XML-based resource format (.resx) files to common
language runtime binary .resources files.
Winres.exe (Windows Forms Resource Editor)
Describes how to use Winres.exe to localize Windows Forms forms.
Extending Metadata Using Attributes
7/29/2017 • 1 min to read • Edit Online
The common language runtime allows you to add keyword-like descriptive declarations, called attributes, to
annotate programming elements such as types, fields, methods, and properties. When you compile your code for
the runtime, it is converted into Microsoft intermediate language (MSIL) and placed inside a portable executable
(PE) file along with metadata generated by the compiler. Attributes allow you to place extra descriptive information
into metadata that can be extracted using runtime reflection services. The compiler creates attributes when you
declare instances of special classes that derive from System.Attribute.
The .NET Framework uses attributes for a variety of reasons and to address a number of issues. Attributes describe
how to serialize data, specify characteristics that are used to enforce security, and limit optimizations by the just-
in-time (JIT) compiler so the code remains easy to debug. Attributes can also record the name of a file or the
author of code, or control the visibility of controls and members during forms development.
Related Topics
TITLE DESCRIPTION
Retrieving Information Stored in Attributes Describes how to retrieve custom attributes for code that is
loaded into the execution context.
Metadata and Self-Describing Components Provides an overview of metadata and describes how it is
implemented in a .NET Framework portable executable (PE)
file.
How to: Load Assemblies into the Reflection-Only Context Explains how to retrieve custom attribute information in the
reflection-only context.
Reference
System.Attribute
Framework Design Guidelines
7/29/2017 • 1 min to read • Edit Online
This section provides guidelines for designing libraries that extend and interact with the .NET Framework. The goal
is to help library designers ensure API consistency and ease of use by providing a unified programming model that
is independent of the programming language used for development. We recommend that you follow these design
guidelines when developing classes and components that extend the .NET Framework. Inconsistent library design
adversely affects developer productivity and discourages adoption.
The guidelines are organized as simple recommendations prefixed with the terms Do , Consider , Avoid , and
Do not . These guidelines are intended to help class library designers understand the trade-offs between different
solutions. There might be situations where good library design requires that you violate these design guidelines.
Such cases should be rare, and it is important that you have a clear and compelling reason for your decision.
These guidelines are excerpted from the book Framework Design Guidelines: Conventions, Idioms, and Patterns for
Reusable .NET Libraries, 2nd Edition, by Krzysztof Cwalina and Brad Abrams.
In This Section
Naming Guidelines
Provides guidelines for naming assemblies, namespaces, types, and members in class libraries.
Type Design Guidelines
Provides guidelines for using static and abstract classes, interfaces, enumerations, structures, and other types.
Member Design Guidelines
Provides guidelines for designing and using properties, methods, constructors, fields, events, operators, and
parameters.
Designing for Extensibility
Discusses extensibility mechanisms such as subclassing, using events, virtual members, and callbacks, and explains
how to choose the mechanisms that best meet your framework's requirements.
Design Guidelines for Exceptions
Describes design guidelines for designing, throwing, and catching exceptions.
Usage Guidelines
Describes guidelines for using common types such as arrays, attributes, and collections, supporting serialization,
and overloading equality operators.
Common Design Patterns
Provides guidelines for choosing and implementing dependency properties and the dispose pattern.
Portions © 2005, 2009 Microsoft Corporation. All rights reserved.
Reprinted by permission of Pearson Education, Inc. from Framework Design Guidelines: Conventions, Idioms, and
Patterns for Reusable .NET Libraries, 2nd Edition by Krzysztof Cwalina and Brad Abrams, published Oct 22, 2008 by
Addison-Wesley Professional as part of the Microsoft Windows Development Series.
See Also
Overview
Roadmap for the .NET Framework
Development Guide
XML Documents and Data
7/29/2017 • 2 min to read • Edit Online
The .NET Framework provides a comprehensive and integrated set of classes that enable you to build XML-aware
apps easily. The classes in the following namespaces support parsing and writing XML, editing XML data in
memory, data validation, and XSLT transformation.
System.Xml
System.Xml.XPath
System.Xml.Xsl
System.Xml.Schema
System.Xml.Linq
For a full list, see the System.Xml Namespaces webpage.
The classes in these namespaces support World Wide Web Consortium (W3C) recommendations. For example:
The System.Xml.XmlDocument class implements the W3C Document Object Model (DOM) Level 1 Core and
DOM Level 2 Core recommendations.
The System.Xml.XmlReader and System.Xml.XmlWriter classes support the W3C XML 1.0 and the
Namespaces in XML recommendations.
Schemas in the System.Xml.Schema.XmlSchemaSet class support the W3C XML Schema Part 1: Structures
and XML Schema Part 2: Datatypes recommendations.
Classes in the System.Xml.Xsl namespace support XSLT transformations that conform to the W3C XSLT 1.0
recommendation.
The XML classes in the .NET Framework provide these benefits:
Productivity. LINQ to XML makes it easier to program with XML and provides a query experience that is
similar to SQL.
Extensibility. The XML classes in the .NET Framework are extensible through the use of abstract base
classes and virtual methods. For example, you can create a derived class of the XmlUrlResolver class that
stores the cache stream to the local disk.
Pluggable architecture. The .NET Framework provides an architecture in which components can utilize
one another, and data can be streamed between components. For example, a data store, such as an
XPathDocument or XmlDocument object, can be transformed with the XslCompiledTransform class, and the
output can then be streamed either into another store or returned as a stream from a web service.
Performance. For better app performance, some of the XML classes in the .NET Framework support a
streaming-based model with the following characteristics:
Minimal caching for forward-only, pull-model parsing (XmlReader).
Forward-only validation (XmlReader).
Cursor style navigation that minimizes node creation to a single virtual node while providing random
access to the document (XPathNavigator).
For better performance whenever XSLT processing is required, you can use the XPathDocument class, which
is an optimized, read-only store for XPath queries designed to work efficiently with the
XslCompiledTransform class.
Integration with ADO.NET. The XML classes and ADO.NET are tightly integrated to bring together
relational data and XML. The DataSet class is an in-memory cache of data retrieved from a database. The
DataSet class has the ability to read and write XML by using the XmlReader and XmlWriter classes, to persist
its internal relational schema structure as XML schemas (XSD), and to infer the schema structure of an XML
document.
In This Section
XML Processing Options
Discusses options for processing XML data.
Processing XML Data In-Memory
Discusses the three models for processing XML data in-memory. LINQ to XML, the XmlDocument class (based on
the W3C Document Object Model), and the XPathDocument class (based on the XPath data model).
XSLT Transformations
Describes how to use the XSLT processor.
XML Schema Object Model (SOM)
Describes the classes used for building and manipulating XML Schemas (XSD) by providing an XmlSchema class to
load and edit a schema.
XML Integration with Relational Data and ADO.NET
Describes how the .NET Framework enables real-time, synchronous access to both the relational and hierarchical
representations of data through the DataSet object and the XmlDataDocument object.
Managing Namespaces in an XML Document
Describes how the XmlNamespaceManager class is used to store and maintain namespace information.
Type Support in the System.Xml Classes
Describes how XML data types map to CLR types, how to convert XML data types, and other type support features
in the System.Xml classes.
Related Sections
ADO.NET
Provides information on how to access data using ADO.NET.
Security
Provides an overview of the .NET Framework security system.
XML Developer Center
Provides additional technical information, downloads, newsgroups, and other resources for XML developers.
Managed Threading
7/29/2017 • 1 min to read • Edit Online
Whether you are developing for computers with one processor or several, you want your application to provide the
most responsive interaction with the user, even if the application is currently doing other work. Using multiple
threads of execution is one of the most powerful ways to keep your application responsive to the user and at the
same time make use of the processor in between or even during user events. While this section introduces the
basic concepts of threading, it focuses on managed threading concepts and using managed threading.
NOTE
Starting with the .NET Framework 4, multithreaded programming is greatly simplified with the
System.Threading.Tasks.Parallel and System.Threading.Tasks.Task classes, Parallel LINQ (PLINQ), new concurrent collection
classes in the System.Collections.Concurrent namespace, and a new programming model that is based on the concept of
tasks rather than threads. For more information, see Parallel Programming.
In This Section
Managed Threading Basics
Provides an overview of managed threading and discusses when to use multiple threads.
Using Threads and Threading
Explains how to create, start, pause, resume, and abort threads.
Managed Threading Best Practices
Discusses levels of synchronization, how to avoid deadlocks and race conditions, single-processor and
multiprocessor computers, and other threading issues.
Threading Objects and Features
Describes the managed classes you can use to synchronize the activities of threads and the data of objects accessed
on different threads, and provides an overview of thread pool threads.
Reference
System.Threading
Contains classes for using and synchronizing managed threads.
System.Collections.Concurrent
Contains collection classes that are safe for use with multiple threads.
System.Threading.Tasks
Contains classes for creating and scheduling concurrent processing tasks.
Related Sections
Application Domains
Provides an overview of application domains and their use by the Common Language Infrastructure.
Asynchronous File I/O
Describes the performance advantages and basic operation of asynchronous I/O.
Event-based Asynchronous Pattern (EAP)
Provides an overview of asynchronous programming.
Calling Synchronous Methods Asynchronously
Explains how to call methods on thread pool threads using built-in features of delegates.
Parallel Programming
Describes the parallel programming libraries, which simplify the use of multiple threads in applications.
Parallel LINQ (PLINQ)
Describes a system for running queries in parallel, to take advantage of multiple processors.
Parallel Programming in the .NET Framework
7/29/2017 • 1 min to read • Edit Online
Many personal computers and workstations have two or four cores (that is, CPUs) that enable multiple threads to
be executed simultaneously. Computers in the near future are expected to have significantly more cores. To take
advantage of the hardware of today and tomorrow, you can parallelize your code to distribute work across multiple
processors. In the past, parallelization required low-level manipulation of threads and locks. Visual Studio 2010 and
the .NET Framework 4 enhance support for parallel programming by providing a new runtime, new class library
types, and new diagnostic tools. These features simplify parallel development so that you can write efficient, fine-
grained, and scalable parallel code in a natural idiom without having to work directly with threads or the thread
pool. The following illustration provides a high-level overview of the parallel programming architecture in the .NET
Framework 4.
Related Topics
TECHNOLOGY DESCRIPTION
Data Structures for Parallel Programming Provides links to documentation for thread-safe collection
classes, lightweight synchronization types, and types for lazy
initialization.
Parallel Diagnostic Tools Provides links to documentation for Visual Studio debugger
windows for tasks and parallel stacks, and the Concurrency
Visualizer, which consists of a set of views in the Visual Studio
Application Lifecycle Management Profiler that you can use to
debug and to tune the performance of parallel code.
TECHNOLOGY DESCRIPTION
Custom Partitioners for PLINQ and TPL Describes how partitioners work and how to configure the
default partitioners or create a new partitioner.
Task Schedulers Describes how schedulers work and how the default
schedulers may be configured.
Lambda Expressions in PLINQ and TPL Provides a brief overview of lambda expressions in C# and
Visual Basic, and shows how they are used in PLINQ and the
Task Parallel Library.
See Also
Patterns for Parallel Programming: Understanding and Applying Parallel Patterns with the .NET Framework 4
Samples for Parallel Programming with the .NET Framework
Security in the .NET Framework
7/29/2017 • 1 min to read • Edit Online
The common language runtime and the .NET Framework provide many useful classes and services that enable
developers to easily write secure code and enable system administrators to customize the permissions granted to
code so that it can access protected resources. In addition, the runtime and the .NET Framework provide useful
classes and services that facilitate the use of cryptography and role-based security.
In This Section
Security Changes
Describes important changes to the .NET Framework security system.
Key Security Concepts
Provides an overview of common language runtime security features. This section is of interest to developers and
system administrators.
Role-Based Security
Describes how to interact with role-based security in your code. This section is of interest to developers.
Cryptography Model
Provides an overview of cryptographic services provided by the .NET Framework. This section is of interest to
developers.
Secure Coding Guidelines
Describes some of the best practices for creating reliable .NET Framework applications. This section is of interest to
developers.
Secure Coding Guidelines for Unmanaged Code
Describes some of the best practices and security concerns when calling unmanaged code.
Windows Identity Foundation
Describes how you can implement claims-based identity in your applications.
Related Sections
Development Guide
Provides a guide to all key technology areas and tasks for application development, including creating, configuring,
debugging, securing, and deploying your application, and information about dynamic programming,
interoperability, extensibility, memory management, and threading.
Serialization in .NET
8/4/2017 • 1 min to read • Edit Online
Serialization is the process of converting the state of an object into a form that can be persisted or transported. The
complement of serialization is deserialization, which converts a stream into an object. Together, these processes
allow data to be easily stored and transferred.
.NET features two serialization technologies:
Binary serialization preserves type fidelity, which is useful for preserving the state of an object between
different invocations of an application. For example, you can share an object between different applications
by serializing it to the Clipboard. You can serialize an object to a stream, to a disk, to memory, over the
network, and so forth. Remoting uses serialization to pass objects "by value" from one computer or
application domain to another.
XML serialization serializes only public properties and fields and does not preserve type fidelity. This is
useful when you want to provide or consume data without restricting the application that uses the data.
Because XML is an open standard, it is an attractive choice for sharing data across the Web. SOAP is likewise
an open standard, which makes it an attractive choice.
In This Section
Serialization How-to Topics
Lists links to How-to topics contained in this section.
Binary Serialization
Describes the binary serialization mechanism that is included with the common language runtime.
XML and SOAP Serialization
Describes the XML and SOAP serialization mechanism that is included with the common language runtime.
Serialization Tools
These tools help develop serialization code.
Serialization Samples
The samples demonstrate how to do serialization.
Reference
System.Runtime.Serialization Contains classes that can be used for serializing and deserializing objects.
System.Xml.Serialization
Contains classes that can be used to serialize objects into XML format documents or streams.
Developing for Multiple Platforms with the .NET
Framework
7/29/2017 • 2 min to read • Edit Online
You can develop apps for both Microsoft and non-Microsoft platforms by using the .NET Framework and Visual
Studio.
Share source code between Windows Phone 8.1 and Windows Shared projects (Universal Apps template in Visual Studio
8.1 apps 2013, Update 2).
Share binaries between apps that target different platforms Portable Class Library projects for code that is platform-
agnostic.
Share source code between apps for platforms other than Add as link feature.
Windows 8.1 and Windows Phone 8.1
- This approach is suitable for app logic that's common to
both apps but not portable, for some reason. You can use this
feature for C# or Visual Basic code.
For example, Windows Phone 8 and Windows 8 share
Windows Runtime APIs, but Portable Class Libraries do not
support Windows Runtime for those platforms. You can use
Add as link to share common Windows Runtime code
between a Windows Phone 8 app and a Windows Store app
that targets Windows 8.
Write Windows Store apps using the .NET Framework or call Windows Runtime APIs from your .NET Framework C# or
Windows Runtime APIs from .NET Framework code Visual Basic code, and use the .NET Framework to create
Windows Store apps. You should be aware of API differences
between the two platforms. However, there are classes to help
you work with those differences.
Build .NET Framework apps for non-Microsoft platforms Portable Class Library reference assemblies in the .NET
Framework, and a Visual Studio extension or third-party tool
such as Xamarin.
Use JavaScript and HTML for cross-platform development Universal App templates in Visual Studio 2013, Update 2 to
develop against Windows Runtime APIs for Windows 8.1 and
Windows Phone 8.1. Currently, you can’t use JavaScript and
HTML with .NET Framework APIs to develop cross-platform
apps.
Check out the "Getting Started" tutorials to learn how to create a simple .NET Core application. It only takes a
few minutes to get your first app up and running.
.NET Core is a general purpose development platform maintained by Microsoft and the .NET community on
GitHub. It is cross-platform, supporting Windows, macOS and Linux, and can be used in device, cloud, and
embedded/IoT scenarios.
The following characteristics best define .NET Core:
Flexible deployment: Can be included in your app or installed side-by-side user- or machine-wide.
Cross-platform: Runs on Windows, macOS and Linux; can be ported to other operating systems. The
supported Operating Systems (OS), CPUs and application scenarios will grow over time, provided by
Microsoft, other companies, and individuals.
Command-line tools: All product scenarios can be exercised at the command-line.
Compatible: .NET Core is compatible with .NET Framework, Xamarin and Mono, via the .NET Standard.
Open source: The .NET Core platform is open source, using MIT and Apache 2 licenses. Documentation is
licensed under CC-BY. .NET Core is a .NET Foundation project.
Supported by Microsoft: .NET Core is supported by Microsoft, per .NET Core Support
Composition
.NET Core is composed of the following parts:
A .NET runtime, which provides a type system, assembly loading, a garbage collector, native interop and other
basic services.
A set of framework libraries, which provide primitive data types, app composition types and fundamental
utilities.
A set of SDK tools and language compilers that enable the base developer experience, available in the .NET
Core SDK.
The 'dotnet' app host, which is used to launch .NET Core apps. It selects the runtime and hosts the runtime,
provides an assembly loading policy and launches the app. The same host is also used to launch SDK tools in
much the same way.
Languages
The C# and F# languages (Visual Basic is coming) can be used to write applications and libraries for .NET Core.
The compilers run on .NET Core, enabling you to develop for .NET Core anywhere it runs. In general, you will not
use the compilers directly, but indirectly using the SDK tools.
The C# and F# compilers and the .NET Core tools are or can be integrated into several text editors and IDEs,
including Visual Studio, Visual Studio Code, Sublime Text and Vim, making .NET Core development an option in
your favorite coding environment and OS. This integration is provided, in part, by the good folks of the
OmniSharp project.
.NET APIs and Compatibility
.NET Core can be thought of as a cross-platform version of the .NET Framework, at the layer of the .NET
Framework Base Class Libraries (BCL). It implements the .NET Standard specification. .NET Core provides a subset
of the APIs that are available in the .NET Framework or Mono/Xamarin. In some cases, types are not fully
implemented (some members are not available or have been moved).
Look at the .NET Core roadmap to learn more about the .NET Core API roadmap.
Relationship to .NET Standard
The .NET Standard is an API spec that describes the consistent set of .NET APIs that developers can expect in each
.NET implementation. .NET implementations need to implement this spec in order to be considered .NET
Standard-compliant and to support libraries that target .NET Standard.
.NET Core implements .NET Standard, and therefore supports .NET Standard libraries.
Workloads
By itself, .NET Core includes a single application model -- console apps -- which is useful for tools, local services
and text-based games. Additional application models have been built on top of .NET Core to extend its
functionality, such as:
ASP.NET Core
Windows 10 Universal Windows Platform (UWP)
Xamarin.Forms when targeting UWP
Open Source
.NET Core is open source (MIT license) and was contributed to the .NET Foundation by Microsoft in 2014. It is now
one of the most active .NET Foundation projects. It can be freely adopted by individuals and companies, including
for personal, academic or commercial purposes. Multiple companies use .NET Core as part of apps, tools, new
platforms and hosting services. Some of these companies make significant contributions to .NET Core on GitHub
and provide guidance on the product direction as part of the .NET Foundation Technical Steering Group.
Acquisition
.NET Core is distributed in two main ways, as packages on NuGet.org and as standalone distributions.
Distributions
You can download .NET Core at the .NET Core Getting Started page.
The Microsoft .NET Core distribution includes the CoreCLR runtime, associated libraries, a console application
host and the dotnet app launcher. It is described by the Microsoft.NETCore.App metapackage.
The Microsoft .NET Core SDK distribution includes .NET Core and a set of tools for restoring NuGet packages
and compiling and building apps.
Typically, you will first install the .NET Core SDK to get started with .NET Core development. You may choose to
install additional .NET Core (perhaps pre-release) builds.
Packages
.NET Core Packages contain the .NET Core runtime and libraries (reference assemblies and implementations).
For example, System.Net.Http.
.NET Core Metapackages describe various layers and app-models by referencing the appropriate set of
versioned library packages.
Architecture
.NET Core is a cross-platform .NET implementation. The primary architectural concerns unique to .NET Core are
related to providing platform-specific implementations for supported platforms.
Environments
.NET Core is supported by Microsoft on Windows, macOS and Linux. On Linux, Microsoft primarily supports .NET
Core running on Red Hat Enterprise Linux (RHEL) and Debian distribution families.
.NET Core currently supports X64 CPUs. On Windows, X86 is also supported. ARM64 and ARM32 are in progress.
The .NET Core Roadmap provides more detailed information on workload and OS and CPU environment support
and plans.
Other companies or groups may support .NET Core for other app types and environment.
Designed for Adaptability
.NET Core has been built as a very similar but unique product relative to other .NET products. It has been
designed to enable broad adaptability to new platforms, for new workloads and with new compiler toolchains. It
has several OS and CPU ports in progress and may be ported to many more. An example is the LLILC project,
which is an early prototype of native compilation for .NET Core via the LLVM compiler.
The product is broken into several pieces, enabling the various parts to be adapted to new platforms on different
schedules. The runtime and platform-specific foundational libraries must be ported as a unit. Platform-agnostic
libraries should work as-is on all platforms, by construction. There is a project bias to reducing platform-specific
implementations to increase developer efficiency, preferring platform-neutral C# code whenever an algorithm or
API can be implemented in-full or in-part that way.
People commonly ask how .NET Core is implemented in order to support multiple operating systems. They
typically ask if there are separate implementations or if conditional compilation is used. It's both, with a strong
bias towards conditional compilation.
You can see in the chart below that the vast majority of CoreFX is platform-neutral code that is shared across all
platforms. Platform-neutral code can be implemented as a single portable assembly that is used on all platforms.
Windows and Unix implementations are similar in size. Windows has a larger implementation since CoreFX
implements some Windows-only features, such as Microsoft.Win32.Registry but does not yet implement any
Unix-only concepts. You will also see that the majority of the Linux and macOS implementations are shared
across a Unix implementation, while the Linux- and macOS-specific implementations are roughly similar in size.
There are a mix of platform-specific and platform-neutral libraries in .NET Core. You can see the pattern in a few
examples:
CoreCLR is platform-specific. It's built in C/C++, so is platform-specific by construction.
System.IO and System.Security.Cryptography.Algorithms are platform-specific, given that the storage and
cryptography APIs differ significantly on each OS.
System.Collections and System.Linq are platform-neutral, given that they create and operate over data
structures.