Welcome To .NET NET Guide

User Manual:

Open the PDF directly: View PDF PDF.
Page Count: 2240

DownloadWelcome To .NET NET Guide
Open PDF In BrowserView PDF
Contents
Welcome
.NET Guide
Get Started with .NET
Tour of .NET
.NET Architectural Components
.NET Standard
What's new in the .NET Standard
Target Frameworks
.NET Glossary
Architecture Guidance
Architect Modern web applications with ASP.NET Core and Microsoft Azure
Modernize Existing .NET Applications with Azure cloud and Windows Containers
Containerized Docker Application Lifecycle with the Microsoft Platform and Tools
.NET Microservices: Architecture for Containerized .NET Applications
Serverless apps: Architecture, patterns, and Azure implementation
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
Analyzers
API Analyzer
Portability Analyzer
Framework Analyzer

Handling and throwing exceptions
.NET Assembly File Format
Garbage Collection
Generic types
Delegates and lambdas
LINQ
Common Type System & Common Language Specification
Parallel Processing, Concurrency, and Async
Asynchronous programming
Asynchronous programming in depth
Asynchronous Programming Patterns
Parallel Programming
Threading
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
Application Essentials
File and Stream I/O
Globalization and Localization
Attributes
Framework Design Guidelines
XML Documents and Data
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
Windows Prerequisites
macOS Prerequisites
Linux Prerequisites
What's new in .NET Core
What's new in .NET Core 2.1
What's new in .NET Core 2.0
Tutorials
Building a complete .NET Core solution on Windows, using Visual Studio 2017
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
Organizing and testing projects with the .NET Core command line
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
.NET Core 2.0 to 2.1
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
Self-contained deployment runtime roll forward
Runtime package store
Docker
Introduction to .NET and Docker
Learn Docker Basics with .NET Core
Building Docker Images for .NET Core Applications
Visual Studio Tools for Docker
Unit Testing
C# unit testing with xUnit
C# unit testing with NUnit
C# unit testing with MSTest
F# unit testing with xUnit
F# unit testing with NUnit
F# unit testing with MSTest
VB unit testing with xUnit
VB unit testing with NUnit
VB unit testing with MSTest
Running selective unit tests
Unit Testing Published Output
Live unit testing .NET Core projects with Visual Studio
Versioning
.NET Core version selection
Runtime IDentifier catalog
.NET Core SDK Overview
.NET Core CLI Tools
Telemetry
Global Tools
Extensibility Model

Continuous Integration
Custom templates
dotnet
dotnet build
dotnet build-server
dotnet clean
dotnet help
dotnet install-script
dotnet migrate
dotnet msbuild
dotnet new
dotnet nuget
dotnet nuget delete
dotnet nuget locals
dotnet nuget push
dotnet pack
dotnet publish
dotnet restore
dotnet run
dotnet sln
dotnet store
dotnet test
dotnet tool
dotnet tool install
dotnet tool list
dotnet tool uninstall
dotnet tool update
dotnet vstest
Project modification commands
References
dotnet add reference
dotnet list reference

dotnet remove reference
Packages
dotnet add package
dotnet remove package
global.json
.NET Core Additional Tools
WCF Web Service Reference Provider
dotnet-svcutil
XML Serializer Generator
Porting from .NET Framework
Organizing projects for .NET Core
Analyzing third-party dependencies
Porting libraries
Using the Windows Compatibility Pack
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
Common Client Technologies
Windows Presentation Foundation

Windows Forms
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
Quickstarts
Tutorials
Tour of C#
What's new in C#
C# 7.3
C# 7.2
C# 7.1
C# 7.0
C# 6

C# Version History
Relationships between language and framework
C# Concepts
C# Type system
Namespaces
Basic Types
Classes
Structs
Tuples
Deconstructing tuples and other types
Interfaces
Methods
Lambda Expressions
Properties
Indexers
Discards
Generics
Iterators
Delegates & events
Introduction to Delegates
System.Delegate and the delegate keyword
Strongly Typed Delegates
Common Patterns for Delegates
Introduction to Events
Standard .NET event patterns
The Updated .NET Event Pattern
Distinguishing Delegates and Events
Language Integrated Query (LINQ)
Asynchronous programming
Pattern Matching
Reference semantics with value types
Expression Trees

Expression Trees Explained
Framework Types Supporting Expression Trees
Executing Expressions
Interpreting Expressions
Building Expressions
Translating Expressions
Summary
Native interoperability
Documenting your code
Versioning
How To C# Topics
Parse strings using `String.Split`
Concatenate strings
Convert a string to a DateTime
Search strings
Modify string contents
Compare strings
The .NET Compiler Platform SDK (Roslyn APIs)
C# Programming Guide
Language Reference
Walkthroughs
F# Guide
Tour of F#
Get Started
Install F#
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
F# style guide
F# code formatting guidelines
F# coding conventions

F# component design guidelines
Tutorials
F# Interactive
Type Providers
Create a Type Provider
Type provider Security
Troubleshooting Type Providers
Introduction to Functional Programming
Functions as First-Class Values
Asynchronous and Concurrent Programming
Asynchronous Programming
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
Arithmetic Operators
Boolean Operators
Bitwise Operators
Nullable Operators
Functions
let Bindings
do Bindings
Lambda Expressions: the fun keyword
Recursive Functions: the rec keyword
Entry Point
External Functions
Inline Functions

Values
Null Values
Literals
F# Types
Type Inference
Basic Types
Unit Type
Strings
Tuples
F# Collection Types
Lists
Options
Results
Sequences
Arrays
Generics
Automatic Generalization
Constraints
Statically Resolved Type Parameters
Records
Discriminated Unions
Enumerations
Reference Cells
Type Abbreviations
Classes
Structures
Inheritance
Interfaces
Abstract Classes
Members
let Bindings in Classes
do Bindings in Classes

Properties
Indexed Properties
Methods
Constructors
Events
Explicit Fields: The `val` Keyword
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
Exception Types
The try...with Expression
The try...finally Expression
The raise Function
The failwith Function
The invalidArg Function
Attributes
Resource Management: the use Keyword

Namespaces
Modules
Import Declarations: The open Keyword
Signature Files
Units of Measure
XML Documentation
Lazy Computations
Computation Expressions
Asynchronous Workflows
Query Expressions
Code Quotations
Fixed keyword
Compiler Directives
Compiler Options
F# Interactive 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
Accessing Computer Resources
Logging Information from the Application
Accessing User Data
Accessing Application Forms
Accessing Application Web Services
How to: Call a Web Service Asynchronously

Accessing Application Settings
Processing Drives, Directories, and Files
Development with My
Performing Tasks with My.Application, My.Computer, and My.User
Default Object Instances Provided by My.Forms and My.WebServices
Rapid Application Development with My.Resources and My.Settings
Overview of the Visual Basic Application Model
How My Depends on Project Type
Accessing Data
Creating and Using Components
Printing and Reporting
PrintForm Component
How to: Print a Scrollable Form
How to: Print Client and Non-Client Areas of a Form
How to: Print the Client Area of a Form
How to: Print a Form by Using the PrintForm Component
Deploying Applications That Reference the PrintForm Component
Adding Printable Reports to Visual Studio Applications
Windows Forms Application Basics
Power Packs Controls
DataRepeater Control
Introduction to the DataRepeater Control
Virtual Mode in the DataRepeater Control
How to: Display Bound Data in a DataRepeater Control
How to: Display Unbound Controls in a DataRepeater Control
How to: Change the Layout of a DataRepeater Control
How to: Change the Appearance of a DataRepeater Control
How to: Display Item Headers in a DataRepeater Control
How to: Disable Adding and Deleting DataRepeater Items
How to: Search Data in a DataRepeater Control
How to: Create a Master-Detail Form by Using Two DataRepeater Controls
Walkthrough: Displaying Data in a DataRepeater Control

Troubleshooting the DataRepeater Control
Line and Shape Controls
Introduction to the Line and Shape Controls
How to: Draw Lines with the LineShape Control
How to: Draw Shapes with the OvalShape and RectangleShape Controls
How to: Enable Tabbing Between Shapes
Deploying Applications That Reference Power Packs Controls
Customizing Projects and Extending My with Visual Basic
Extending the My Namespace
Packaging and Deploying Custom My Extensions
Extending the Visual Basic Application Model
Customizing Which Objects are Available in My
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
Walkthrough: Creating and Implementing 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
Configure language version
Typographic and Code Conventions
Visual Basic Runtime Library Members
Keywords
Arrays Summary
Collection Object Summary
Control Flow Summary
Conversion Summary
Data Types Summary
Dates and Times Summary
Declarations and Constants Summary
Directories and Files Summary
Errors Summary
Financial Summary
Information and Interaction Summary
Input and Output Summary
Math Summary
Derived Math Functions
My Reference
Operators Summary
Registry Summary
String Manipulation Summary
Attributes
Constants and Enumerations

Data Type Summary
Boolean Data Type
Byte Data Type
Char Data Type
Date Data Type
Decimal Data Type
Double Data Type
Integer Data Type
Long Data Type
Object Data Type
SByte Data Type
Short Data Type
Single Data Type
String Data Type
UInteger Data Type
ULong Data Type
User-Defined Data Type
UShort Data Type
Directives
#Const Directive
#ExternalSource Directive
#If...Then...#Else Directives
#Region Directive
Functions
Conversion Functions
Math Functions
String Functions
Type Conversion Functions
Return Values for the CStr Function
CType Function
Modifiers
Ansi

Assembly
Async
Auto
ByRef
ByVal
Default
Friend
In (Generic Modifier)
Iterator
Key
Module 
MustInherit
MustOverride
Narrowing
NotInheritable
NotOverridable
Optional
Out (Generic Modifier)
Overloads
Overridable
Overrides
ParamArray
Partial
Private
Protected
Public
ReadOnly
Shadows
Shared
Static
Unicode
Widening

WithEvents
WriteOnly
Modules
Nothing
Objects
My.Application Object
My.Application.Info Object
My.Application.Log Object
My.Computer Object
My.Computer.Audio Object
My.Computer.Clipboard Object
My.Computer.Clock Object
My.Computer.FileSystem Object
My.Computer.FileSystem.SpecialDirectories Object
My.Computer.Info Object
My.Computer.Keyboard Object
My.Computer.Mouse Object
My.Computer.Network Object
My.Computer.Ports Object
My.Computer.Registry Object
My.Forms Object
My.Log Object
My.Request Object
My.Response Object
My.Resources Object
My.Settings Object
My.User Object
My.WebServices Object
TextFieldParser Object
Operators
Operator Precedence
Operators Listed by Functionality

& Operator
&= Operator
* Operator
*= Operator
+ Operator
+= Operator
= Operator
- Operator
-= Operator
<< Operator
<<= Operator
>> Operator
>>= Operator
/ Operator
/= Operator
\ Operator
\= Operator
^ Operator
^= Operator
AddressOf Operator
And Operator
AndAlso Operator
Await Operator
Function Expression
GetType Operator
GetXmlNamespace Operator
If Operator
Is Operator
IsFalse Operator
IsNot Operator
IsTrue Operator
Like Operator

Mod Operator
Not Operator
Or Operator
OrElse Operator
Sub Expression
TypeOf Operator
Xor Operator
Data Types of Operator Results
DirectCast Operator
TryCast Operator
New Operator
Arithmetic Operators
Assignment Operators
Bit Shift Operators
Comparison Operators
Concatenation Operators
Logical-Bitwise Operators
Miscellaneous Operators
Properties
Queries
Aggregate Clause
Distinct Clause
Equals Clause
From Clause
Group By Clause
Group Join Clause
Join Clause
Let Clause
Order By Clause
Select Clause
Skip Clause
Skip While Clause

Take Clause
Take While Clause
Where Clause
Statements
A-E Statements
AddHandler Statement
Call Statement
Class Statement
Const Statement
Continue Statement
Declare Statement
Delegate Statement
Dim Statement
Do...Loop Statement
Else Statement
End Statement
End  Statement
Enum Statement
Erase Statement
Error Statement
Event Statement
Exit Statement
F-P Statements
For Each...Next Statement
For...Next Statement
Function Statement
Get Statement
GoTo Statement
If...Then...Else Statement
Implements Statement
Imports Statement (.NET Namespace and Type)
Imports Statement (XML Namespace)

Inherits Statement
Interface Statement
Mid Statement
Module Statement
Namespace Statement
On Error Statement
Operator Statement
Option  Statement
Option Compare Statement
Option Explicit Statement
Option Infer Statement
Option Strict Statement
Property Statement
Q-Z Statements
RaiseEvent Statement
ReDim Statement
REM Statement
RemoveHandler Statement
Resume Statement
Return Statement
Select...Case Statement
Set Statement
Stop Statement
Structure Statement
Sub Statement
SyncLock Statement
Then Statement
Throw Statement
Try...Catch...Finally Statement
Using Statement
While...End While Statement
With...End With Statement

Yield Statement
Clauses
Alias Clause
As Clause
Handles Clause
Implements Clause
In Clause
Into Clause
Of Clause
Declaration Contexts and Default Access Levels
Attribute List
Parameter List
Type List
XML Comment Tags

















XML Axis Properties

XML Attribute Axis Property
XML Child Axis Property
XML Descendant Axis Property
Extension Indexer Property
XML Value Property
XML Literals
XML Element Literal
XML Document Literal
XML CDATA Literal
XML Comment Literal
XML Processing Instruction Literal
Error Messages
'#ElseIf' must be preceded by a matching '#If' or '#ElseIf'
'#Region' and '#End Region' statements are not valid within method bodiesmultiline lambdas
'' cannot be applied because the format of the GUID '' is not
correct
'' is not CLS-compliant because the interface '' it
implements is not CLS-compliant
'' is obsolete (Visual Basic Warning)
'' is an event, and cannot be called directly
'' cannot be used as a type constraint
'' is not declared (Smart Device-Visual Basic Compiler Error)
'.' is already implemented by the base class
''. Re-implementation of  assumed
'' is valid only within an instance method
'' cannot expose type '' outside the project through
 ''
'' is ambiguous across the inherited interfaces ''
and ''
 This error could also be due to mixing a file reference with a project
reference to assembly ''
'' has multiple definitions with identical signatures
'' is ambiguous in the namespace ''

'' is ambiguous, imported from the namespaces or types ''
 is not CLS-compliant because it overloads
 which differs from it only by array of array parameter types
or by the rank of the array parameter types
'' must implement '' for interface
''
'' must implement '' for interface
''
'' cannot inherit from  '' because it expands
the access of the base  outside the assembly
'' is a delegate type
'' is a type and cannot be used as an expression
A double quote is not a valid comment token for delimited fields where
EscapeQuote is set to True
A property or method call cannot include a reference to a private object, either as
an argument or as a return value
A reference was created to embedded interop assembly '' because of
an indirect reference to that assembly from assembly ''
A startup form has not been specified
Access of shared member through an instance; qualifying expression will not be
evaluated
'AddressOf' operand must be the name of a method (without parentheses)
An unexpected error has occurred because an operating system resource required
for single instance startup cannot be acquired
Anonymous type member name can be inferred only from a simple or qualified
name with no arguments
Argument not optional
Array bounds cannot appear in type specifiers
Array declared as for loop control variable cannot be declared with an initial size
Array subscript expression missing
Arrays declared as structure members cannot be declared with an initial size
'As Any' is not supported in 'Declare' statements
Attribute '' cannot be applied multiple times
Automation error
Bad checksum value, non hex digits or odd number of hex digits

Bad DLL calling convention
Bad file mode
Bad file name or number
Bad record length
Because this call is not awaited, the current method continues to run before the call
is completed
Cannot convert anonymous type to expression tree because it contains a field that
is used in the initialization of another field
Cannot create ActiveX Component
Cannot refer to '' because it is a member of the value-typed field
'' of class '' which has 'System.MarshalByRefObject' as a base
class
Cannot refer to an instance member of a class from within a shared method or
shared member initializer without an explicit instance of the class
Can't create necessary temporary file
Can't open '' for writing
Class '' cannot be found
Class does not support Automation or does not support expected interface
'Class' statement must end with a matching 'End Class'
Clipboard format is not valid
Constant expression not representable in type ''
Constants must be of an intrinsic or enumerated type, not a class, structure, type
parameter, or array type
Constructor '' cannot call itself
Copying the value of 'ByRef' parameter '' back to the matching
argument narrows from type '' to type ''
'Custom' modifier is not valid on events declared without explicit delegate types
Data type(s) of the type parameter(s) cannot be inferred from these arguments
Declaration expected
Default property '' conflicts with default property
'' in '' and so should be declared 'Shadows'
Default property access is ambiguous between the inherited interface members
'' of interface '' and
'' of interface ''
Delegate class '' has no Invoke method, so an expression of this type

cannot be the target of a method call
Derived classes cannot raise base class events
Device I/O error
'Dir' function must first be called with a 'PathName' argument
End of statement expected
Error creating assembly manifest: 
Error creating Win32 resources: 
Error in loading DLL
Error saving temporary Win32 resource file '': 
Errors occurred while compiling the XML schemas in the project
Evaluation of expression or statement timed out
Event '' cannot implement event '' on interface
'' because their delegate types '' and '' do not
match
Events cannot be declared with a delegate type that has a return type
Events of shared WithEvents variables cannot be handled by non-shared methods
Expression does not produce a value
Expression has the type '' which is a restricted type and cannot be
used to access members inherited from 'Object' or 'ValueType'
Expression is a value and therefore cannot be the target of an assignment
Expression of type  is not queryable
Expression recursively calls the containing property ''
Expression too complex
'Extension' attribute can be applied only to 'Module', 'Sub', or 'Function'
declarations
File already open
File is too large to read into a byte array
File name or class name not found during Automation operation
File not found (Visual Basic Run-Time Error)
First operand in a binary 'If' expression must be nullable or a reference type
First statement of this 'Sub New' must be a call to 'MyBase.New' or 'MyClass.New'
(No Accessible Constructor Without Parameters)
First statement of this 'Sub New' must be an explicit call to 'MyBase.New' or
'MyClass.New' because the '' in the base class

'' of '' is marked obsolete: ''
'For Each' on type '' is ambiguous because the type implements
multiple instantiations of 'System.Collections.Generic.IEnumerable(Of T)'
Friend assembly reference  is invalid
Function '' doesn't return a value on all code paths
Function evaluation is disabled because a previous function evaluation timed out
Generic parameters used as optional parameter types must be class constrained
'Get' accessor of property '' is not accessible
Handles clause requires a WithEvents variable defined in the containing type or
one of its base types
Identifier expected
Identifier is too long
Initializer expected
Input past end of file
Internal error happened at 
Implicit conversion from '' to '' in copying the value of
'ByRef' parameter '' back to the matching argument.
'Is' requires operands that have reference types, but this operand has the value
type ''
'IsNot' operand of type 'typename' can only be compared to 'Nothing', because
'typename' is a nullable type
Labels that are numbers must be followed by colons
Lambda expression will not be removed from this event handler
Lambda expressions are not valid in the first expression of a 'Select Case' statement
Late bound resolution; runtime errors could occur
Latebound overload resolution cannot be applied to '' because
the accessing instance is an interface type
Leading '.' or '!' can only appear inside a 'With' statement
Line is too long
'Line' statements are no longer supported (Visual Basic Compiler Error)
Method does not have a signature compatible with the delegate
Methods of 'System.Nullable(Of T)' cannot be used as operands of the 'AddressOf'
operator
'Module' statements can occur only at file or namespace level

Name  is not CLS-compliant
Name '' is not declared
Name  in the root namespace  is not
CLS-compliant
Namespace or type specified in the Imports '' doesn't
contain any public member or cannot be found
Namespace or type specified in the project-level Imports
'' doesn't contain any public member or cannot be found
Need property array index
Nested function does not have a signature that is compatible with delegate
''
No accessible 'Main' method with an appropriate signature was found in ''
Non-CLS-compliant  is not allowed in a CLS-compliant interface
Nullable type inference is not supported in this context
Number of indices exceeds the number of dimensions of the indexed array
Object or class does not support the set of events
Object required
Object variable or With block variable not set
Operator declaration must be one of: +,-,*,-,-,^, &, Like, Mod, And, Or, Xor, Not,
<<, >>, =, <>, <, <=, >, >=, CType, IsTrue, IsFalse
'Optional' expected
Optional parameters must specify a default value
Ordinal is not valid
Out of memory (Visual Basic Compiler Error)
Out of stack space
Out of string space
Overflow (Visual Basic Error)
Overflow (Visual Basic Run-Time Error)
Path not found
Path-File access error
Permission denied
Procedure call or argument is not valid
Property '' doesn't return a value on all code paths
Property array index is not valid

Property let procedure not defined and property get procedure did not return an
object
Property not found
Property or method not found
Range variable  hides a variable in an enclosing block, a previously
defined range variable, or an implicitly declared variable in a query expression
Range variable name can be inferred only from a simple or qualified name with no
arguments
Reference required to assembly '' containing type
'', but a suitable reference could not be found due to ambiguity
between projects '' and ''
Reference required to assembly '' containing the base class
''
Resume without error
Return type of function '' is not CLS-compliant
'Set' accessor of property '' is not accessible
Some subkeys cannot be deleted
Statement cannot end a block outside of a line 'If' statement
Statement is not valid in a namespace
Statement is not valid inside a method-multiline lambda
String constants must end with a double quote
Structure '' must contain at least one instance member variable or
at least one instance event declaration not marked 'Custom'
'Sub Main' was not found in ''
Sub or Function not defined
Subscript out of range
TextFieldParser is unable to complete the read operation because maximum buffer
size has been exceeded
The type for variable '' will not be inferred because it is bound to a
field in an enclosing scope
This array is fixed or temporarily locked
This key is already associated with an element of this collection
Too many files
Type '' has no constructors
Type  is not CLS-compliant

Type '' is not defined
Type arguments could not be inferred from the delegate
Type mismatch
Type of '' cannot be inferred because the loop bounds and the
step variable do not widen to the same type
Type of member '' is not CLS-compliant
Type of optional value for optional parameter  is not CLScompliant
Type of parameter '' is not CLS-compliant
Type parameters cannot be used as qualifiers
Unable to create strong-named assembly from key file '': 
Unable to embed resource file '': 
Unable to emit assembly: 
Unable to find required file ''
Unable to get serial port names because of an internal system error
Unable to link to resource file '': 
Unable to load information for class ''
Unable to write output to memory
Unable to write temporary file because temporary path is not available
Unable to write to output file '': 
Underlying type  of Enum is not CLS-compliant
Using the iteration variable in a lambda expression may have unexpected results
Value of type '' cannot be converted to ''
Value of type '' cannot be converted to '' (Multiple file
references)
Value of type 'type1' cannot be converted to 'type2'
Variable '' hides a variable in an enclosing block
Variable '' is used before it has been assigned a value
Variable uses an Automation type not supported in Visual Basic
XML axis properties do not support late binding
XML comment exception must have a 'cref' attribute
XML entity references are not supported
XML literals and XML properties are not supported in embedded code within

ASP.NET
XML namespace URI '' can be bound only to 'xmlns'
Reference
Command-Line Compiler
Building from the Command Line
How to: Invoke the Command-Line Compiler
Sample Compilation Command Lines
Compiler Options Listed Alphabetically
@ (Specify Response File)
-addmodule
-baseaddress
-bugreport
-codepage
-debug
-define
-delaysign
-deterministic
-doc
-errorreport
-filealign
-help, /?
-highentropyva
-imports
-keycontainer
-keyfile
-langversion
-libpath
-link
-linkresource
-main
-moduleassemblyname
-netcf

-noconfig
-nologo
-nostdlib
-nowarn
-nowin32manifest
-optimize
-optioncompare
-optionexplicit
-optioninfer
-optionstrict
-out
-platform
-quiet
-recurse
-reference
-refonly
-refout
-removeintchecks
-resource
-rootnamespace
-sdkpath
-target
-subsystemversion
-utf8output
-vbruntime
-verbose
-warnaserror
-win32icon
-win32manifest
-win32resource
Compiler Options Listed by Category
.NET Framework Reference Information

Language Specification
Sample Applications
Walkthroughs
ML.NET Guide
Tutorials
Sentiment analysis (binary classification)
Taxi fare predictor (regression)
Iris clustering
Resources
Machine learning glossary
Machine learning basics
Machine learning tasks
Samples and Tutorials

Welcome to .NET
5/1/2018 • 2 minutes to read • Edit Online

See Get 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
Microsoft Build 2018
Announcing the .NET Framework 4.7.2
Announcing .NET Core 2.1 Preview 2
ASP.NET Core 2.1.0-preview2 now available
Announcing Entity Framework Core 2.1 Preview 2
Visual Studio 2017 version 15.6, Visual Studio for Mac version 7.4 Released
Welcome to C# 7.2 and Span
.NET Core 2.0 Released!
Announcing .NET Standard 2.0
New for Visual Basic: .NET Standard Class Libraries and the dotnet CLI!
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 F# 4.1 and the Visual F# Tools for Visual Studio 2017

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
This 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 also 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
6/29/2018 • 2 minutes 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 want a high-level overview about .NET, check out What is .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.

New to .NET Core
If you're new to .NET Core, check out Get Started with .NET Core.

New to .NET Standard
If you're new to .NET Standard, check out .NET Standard.

Porting .NET Framework Code to .NET Core
If you're looking to port an application, service, or some component of a system to .NET Core, check out Porting to .NET Core from .NET Framework.

Porting a NuGet package from .NET Framework to .NET Standard or .NET Core
If you're looking to port a NuGet package to .NET Standard, check out Porting to .NET Core from .NET Framework. Tooling for .NET Standard and .NET
Core are shared, so the content will be relevant for porting to .NET Standard as well as .NET Core.

Interested in Major .NET Concepts
If you're interested in some of the major concepts of .NET, check out:
.NET Architectural Components
.NET Standard
Native Interoperability
Garbage Collection
Base Types in .NET
Collections
Dates, times, and time zones
Asynchronous Programming
Additionally, check out each language guide to learn about the three major .NET languages:
C# Guide
F# Guide
Visual Basic Guide

API Reference
Check out the .NET API Reference to see the breadth of APIs available.

Get Started
5/2/2018 • 2 minutes 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.

Get started using .NET languages
The C# Getting Started articles and C# Tutorials provide a number of ways to get started in a C#-centric way.
The F# Getting Started tutorials provide three primary ways you can use F#: with Visual Studio, Visual Studio Code, or command-line tools.
The Visual Basic Getting Started articles provide guides for using Visual Basic in Visual Studio.

Get started using .NET Core
Getting Started with .NET Core provides an overview of articles which show how to get started with .NET Core on different operating systems
and using different tools.
The .NET Core Tutorials detail a number of ways you can get started with .NET Core using your operating system and tooling of choice.

Get started using Docker on .NET Framework
Docker on .NET Framework shows how you can use .NET Framework on Windows Docker containers.

Tour of .NET
6/22/2018 • 9 minutes to read • Edit Online

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

How to run the code samples
To learn how to set up a development environment to run the code samples, see the Getting Started topic. Copy and paste code samples from this page
into your environment to execute them.

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.

Automatic memory management
.NET uses garbage collection (GC ) to provide automatic memory management for programs. The GC operates on a lazy approach to memory
management, preferring app throughput to the immediate collection of memory. To learn more about the .NET GC, check out Fundamentals of garbage
collection (GC ).
The following two lines both allocate memory:
var title = ".NET Primer";
var list = new List();

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:

int[] numbers = new int[42];
int number = numbers[42]; // Will throw an exception (indexes are 0-based)

Working with unmanaged resources
Some objects reference unmanaged resources. Unmanaged resources are resources that aren't automatically maintained by the .NET runtime. For
example, a file handle is an unmanaged resource. A FileStream object is a managed object, but it references a file handle, which is unmanaged. When
you're done using the FileStream, you need to release the file handle.
In .NET, objects that reference unmanaged resources implement the IDisposable interface. When you're done using the object, you call the object's
Dispose() method, which is responsible for releasing any unmanaged resources. .NET languages provide a convenient using syntax for such objects, as
shown in the following example:

using System.IO;
using (FileStream stream = GetFileStream(context))
{
// Operations on the stream
}

Once the using block completes, the .NET runtime automatically calls the
runtime also does this if an exception causes control to leave the block.

stream

object's Dispose() method, which releases the file handle. The

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.
Dog dog = AnimalShelter.AdoptDog(); // Returns a Dog type.
Pet pet = (Pet)dog; // Dog derives from Pet.
pet.ActCute();
Car car = (Car)dog; // Will throw - no relationship between Car and Dog.
object temp = (object)dog; // Legal - a Dog is an object.

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:
var dog = AnimalShelter.AdoptDog();
var pet = (Pet)dog;
pet.ActCute();
Car car = (Car)dog; // will throw - no relationship between Car and Dog
object temp = (object)dog; // legal - a Dog is an object
car = (Car)temp; // will throw - the runtime isn't fooled
car.Accelerate() // the dog won't like this, nor will the program get this far

F# has even further type inference capabilities than the method-local type inference found in C# and VB. To learn more, see Type Inference.

Delegates and lambdas
A delegate is represented by a method signature. Any method with that signature can be assigned to the delegate and is executed when the delegate is
invoked.
Delegates are like C++ function pointers except that they're type safe. They're a kind of disconnected method within the CLR type system. Regular
methods are attached to a class and are only directly callable through static or instance calling conventions.
In .NET, delegates are commonly used in event handlers, in defining asynchronous operations, and in lambda expressions, which are a cornerstone of
LINQ. Learn more in the Delegates and lambdas topic.

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 types:
using System;
using System.Collections.Generic;
namespace GenericsSampleShort
{
public static void Main(string[] args)
{
// List is the client way of specifying the actual type for the type parameter T
List listOfStrings = new List { "First", "Second", "Third" };
// listOfStrings can accept only strings, both on read and write.
listOfStrings.Add("Fourth");
// Below will throw a compile-time error, since the type parameter
// specifies this list as containing only strings.
listOfStrings.Add(1);
}
}

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.

Language Integrated Query (LINQ)
LINQ is a powerful set of features for C# and VB that allow you to write simple, declarative code for operating on data. The data can be in many forms
(such as in-memory objects, a SQL database, or an XML document), but the LINQ code you write typically doesn't differ by data source.
To learn more and see some samples, see the LINQ (Language Integrated Query) 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
efficiently implement an algorithm by moving around chunks of memory directly:

unsafe

code can

public override String ToString()
{
if (Length == 0)
return String.Empty;
string ret = string.FastAllocateString(Length);
StringBuilder chunk = this;
unsafe
{
fixed (char* destinationPtr = ret)
{
do
{
if (chunk.m_ChunkLength > 0)
{
// Copy these into local variables so that they are stable even in the presence of ----s (hackers might do this)
char[] sourceArray = chunk.m_ChunkChars;
int chunkOffset = chunk.m_ChunkOffset;
int chunkLength = chunk.m_ChunkLength;
// Check that we will not overrun our boundaries.
if ((uint)(chunkLength + chunkOffset) <= ret.Length && (uint)chunkLength <= (uint)sourceArray.Length)
{
fixed (char* sourcePtr = sourceArray)
string.wstrcpy(destinationPtr + chunkOffset, sourcePtr, chunkLength);
}
else
{
throw new ArgumentOutOfRangeException("chunkLength", Environment.GetResourceString("ArgumentOutOfRange_Index"));
}
}
chunk = chunk.m_ChunkPrevious;
} while (chunk != null);
}
}
return ret;
}

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.

.NET architectural components
5/2/2018 • 4 minutes 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. Mono also powers games built using the Unity engine.
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

.NET tooling and common infrastructure
You have access to an extensive set of tools and infrastructure components that work with every implementation of .NET. These include, but are not
limited to the following:
The .NET languages and their compilers
The .NET project system (based on .csproj, .vbproj, and .fsproj files)
MSBuild, the build engine used to build projects
NuGet, Microsoft's package manager for .NET
Open-source build orchestration tools, such as CAKE and FAKE

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
7/20/2018 • 8 minutes 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's 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 implementation support
The following table lists the minimum platform versions that support each .NET Standard version.
.NET
STANDARD

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

.NET
Framework 1

4.5

4.5

4.5.1

4.6

4.6.1

4.6.1

4.6.1

4.6.1

Mono

4.6

4.6

4.6

4.6

4.6

4.6

4.6

5.4

Xamarin.iOS

10.0

10.0

10.0

10.0

10.0

10.0

10.0

10.14

Xamarin.Mac

3.0

3.0

3.0

3.0

3.0

3.0

3.0

3.8

Xamarin.Andro
id

7.0

7.0

7.0

7.0

7.0

7.0

7.0

8.0

Universal
Windows
Platform

10.0

10.0

10.0

10.0

10.0

10.0.16299

10.0.16299

10.0.16299

Windows

8.0

8.0

8.1

Windows
Phone

8.1

8.1

8.1

Windows
Phone
Silverlight

8.0

1 The versions listed for .NET Framework apply to .NET Core SDK 2.0 and later versions of the tooling. Older versions used a different mapping for .NET Standard 1.5 and higher.

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.
For an interactive table, see .NET Standard versions.
To find the highest version of .NET Standard that you can target, do the following steps:
1.
2.
3.
4.

Find the row that indicates the .NET implementation you want to run on.
Find the column in that row that indicates your version starting from right to left.
The column header indicates the .NET Standard version that your target supports (and any lower .NET Standard versions will also support it).
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 first become available in specific .NET implementations, such as .NET Core.
If the .NET Standard review board believes the new APIs should be available for all .NET implementations, they're 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 are 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. For the broadest set of APIs, target netstandard2.0 since the number of available APIs more than doubled between .NET Standard 1.6
and 2.0.
The

metapackage references the complete set of NuGet packages that define .NET Standard. The most common way to target
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.
NETStandard.Library

netstandard

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.

Targeting .NET Standard
You can build .NET Standard Libraries using a combination of the
examples of targeting the .NET Standard with .NET Core tools.

netstandard

framework and the NETStandard.Library metapackage. You can see

.NET Framework compatibility mode
Starting with .NET Standard 2.0, the .NET Framework compatibility mode was introduced. This compatibility mode allows .NET Standard projects to
reference .NET Framework libraries as if they were compiled for .NET Standard. Referencing .NET Framework libraries doesn't work for all projects,
such as libraries that use Windows Presentation Foundation (WPF ) APIs.
For more information, see .NET Framework compatibility mode.

.NET Standard libraries and Visual Studio
In order to build .NET Standard libraries in Visual Studio, make sure you have Visual Studio 2017 version 15.3 or later installed on Windows, or Visual
Studio for Mac version 7.1 or later installed on macOS.
If you only need to consume .NET Standard 2.0 libraries in your projects, you can also do that in Visual Studio 2015. However, you need NuGet client
3.6 or higher installed. You can download the NuGet client for Visual Studio 2015 from the NuGet downloads page.

Comparison to Portable Class Libraries
.NET Standard is the replacement for Portable Class Libraries (PCL ). The .NET Standard improves on the experience of creating portable libraries by
curating a standard BCL and establishing greater uniformity across .NET implementations as a result. A library that targets .NET Standard is a PCL or a
".NET Standard-based PCL". Existing PCLs are "profile-based PCLs".
.NET Standard and PCL profiles were created for similar purposes but also differ in key ways.
Similarities:
Define APIs that can be used for binary code sharing.
Differences:
.NET Standard is a curated set of APIs, while PCL profiles are defined by intersections of existing platforms.
.NET Standard linearly versions, while PCL profiles do not.
PCL profiles represents Microsoft platforms while the .NET Standard is platform-agnostic.
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
with existing users.

netstandard

are easier to consume than typically packaged profile-based PCLs.

netstandard

packaging is compatible

You can see the set of PCL profiles that are compatible with the .NET Standard:
PCL PROFILE

.NET STANDARD

PCL PLATFORMS

Profile7

1.1

.NET Framework 4.5, Windows 8

Profile31

1.0

Windows 8.1, Windows Phone Silverlight 8.1

Profile32

1.2

Windows 8.1, Windows Phone 8.1

Profile44

1.2

.NET Framework 4.5.1, Windows 8.1

Profile49

1.0

.NET Framework 4.5, Windows Phone Silverlight 8

Profile78

1.0

.NET Framework 4.5, Windows 8, Windows Phone
Silverlight 8

Profile84

1.0

Windows Phone 8.1, Windows Phone Silverlight 8.1

Profile111

1.1

.NET Framework 4.5, Windows 8, Windows Phone 8.1

PCL PROFILE

.NET STANDARD

PCL PLATFORMS

Profile151

1.2

.NET Framework 4.5.1, Windows 8.1, Windows Phone
8.1

Profile157

1.0

Windows 8.1, Windows Phone 8.1, Windows Phone
Silverlight 8.1

Profile259

1.0

.NET Framework 4.5, Windows 8, Windows Phone 8.1,
Windows Phone Silverlight 8

See also
.NET Standard Versions

What's new in the .NET Standard
5/2/2018 • 3 minutes to read • Edit Online

The .NET Standard is a formal specification that defines a versioned set of APIs that must be available on .NET implementations that comply with that
version of the standard. The .NET Standard is targeted at library developers. A library that targets a .NET Standard version can be used on any .NET
Framework, .NET Core, or Xamarin implementation that supports that version of the standard.
The most recent version of the .NET Standard is 2.0. It is included with the .NET Core 2.0 SDK, as well as with Visual Studio 2017 Version 15.3 with the
.NET Core workload installed.

Supported .NET implementations
The .NET Standard 2.0 is supported by the following .NET implementations:
.NET Core 2.0 or later
.NET Framework 4.6.1 or later
Mono 5.4 or later
Xamarin.iOS 10.14 or later
Xamarin.Mac 3.8 or later
Xamarin.Android 8.0 or later
Universal Windows Platform 10.0.16299 or later

What's new in the .NET Standard 2.0
The .NET Standard 2.0 includes the following new features:
A vastly expanded set of APIs
Through version 1.6, the .NET Standard included a comparatively small subset of APIs. Among those excluded were many APIs that were commonly
used in the .NET Framework or Xamarin. This complicates development, since it requires that developers find suitable replacements for familiar APIs
when they develop applications and libraries that target multiple .NET implementations. The .NET Standard 2.0 addresses this limitation by adding over
20,000 more APIs than were available in .NET Standard 1.6, the previous version of the standard. For a list of the APIs that have been added to the .NET
Standard 2.0, see .NET Standard 2.0 vs 1.6.
Some of the additions to the System namespace in .NET Standard 2.0 include:
Support for the AppDomain class.
Better support for working with arrays from additional members in the Array class.
Better support for working with attributes from additional members in the Attribute class.
Better calendar support and additional formatting options for DateTime values.
Additional Decimal rounding functionality.
Additional functionality in the Environment class.
Enhanced control over the garbage collector through the GC class.
Enhanced support for string comparison, enumeration, and normalization in the String class.
Support for daylight saving adjustments and transition times in the TimeZoneInfo.AdjustmentRule and TimeZoneInfo.TransitionTime classes.
Significantly enhanced functionality in the Type class.
Better support for deserialization of exception objects by adding an exception constructor with SerializationInfo and StreamingContext parameters.
Support for .NET Framework libraries
The overwhelming majority of libraries target the .NET Framework rather than .NET Standard. However, most of the calls in those libraries are to APIs
that are included in the .NET Standard 2.0. Starting with the .NET Standard 2.0, you can access .NET Framework libraries from a .NET Standard library
by using a compatibility shim. This compatibility layer is transparent to developers; you don't have to do anything to take advantage of .NET Framework
libraries.
The single requirement is that the APIs called by the .NET Framework class library must be included in the .NET Standard 2.0.
Support for Visual Basic
You can now develop .NET Standard libraries in Visual Basic. For Visual Basic developers using Visual Studio 2017 Version 15.3 or later with the .NET
Core workload installed, Visual Studio now includes a .NET Standard Class Library template. For Visual Basic developers who use other development
tools and environments, you can use the dotnet new command to create a .NET Standard Library project. For more information, see the Tooling support
for .NET Standard libraries.
Tooling support for .NET Standard libraries
With the release of .NET Core 2.0 and .NET Standard 2.0, both Visual Studio 2017 and the .NET Core Command Line Interface (CLI) include tooling
support for creating .NET Standard libraries.
If you install Visual Studio with the .NET Core cross-platform development workload, you can create a .NET Standard 2.0 library project by using a

project template, as the following figure shows:
C#
Visual Basic

If you're using the .NET Core CLI, the following dotnet new command creates a class library project that targets the .NET Standard 2.0:
dotnet new classlib

See also
.NET Standard
Introducing .NET Standard

Target frameworks
6/2/2018 • 4 minutes 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.

Latest target framework versions
The following table defines the most common target frameworks, how they're referenced, and which version of the .NET Standard they implement.
These target framework versions are the latest stable versions. Pre-release versions aren't shown. A Target Framework Moniker (TFM ) is a standardized
token format for specifying the target framework of a .NET app or library.
TARGET FRAMEWORK

LATEST
STABLE VERSION

TARGET FRAMEWORK MONIKER (TFM)

IMPLEMENTED
.NET STANDARD VERSION

.NET Standard

2.0

netstandard2.0

N/A

.NET Core

2.1

netcoreapp2.1

2.0

.NET Framework

4.7.2

net472

2.0

Supported target framework versions
A target framework is typically referenced by a TFM. The following table shows the target frameworks supported by the .NET Core SDK and the NuGet
client. Equivalents are shown within brackets. For example, win81 is an equivalent TFM to netcore451 .
TARGET FRAMEWORK

TFM

.NET Standard

netstandard1.0
netstandard1.1
netstandard1.2
netstandard1.3
netstandard1.4
netstandard1.5
netstandard1.6
netstandard2.0

.NET Core

netcoreapp1.0
netcoreapp1.1
netcoreapp2.0
netcoreapp2.1

.NET Framework

net11
net20
net35
net40
net403
net45
net451
net452
net46
net461
net462
net47
net471
net472

TARGET FRAMEWORK

TFM

Windows Store

netcore [netcore45]
netcore45 [win] [win8]
netcore451 [win81]

.NET Micro Framework

netmf

Silverlight

sl4
sl5

Windows Phone

wp [wp7]
wp7
wp75
wp8
wp81
wpa81

Universal Windows Platform

uap [uap10.0]
uap10.0 [win10] [netcore50]

How to specify target frameworks
Target frameworks are specified in your project file. When a single target framework is specified, use the TargetFramework element. The following
console app project file demonstrates how to target .NET Core 2.0:


Exe
netcoreapp2.0



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:


netstandard1.4;net40;net45












Within your library or app, you write conditional code to compile for each target framework:
public class MyClass
{
static void Main()
{
#if NET40
Console.WriteLine("Target framework: .NET Framework 4.0");
#elif NET45
Console.WriteLine("Target framework: .NET Framework 4.5");
#else
Console.WriteLine("Target framework: .NET Standard 1.4");
#endif
}
}

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

.NET Framework

SYMBOLS
NET20

.NET Standard

,
,

NET35

,

,

NET45

,

NET451

,

NET472

NETSTANDARD1_0

,
,

NETSTANDARD1_1

NETSTANDARD1_4

.NET Core

NET40

NET471

NET47

NETCOREAPP1_0

,

NETSTANDARD1_5

NETCOREAPP1_1

,

,
,

,

NET452

,

NET46

NETSTANDARD1_2
NETSTANDARD1_6

NETCOREAPP2_0

,

,
,

,

NET461

NETSTANDARD1_3
NETSTANDARD2_0

NETCOREAPP2_1

Deprecated target frameworks
The following target frameworks are deprecated. Packages targeting these target frameworks should migrate to the indicated replacements.
DEPRECATED TFM

REPLACEMENT

aspnet50
aspnetcore50
dnxcore50
dnx
dnx45
dnx451
dnx452

netcoreapp

dotnet
dotnet50
dotnet51
dotnet52
dotnet53
dotnet54
dotnet55
dotnet56

netstandard

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

,

NET462

,

,

.NET Glossary
5/2/2018 • 10 minutes 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 crossmodule 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. Refer to ASP.NET 4.x when you want to make it clear that you’re not using ASP.NET to mean both
implementations.
See ASP.NET documentation.

ASP.NET Core
A cross-platform, high-performance, open source implementation of ASP.NET built on .NET Core.
See ASP.NET Core documentation.

assembly
A .dll/.exe file that can contain a collection of APIs that can be called by apps or other assemblies.
An assembly may include types such as 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
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 apps that require 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.

.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 Core CLI
A cross-platform toolchain for developing .NET Core applications.
See .NET Core command-line interface (CLI) tools.

.NET Core SDK
A set of libraries and tools that allow developers to create .NET Core applications and libraries. Includes the .NET Core CLI for building apps, .NET Core
libraries and runtime for building and running apps, and the dotnet executable (dotnet.exe) that runs CLI commands and runs applications.
See .NET Core SDK Overview.

.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 ).
See .NET Standard.

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 target 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 implementationspecific 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

.NET Architecture Guidance
7/3/2018 • 2 minutes to read • Edit Online

Containerized Docker Application Lifecycle with the Microsoft Platform and Tools
This guide is an introduction to the recommended end to end lifecycle processes you'll use to develop, validate, and deploy containerized Docker
applications using Visual Studio and Microsoft Azure.

Modernize Existing .NET Applications with Azure cloud and Windows Containers
This guide is an introduction to the strategies you'll need to migrate existing web applications to the Azure cloud and Windows containers. You'll learn
about code strategies, data migration, orchestrators, and CI/CD processes.

Architect modern web applications with ASP.NET Core and Azure
This guide is an introduction to the recommended architecture, design, and deployment processes you'll use to build ASP.NET and ASP.NET Core
applications and host those applications in Azure.

Architecting Container and Microservice Based Applications
This guide is an introduction to developing microservices-based applications and managing them using containers. It discusses architectural design and
implementation approaches using .NET Core and Docker containers.

Serverless apps: Architecture, patterns, and Azure implementation
This is a guide for building serverless applications with examples using Azure. It discusses various architecture and design approaches, the benefits and
challenges that come with serverless, and provides scenarios and use cases for serverless apps.

Architect Modern Web Applications with ASP.NET Core and Azure
7/10/2018 • 3 minutes to read • Edit Online

PUBLISHED BY
Microsoft Developer Division, .NET, and Visual Studio product teams
A division of Microsoft Corporation
One Microsoft Way

Redmond, Washington 98052-6399
Copyright © 2018 by Microsoft Corporation
All rights reserved. No part of the contents of this book may be reproduced or transmitted in any form or by any means without the written permission
of the publisher.
This book is provided “as-is” and expresses the author’s views and opinions. The views, opinions and information expressed in this book, including URL
and other Internet website references, may change without notice.
Some examples depicted herein are provided for illustration only and are fictitious. No real association or connection is intended or should be inferred.
Microsoft and the trademarks listed at https://www.microsoft.com on the “Trademarks” webpage are trademarks of the Microsoft group of companies.
Mac and macOS are trademarks of Apple Inc.
The Docker whale logo is a registered trademark of Docker, Inc. Used by permission.
All other marks and logos are property of their respective owners.
Author:
Steve Smith (@ardalis), Software Architecture Advisor, Ardalis.com
Editors:
Maira Wenzel

Introduction
.NET Core and ASP.NET Core offer several advantages over traditional .NET development. You should use .NET Core for your server applications if
some or all of the following are important to your application's success:
Cross-platform support.
Use of microservices.
Use of Docker containers.
High performance and scalability requirements.
Side-by-side versioning of .NET versions by application on the same server.
Traditional .NET applications can and do support these requirements, but ASP.NET Core and .NET Core have been optimized to offer improved support
for the above scenarios.
More and more organizations are choosing to host their web applications in the cloud using services like Microsoft Azure. You should consider hosting
your application in the cloud if the following are important to your application or organization:
Reduced investment in data center costs (hardware, software, space, utilities, etc.)
Flexible pricing (pay based on usage, not for idle capacity).
Extreme reliability.
Improved app mobility; easily change where and how your app is deployed.
Flexible capacity; scale up or down based on actual needs.
Building web applications with ASP.NET Core, hosted in Azure, offers many competitive advantages over traditional alternatives. ASP.NET Core is
optimized for modern web application development practices and cloud hosting scenarios. In this guide, you'll learn how to architect your ASP.NET
Core applications to best take advantage of these capabilities.

Purpose
This guide provides end-to-end guidance on building monolithic web applications using ASP.NET Core and Azure.
This guide is complementary to the ".NET Microservices. Architecture for Containerized .NET Applications" which focuses more on Docker,
Microservices, and Deployment of Containers to host enterprise applications.
.NET Microservices. Architecture for Containerized .NET Applications
e-book
https://aka.ms/MicroservicesEbook
Sample Application
https://aka.ms/microservicesarchitecture

Who should use this guide
The audience for this guide is mainly developers, development leads, and architects who are interested in building modern web applications using

Microsoft technologies and services in the cloud.
A secondary audience is technical decision makers who are already familiar ASP.NET or Azure and are looking for information on whether it makes
sense to upgrade to ASP.NET Core for new or existing projects.

How you can use this guide
This guide has been condensed into a relatively small document that focuses on building web applications with modern .NET technologies and
Windows Azure. As such, it can be read in its entirety to provide a foundation of understanding such applications and their technical considerations. The
guide, along with its sample application, can also serve as a starting point or reference. Use the associated sample application as a template for your
own applications, or to see how you might organize your application's component parts. Refer back to the guide's principles and coverage of
architecture and technology options and decision considerations when you're weighing these choices for your own application.
Feel free to forward this guide to your team to help ensure a common understanding of these considerations and opportunities. Having everybody
working from a common set of terminology and underlying principles helps ensure consistent application of architectural patterns and practices.

References
Choosing between .NET Core and .NET Framework for server apps
https://docs.microsoft.com/dotnet/standard/choosing-core-framework-server

NEXT

Modernize existing .NET applications with Azure cloud and Windows
Containers (2nd edition)
6/22/2018 • 15 minutes to read • Edit Online

PUBLISHED BY
Microsoft Press and Microsoft DevDiv
Divisions of Microsoft Corporation
One Microsoft Way
Redmond, Washington 98052-6399

Copyright © 2018 by Microsoft Corporation
All rights reserved. No part of the contents of this book may be reproduced in any form or by any means without the written permission of the
publisher.
This book is available for free in the form of an electronic book (e-book) available through multiple channels at Microsoft such as
http://dot.net/architecture.
If you have questions related to this book, email at dotnet-architecture-ebooks-feedback@service.microsoft.com
This book is provided "as-is" and expresses the author's views and opinions. The views, opinions, and information expressed in this book, including URL
and other Internet website references, may change without notice.
Some examples depicted herein are provided for illustration only and are fictitious. No real association or connection is intended or should be inferred.
Microsoft and the trademarks listed at http://www.microsoft.com on the "Trademarks" webpage are trademarks of the Microsoft group of companies.
All other marks are property of their respective owners.
Author:
Cesar de la Torre, Sr. PM, .NET Product Team, Microsoft Corp.
Participants and reviewers:
Scott Hunter, Partner Director PM, .NET team, Microsoft
Paul Yuknewicz, Principal PM Manager, Visual Studio Tools team, Microsoft
Lisa Guthrie, Sr. PM, Visual Studio Tools team, Microsoft
Ankit Asthana, Principal PM Manager, .NET team, Microsoft
Unai Zorrilla, Developer Lead, Plain Concepts
Javier Valero, Chief Operating Officer at Grupo Solutio

Introduction
When you decide to modernize your web applications or services and move them to the cloud, you don't necessarily have to fully rearchitect your apps.
Rearchitecting an application by using an advanced approach like microservices isn't always an option because of cost and time restraints. Depending
on the type of application, rearchitecting an app also might not be necessary. To optimize the cost-effectiveness of your organization's cloud migration
strategy, it's important to consider the needs of your business and requirements of your apps. You'll need to determine:
Which apps require a transformation or rearchitecting.
Which apps need to be only partially modernized.
Which apps you can "lift and shift" directly to the cloud.

About this guide
This guide focuses primarily on initial modernization of existing Microsoft .NET Framework web or service-oriented applications, meaning the action of
moving a workload to a newer or more modern environment without significantly altering the application's code and basic architecture.
This guide also highlights the benefits of moving your apps to the cloud and partially modernizing apps by using a specific set of new technologies and
approaches, like Windows Containers and related compute-platforms in Azure supporting Windows Containers.

Path to the cloud for existing .NET applications
Organizations typically choose to move to the cloud for the agility and speed they can get for their applications. You can set up thousands of servers
(VMs) in the cloud in minutes, compared to the weeks it typically takes to set up on-premises servers.
There isn't a single, one-size-fits-all strategy for migrating applications to the cloud. The right migration strategy for you will depend on your
organization's needs and priorities, and the kind of applications you are migrating. Not all applications warrant the investment of moving to a platform
as a service (PaaS ) model or developing a cloud-native application model. In many cases, you can take a phased or incremental approach to invest in
moving your assets to the cloud, based on your business needs.
For modern applications with the best long-term agility and value for the organization, you might benefit from investing in cloud-native application
architectures. However, for applications that are existing or legacy assets, the key is to spend minimal time and money (no rearchitecting or code
changes) while moving them to the cloud, to realize significant benefits.
Figure 1-1 shows the possible paths you can take when you move existing .NET applications to the cloud in incremental phases.

Figure 1-1. Modernization paths for existing .NET applications and services
Each migration approach has different benefits and reasons for using it. You can choose a single approach when you migrate apps to the cloud, or
choose certain components from multiple approaches. Individual applications aren't limited to a single approach or maturity state. For instance, a
common hybrid approach would have certain on-premises components plus other components in the cloud.
The definition and short explanation for each application maturity level are the following:
Level 1: Cloud Infrastructure-Ready applications: In this migration approach, you simply migrate or rehost your current on-premises applications to
an infrastructure as a service (IaaS ) platform. Your apps have almost the same composition as before, but now you deploy them to VMs in the cloud.
This simple type of migration is typically known in the industry as "Lift & Shift."
Level 2: Cloud Optimized applications: At this level and still without rearchitecting or altering significant code, you can gain additional benefits from
running your app in the cloud with modern technologies like containers and additional cloud-managed services. You improve the agility of your
applications to ship faster by refining your enterprise development operations (DevOps) processes. You achieve this by using technologies like
Windows Containers, which is based on Docker Engine. Containers remove the friction that’s caused by application dependencies when you deploy in
multiple stages. In this maturity model, you can deploy containers on IaaS or PaaS while using additional cloud-managed services related to databases,
cache as a service, monitoring, and continuous integration/continuous deployment (CI/CD ) pipelines.
The third level of maturity is the ultimate goal in the cloud, but it's optional for many apps and not the main focus of this guide:
Level 3: Cloud-Native applications: This migration approach typically is driven by business need and targets modernizing your mission-critical
applications. At this level, you use PaaS services to move your apps to PaaS computing platforms. You implement cloud-native applications and
microservices architecture to evolve applications with long-term agility, and to scale to new limits. This type of modernization usually requires
architecting specifically for the cloud. New code often must be written, especially when you move to cloud-native application and microservice-based
models. This approach can help you gain benefits that are difficult to achieve in your monolithic and on-premises application environment.
Table 1-1 describes the main benefits of and reasons for choosing each migration or modernization approach.
CLOUD INFRASTRUCTURE-READY
LIFT AND SHIFT

CLOUD-OPTIMIZED
MODERNIZE

CLOUD-NATIVE
MODERNIZE, REARCHITECT AND REWRITE

Monolithic or N-Tier apps deployed to Azure App
Service, Azure Container Instance (ACI), VMs with
containers, Azure Service Fabric, or AKS (Azure
Kubernetes Service)

Containerized microservices on Azure Kubernetes
Service (AKS), Service Fabric and/or serverless
microservices based on Azure Functions.

Azure SQL Database Managed Instance or another
managed database in the cloud.

Fined-grain databases per microservice, based on
Azure SQL Database, Azure Cosmos DB, or another
managed database in the cloud

Application's compute target
Applications deployed to VMs in Azure

Data target
SQL or any relational database on a VM

Advantages

CLOUD INFRASTRUCTURE-READY
LIFT AND SHIFT

CLOUD-OPTIMIZED
MODERNIZE

CLOUD-NATIVE
MODERNIZE, REARCHITECT AND REWRITE

No rearchitecting, no new code
Least effort for quick migration
Least-common denominator supported in Azure
Basic availability guarantees
After moving to the cloud, it's easier to modernize
even more

No rearchitecting
Minimal code/config changes
Improved deployment and DevOps agility to
release because of containers
Increased density and lower deployment costs
Portability of apps and dependencies
Flexibility of host targets: PaaS approaches or IaaS

Architect for the cloud, you get the best benefits
from the cloud but new code is needed
Microservices cloud-native approaches
Modern mission-critical applications, cloud-resilient
hyper-scalable
Fully managed services
Optimized for scale
Optimized for autonomous agility by subsystem
Built on deployment and DevOps

Containerizing is an additional step in the learning
curve for developers and IT Operations
DevOps and CI/CD pipelines is usually ‘a must’ for
this approach. If not currently present in the culture
of the organization, it might be an additional
challenge

Requires rearchitecture for cloud native apps and
microservice architectures and usually requires
significant code refactoring or rewriting when
modernizing (increased time and budget)
DevOps and CI/CD pipelines is usually ‘a must’ for
this approach. If not currently present in the culture
of the organization, it might be an additional
challenge

Challenges
Smaller cloud value, other than shift in operating
expense or closing datacenters
Little is managed: No OS or middleware patching;
might use infrastructure solutions, like Terraform,
Spinnaker, or Puppet

Table 1-1. Benefits and challenges of modernization paths for existing .NET applications and services
Key technologies and architectures by maturity level
.NET Framework applications initially started with the .NET Framework version 1.0, which was released in late 2001. Then, companies moved towards
newer versions (such as 2.0, 3.5 and .NET 4.x). Most of those applications ran on Windows Server and Internet Information Server (IIS ), and used a
relational database, like SQL Server, Oracle, MySQL, or any other RDBMS.
Most existing .NET applications might nowadays be based on .NET Framework 4.x, or even on .NET Framework 3.5, and use web frameworks like
ASP.NET MVC, ASP.NET Web Forms, ASP.NET Web API, Windows Communication Foundation (WCF ), ASP.NET SignalR, and ASP.NET Web Pages.
These established .NET Framework technologies depend on Windows. That dependency is important to consider if you are simply migrating legacy
apps and you want to make minimal changes to your application infrastructure.
Figure 1-2 shows the primary technologies and architecture styles used at each of the three cloud maturity levels:

Figure 1-2. Primary technologies for each maturity level for modernizing existing .NET web applications
Figure 1-2 highlights the most common scenarios, but many hybrid and mixed variations are possible when it comes to architecture. For example, the
maturity models apply not only to monolithic architectures in existing web apps, but also to service orientation, N-Tier, and other architecture style
variations. The higher focus or percentage on one or another architecture type and related technologies determines the overall maturity level of your
applications.
Each maturity level in the modernization process is associated with the following key technologies and approaches:
Cloud Infrastructure-Ready (rehost or basic lift & shift): As a first step, many organizations want only to quickly execute a cloud-migration

strategy. In this case, applications are rehosted. Most rehosting can be automated by using Azure Migrate, a service that provides the guidance,
insights, and mechanisms needed to assist you in migrating to Azure based on cloud tools like Azure Site Recovery and Azure Database
Migration Service. You can also set up rehosting manually, so that you can learn infrastructure details about your assets when you move legacy
apps to the cloud. For example, you can move your applications to VMs in Azure with little modification-probably with only minor configuration
changes. The networking in this case is similar to an on-premises environment, especially if you create virtual networks in Azure.
Cloud-Optimized (Managed Services and Windows Containers): This model is about making a few important deployment optimizations to
gain some significant benefits from the cloud, without changing the core architecture of the application. The fundamental step here is to add
Windows Containers support to your existing .NET Framework applications. This important step (containerization) doesn't require touching the
code, so the overall lift and shift effort is light. You can use tools like Image2Docker or Visual Studio, with its tools for Docker. Visual Studio
automatically chooses smart defaults for ASP.NET applications and Windows Containers images. These tools offer both a rapid inner loop, and a
fast path to get the containers to Azure. Your agility is improved when you deploy to multiple environments. Then, moving to production, you can
deploy your Windows Containers to Azure Web App for Containers, [Azure Container Instances (ACI), and Azure VMs with Windows Server
2016 and containers if you prefer an IaaS approach. For slightly more complex multi-container applications, into orchestrators like Azure Service
Fabric or Azure Kubernetes Service (AKS/ACS ). During this initial modernization, you can also add assets from the cloud, such as monitoring
with tools like Azure Application Insights; CI/CD pipelines for your app lifecycles with Visual Studio Team Services; and many more data
resource services that are available in Azure. For instance, you can modify a monolithic web app that was originally developed by using
traditional ASP.NET Web Forms or ASP.NET MVC, but now you deploy it by using Windows Containers. When you use Windows Containers,
you should also migrate your data to a database in Azure SQL Database Managed Instance, all without changing the core architecture of your
application.
Cloud-Native: As introduced, you should think about architecting cloud-native applications when you are targeting large and complex
applications with multiple independent development teams working on different microservices that can be developed and deployed
autonomously. Also, due to granularized and independent scalability per microservice. These architectural approaches face very important
challenges and complexities but can be greatly simplified by using cloud PaaS and orchestrators like Azure Kubernetes Service (AKS/ACS )
(managed Kubernetes), [Azure Service Fabric, and Azure Functions for a serverless approach. All these approaches (like microservices and
Serverless) typically require you to architect for the cloud and write new code—code that is adapted to specific PaaS platforms, or code that
aligns with specific architectures, like microservices.
Figure 1-3 shows the internal technologies that you can use for each maturity level:

Figure 1-3. Internal technologies for each modernization maturity level

Lift and shift scenario
For lift and shift migrations, keep in mind that you can use many different variations of lift and shift in your application scenarios. If you only rehost
your application, you might have a scenario like the one shown in Figure 1-4, where you use VMs in the cloud only for your application and for your
database server.

Figure 1-4. Example of a pure IaaS scenario in the cloud

Modernization scenarios
For modernization scenarios, you might have a pure Cloud-Optimized application that uses elements only from that maturity level. Or, you might have
an intermediate-state application with some elements from Cloud Infrastructure-Ready and other elements from Cloud-Optimized (a "pick and choose"
or mixed model), like in Figure 1-5.

Figure 1-5. Example "pick and choose" scenario, with database on IaaS, DevOps, and containerization assets
Next, as the ideal scenario for many existing .NET Framework applications to migrate, you could migrate to a Cloud-Optimized application, to get
significant benefits from little work. This approach also sets you up for Cloud-Native as a possible future evolution. Figure 1-6 shows an example.

Figure 1-6. Example Cloud-Optimized apps scenario, with Windows Containers and managed services

Going even further, you could extend your existing Cloud-Optimized application by adding a few microservices for specific scenarios. This would move
you partially to the level of Cloud-Native model, which is not the main focus of the present guidance.

What this guide does not cover
This guide covers a specific subset of the example scenarios, as shown in Figure 1-7. This guide focuses only on lift and shift scenarios, and ultimately,
on the Cloud-Optimized model. In the Cloud-Optimized model, a .NET Framework application is modernized by using Windows Containers, plus
additional components like monitoring and CI/CD pipelines. Each component is fundamental to deploying applications to the cloud, faster, and with
agility.

Figure 1-7. Cloud-Native is not covered in this guide
The focus of this guide is specific. It shows you the path you can take to achieve a lift and shift of your existing .NET applications, without rearchitecting,
and with no code changes. Ultimately, it shows you how to make your application Cloud-Optimized.
This guide doesn't show you how to create Cloud-Native applications, such as how to evolve to a microservices architecture. To rearchitect your
applications or to create brand-new applications that are based on microservices, see the e-book .NET Microservices: Architecture for containerized
.NET applications.
Additional resources
Containerized Docker application lifecycle with Microsoft platform and tools (downloadable e-book):
https://aka.ms/dockerlifecycleebook
.NET Microservices: Architecture for containerized .NET applications (downloadable e-book): https://aka.ms/microservicesebook
Architecting modern web applications with ASP.NET Core and Azure (downloadable e-book): https://aka.ms/webappebook

Who should use this guide
This guide was written for developers and solution architects who want to modernize existing ASP.NET web applications or WCF services that are
based on the .NET Framework, for improved agility in shipping and releasing applications.
You also might find this guide useful if you are a technical decision maker, such as an enterprise architect or a development lead/director who just wants
an overview of the benefits that you can get by using Windows Containers, and by deploying to the cloud when using Microsoft Azure.

How to use this guide
This guide addresses the "why"-why you might want to modernize your existing applications, and the specific benefits you get from using Windows
Containers when you move your apps to the cloud. The content in the first few chapters of the guide is designed for architects and technical decision
makers who want an overview, but who don't need to focus on implementation and technical, step-by-step details.
The last chapter of this guide introduces multiple walkthroughs that focus on specific deployment scenarios. This guide offers shorter versions of the
walkthroughs, to summarize the scenarios and highlight their benefits. The full walkthroughs drill down into setup and implementation details, and are
published as a set of wiki posts in the same public GitHub repo where related sample apps reside (discussed in the next section). The last chapter and
the step-by-step wiki walkthroughs on GitHub will be of more interest to developers and architects who want to focus on implementation details.

Sample apps for modernizing legacy apps: eShopModernizing
The eShopModernizing repo on GitHub offers two sample applications that simulate legacy monolithic web applications. One web app is developed by
using ASP.NET MVC; the second web app is developed by using ASP.NET Web Forms and the third app is an N-Tier app with a WinForms client
desktop app consuming a WCF service backend. All these apps are based on the traditional .NET Framework. These sample apps don't use .NET Core
or ASP.NET Core as they are supposed to be existing/legacy .NET Framework applications to be modernized.
These sample apps have a second version, with modernized code, and which are fairly straightforward. The most important difference between the app
versions is that the second versions use Windows Containers as the deployment choice. There also are a few additions to the second versions, like
Azure Storage Blobs for managing images, Azure Active Directory for managing security, and Azure Application Insights for monitoring and auditing
the applications.

Send your feedback
This guide was written to help you understand your options for improving and modernizing existing .NET web applications. The guide and related
sample applications are evolving. Your feedback is welcome! If you have comments about how this guide might be more helpful, please send them to
dotnet-architecture-ebooks-feedback@service.microsoft.com.

NEXT

Introduction to containers and Docker
6/29/2018 • 2 minutes to read • Edit Online

Containerization is an approach to software development in which an application or service, its dependencies, and its configuration (abstracted as
deployment manifest files) are packaged together as a container image. You then can test the containerized application as a unit and deploy it as a
container image instance to the host operating system.
Just as the shipping industry uses standardized containers to move goods by ship, train, or truck, regardless of the cargo within them, software
containers act as a standard unit of software that can contain different code and dependencies. Placing software into containers makes it possible for
developers and IT professionals to deploy those containers across environments with little or no modification.
Containers also isolate applications from one another on a shared operating system (OS ). Containerized applications run on top of a container host,
which in turn runs on the OS (Linux or Windows). Thus, containers have a significantly smaller footprint than virtual machine (VM ) images.
Each container can run an entire web application or a service, as shown in Figure 1-1.

Figure 1-1: Multiple containers running on a container host
In this example, Docker Host is a container host, and App 1, App 2, Svc 1, and Svc 2 are containerized applications or services.
Another benefit you can derive from containerization is scalability. You can scale-out quickly by creating new containers for short-term tasks. From an
application point of view, instantiating an image (creating a container) is similar to instantiating a process like a service or web app. For reliability,
however, when you run multiple instances of the same image across multiple host servers, you typically want each container (image instance) to run in a
different host server or VM in different fault domains.
In short, containers offer the benefits of isolation, portability, agility, scalability, and control across the entire application life cycle workflow. The most
important benefit is the isolation provided between Dev and Ops.

NEXT

6/29/2018 • 5 minutes to read • Edit Online

.NET Microservices. Architecture for Containerized .NET Applications
DOWNLOAD available at: https://aka.ms/microservicesebook
PUBLISHED BY
Microsoft Developer Division, .NET and Visual Studio product teams

A division of Microsoft Corporation
One Microsoft Way
Redmond, Washington 98052-6399
Copyright © 2018 by Microsoft Corporation
All rights reserved. No part of the contents of this book may be reproduced or transmitted in any form or by any means without the written permission
of the publisher.
This book is provided “as-is” and expresses the author’s views and opinions. The views, opinions and information expressed in this book, including URL
and other Internet website references, may change without notice.
Some examples depicted herein are provided for illustration only and are fictitious. No real association or connection is intended or should be inferred.
Microsoft and the trademarks listed at http://www.microsoft.com on the “Trademarks” webpage are trademarks of the Microsoft group of companies.
Mac and macOS are trademarks of Apple Inc.
The Docker whale logo is a registered trademark of Docker, Inc. Used by permission.
All other marks and logos are property of their respective owners.
Co-Authors:
Cesar de la Torre, Sr. PM, .NET product team, Microsoft Corp.
Bill Wagner, Sr. Content Developer, C+E, Microsoft Corp.
Mike Rousos, Principal Software Engineer, DevDiv CAT team, Microsoft
Editors:
Mike Pope
Steve Hoag
Participants and reviewers:
Jeffrey Richter, Partner Software Eng, Azure team, Microsoft
Jimmy Bogard, Chief Architect at Headspring
Udi Dahan, Founder & CEO, Particular Software
Jimmy Nilsson, Co-founder and CEO of Factor10
Glenn Condron, Sr. Program Manager, ASP.NET team
Mark Fussell, Principal PM Lead, Azure Service Fabric team, Microsoft
Diego Vega, PM Lead, Entity Framework team, Microsoft
Barry Dorrans, Sr. Security Program Manager
Rowan Miller, Sr. Program Manager, Microsoft
Ankit Asthana, Principal PM Manager, .NET team, Microsoft
Scott Hunter, Partner Director PM, .NET team, Microsoft
Dylan Reisenberger, Architect and Dev Lead at Polly
Steve Smith, Software Craftsman & Trainer at ASPSmith Ltd.
Ian Cooper, Coding Architect at Brighter
Unai Zorrilla, Architect and Dev Lead at Plain Concepts
Eduard Tomas, Dev Lead at Plain Concepts
Ramon Tomas, Developer at Plain Concepts
David Sanz, Developer at Plain Concepts
Javier Valero, Chief Operating Officer at Grupo Solutio
Pierre Millet, Sr. Consultant, Microsoft
Michael Friis, Product Manager, Docker Inc
Charles Lowell, Software Engineer, VS CAT team, Microsoft

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

About this guide
This guide is an introduction to developing microservices-based applications and managing them using containers. It discusses architectural design and
implementation approaches using .NET Core and Docker containers. To make it easier to get started with containers and microservices, the guide
focuses on a reference containerized and microservice-based application that you can explore. The sample application is available at the
eShopOnContainers GitHub repo.
This guide provides foundational development and architectural guidance primarily at a development environment level with a focus on two
technologies: Docker and .NET Core. Our intention is that you read this guide when thinking about your application design without focusing on the
infrastructure (cloud or on-premises) of your production environment. You will make decisions about your infrastructure later, when you create your
production-ready applications. Therefore, this guide is intended to be infrastructure agnostic and more development-environment-centric.
After you have studied this guide, your next step would be to learn about production-ready microservices on Microsoft Azure.

What this guide does not cover
This guide does not focus on the application lifecycle, DevOps, CI/CD pipelines, or team work. The complementary guide Containerized Docker
Application Lifecycle with Microsoft Platform and Tools focuses on that subject. The current guide also does not provide implementation details on
Azure infrastructure, such as information on specific orchestrators.
Additional resources
Containerized Docker Application Lifecycle with Microsoft Platform and Tools (downloadable e-book) https://aka.ms/dockerlifecycleebook

Who should use this guide
We wrote this guide for developers and solution architects who are new to Docker-based application development and to microservices-based
architecture. This guide is for you if you want to learn how to architect, design, and implement proof-of-concept applications with Microsoft
development technologies (with special focus on .NET Core) and with Docker containers.
You will also find this guide useful if you are a technical decision maker, such as an enterprise architect, who wants an architecture and technology
overview before you decide on what approach to select for new and modern distributed applications.
How to use this guide
The first part of this guide introduces Docker containers, discusses how to choose between .NET Core and the .NET Framework as a development
framework, and provides an overview of microservices. This content is for architects and technical decision makers who want an overview but who do
not need to focus on code implementation details.
The second part of the guide starts with the Development process for Docker based applications section. It focuses on development and microservice
patterns for implementing applications using .NET Core and Docker. This section will be of most interest to developers and architects who want to focus
on code and on patterns and implementation details.

Related microservice and container-based reference application: eShopOnContainers
The eShopOnContainers application is a reference app for .NET Core and microservices that is designed to be deployed using Docker containers. The
application consists of multiple subsystems, including several e-store UI front ends (a Web app and a native mobile app). It also includes the back-end
microservices and containers for all required server-side operations.
This microservice and container-based application source code is open source and available at the eShopOnContainers GitHub repo.

Send us your feedback!
We wrote this guide to help you understand the architecture of containerized applications and microservices in .NET. The guide and related reference
application will be evolving, so we welcome your feedback! If you have comments about how this guide can be improved, please send them to:
dotnet-architecture-ebooks-feedback@service.microsoft.com

NEXT

7/3/2018 • 6 minutes to read • Edit Online

Serverless apps: Architecture, patterns, and Azure implementation
DOWNLOAD available at: https://aka.ms/serverless-ebook
PUBLISHED BY

Microsoft Developer Division, .NET, and Visual Studio product teams
A division of Microsoft Corporation
One Microsoft Way
Redmond, Washington 98052-6399
Copyright © 2018 by Microsoft Corporation
All rights reserved. No part of the contents of this book may be reproduced or transmitted in any form or by any means without the written permission
of the publisher.
This book is provided "as-is" and expresses the author's views and opinions. The views, opinions and information expressed in this book, including URL
and other Internet website references, may change without notice.
Some examples depicted herein are provided for illustration only and are fictitious. No real association or connection is intended or should be inferred.
Microsoft and the trademarks listed at https://www.microsoft.com on the "Trademarks" webpage are trademarks of the Microsoft group of companies.
Mac and macOS are trademarks of Apple Inc.
All other marks and logos are property of their respective owners.
Author:
Jeremy Likness, Sr. Cloud Developer Advocate, APEX, Microsoft Corp.
Contributor:
Cecil Phillip, Cloud Developer Advocate II, APEX, Microsoft Corp.
Editors:
Bill Wagner, Senior Content Developer, APEX, Microsoft Corp.
Maira Wenzel, Senior Content Developer, APEX, Microsoft Corp.
Participants and reviewers:
Steve Smith, Owner, Ardalis Services.

Introduction
Serverless is the evolution of cloud platforms in the direction of pure cloud native code. Serverless brings developers closer to business logic while
insulating them from infrastructure concerns. It's a pattern that doesn't imply "no server" but rather, "less server." Serverless code is event-driven. Code
may be triggered by anything from a traditional HTTP web request to a timer or the result of uploading a file. The infrastructure behind serverless
allows for instant scale to meet elastic demands and offers micro-billing to truly "pay for what you use." Serverless requires a new way of thinking and
approach to building applications and isn't the right solution for every problem. As a developer, you must decide:
What are the pros and cons of serverless?
Why should you consider serverless for your own applications?
How can you build, test, deploy, and maintain your serverless code?
Where does it make sense to migrate code to serverless in existing applications, and what is the best way to accomplish this transformation?

About this guide
This guide focuses on cloud native development of applications that use serverless. The book highlights the benefits and exposes the potential
drawbacks of developing serverless apps and provides a survey of serverless architectures. Many examples of how serverless can be used are
illustrated along with various serverless design patterns.
This guide explains the components of the Azure serverless platform and focuses specifically on implementation of serverless using Azure Functions.
You'll learn about triggers and bindings as well as how to implement serverless apps that rely on state using durable functions. Finally, business
examples and case studies will help provide context and a frame of reference to determine whether serverless is the right approach for your projects.

Evolution of cloud platforms
Serverless is the culmination of several iterations of cloud platforms. The evolution began with physical metal in the data center and progressed
through Infrastructure as a Service (IaaS ) and Platform as a Service (PaaS ).

Before the cloud, a discernible boundary existed between development and operations. Deploying an application meant answering myriad questions
like:
What hardware should be installed?
How is physical access to the machine secured?
Does the data center require an Uninterruptible Power Supply (UPS )?
Where are storage backups sent?
Should there be redundant power?
The list goes on and the overhead was enormous. In many situations, IT departments were forced to deal with incredible waste. The waste was due to
over-allocation of servers as backup machines for disaster recovery and standby servers to enable scale-out. Fortunately, the introduction of
virtualization technology (like Hyper-V ) with Virtual Machines (VMs) gave rise to Infrastructure as a Service (IaaS ). Virtualized infrastructure allowed
operations to set up a standard set of servers as the backbone, leading to a flexible environment capable of provisioning unique servers "on demand."
More important, virtualization set the stage for using the cloud to provide virtual machines "as a service." Companies could easily get out of the
business of worrying about redundant power or physical machines. Instead, they focused on the virtual environment.
IaaS still requires heavy overhead because operations is still responsible for various tasks. These tasks include:
Patching and backing up servers.
Installing packages.
Keeping the operating system up-to-date.
Monitoring the application.
The next evolution reduced the overhead by providing Platform as a Service (PaaS ). With PaaS, the cloud provider handles operating systems, security
patches, and even the required packages to support a specific platform. Instead of building a VM then configuring the .NET Framework and standing up
Internet Information Services (IIS ) servers, developers simply choose a "platform target" such as "web application" or "API endpoint" and deploy code
directly. The infrastructure questions are reduced to:
What size services are needed?
How do the services scale out (add more servers or nodes)?
How do the services scale up (increase the capacity of hosting servers or nodes)?
Serverless further abstracts servers by focusing on event-driven code. Instead of a platform, developers can focus on a microservice that does one
thing. The two key questions for building the serverless code are:
What triggers the code?
What does the code do?
With serverless, infrastructure is abstracted. In some cases, the developer no longer worries about the host at all. Whether or not an instance of IIS,
Kestrel, Apache, or some other web server is running to manage web requests, the developer focuses on an HTTP trigger. The trigger provides the
standard, cross-platform payload for the request. The payload not only simplifies the development process, but facilitates testing and in some cases,
makes the code easily portable across platforms.
Another feature of serverless is micro-billing. It's common for web applications to host Web API endpoints. In traditional bare metal, IaaS and even
PaaS implementations, the resources to host the APIs are paid for continuously. That means you pay to host the endpoints even when they aren't being
accessed. Often you'll find one API is called more than others, so the entire system is scaled based on supporting the popular endpoints. Serverless
enables you to scale each endpoint independently and pay for usage, so no costs are incurred when the APIs aren't being called. Migration may in many
circumstances dramatically reduce the ongoing cost to support the endpoints.

What this guide doesn't cover
This guide specifically emphasizes architecture approaches and design patterns and isn't a deep dive into the implementation details of Azure Functions,
Logic Apps, or other serverless platforms. This guide doesn't cover, for example, advanced workflows with Logic Apps or features of Azure Functions
such as configuring Cross-Origin Resource Sharing (CORS ), applying custom domains, or uploading SSL certificates. These details are available
through the online Azure Functions documentation.
Additional resources

Azure Architecture center
Best practices for cloud applications

Who should use the guide
This guide was written for developers and solution architects who want to build enterprise applications with .NET that may use serverless components
either on premises or in the cloud. It's useful to developers, architects, and technical decision makers interested in:
Understanding the pros and cons of serverless development
Learning how to approach serverless architecture
Example implementations of serverless apps

How to use the guide
The first part of this guide examines why serverless is a viable option by comparing several different architecture approaches. It examines both the
technology and development lifecycle, because all aspects of software development are impacted by architecture decisions. The guide then examines
use cases and design patterns and includes reference implementations using Azure Functions. Each section contains additional resources to learn more
about a particular area. The guide concludes with resources for walkthroughs and hands-on exploration of serverless implementation.

Send your feedback
The guide and related samples are constantly evolving, so your feedback is welcomed! If you have comments about how this guide can be improved,
use the feedback section at the bottom of any page built on GitHub issues.

NEXT

Choosing between .NET Core and .NET Framework for server apps
6/21/2018 • 6 minutes 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.

When to choose .NET Core
The following sections give a more detailed explanation of the previously stated reasons for picking .NET Core.
Cross-platform needs
If your application (web/service) needs to run on multiple platforms (Windows, Linux, and macOS ), use .NET Core.
.NET Core supports the previously mentioned operating systems as your development workstation. Visual Studio provides an Integrated Development
Environment (IDE ) for Windows and macOS. You can also use Visual Studio Code, which runs on macOS, Linux, and Windows. Visual Studio Code
supports .NET Core, including IntelliSense and debugging. Most third-party editors, such as Sublime, Emacs, and VI, work with .NET Core. These thirdparty editors get editor IntelliSense using Omnisharp. You can also avoid any code editor and directly use the .NET Core CLI tools, available for all
supported platforms.
Microservices architecture
A microservices architecture allows a mix of technologies across a service boundary. This technology mix enables a gradual embrace of .NET Core for
new microservices that work with other microservices or services. For example, you can mix microservices or services developed with .NET Framework,
Java, Ruby, or other monolithic technologies.
There are many infrastructure platforms available. Azure Service Fabric is designed for large and complex microservice systems. Azure App Service is a
good choice for stateless microservices. Microservices alternatives based on Docker fit any kind of microservices approach, as explained in the
Containers section. All these platforms support .NET Core and make them ideal for hosting your microservices.
For more information about microservices architecture, see .NET Microservices. Architecture for Containerized .NET Applications.
Containers
Containers are commonly used in conjunction with a microservices architecture. Containers can also be used to containerize web apps or services that
follow any architectural pattern. .NET Framework can be used on Windows containers, but the modularity and lightweight nature of .NET Core makes it
a better choice for containers. When creating and deploying a container, the size of its image is much smaller with .NET Core than with .NET
Framework. Because it's cross-platform, you can deploy server apps to Linux Docker containers, for example.
Docker containers can be hosted in your own Linux or Windows infrastructure, or in a cloud service such as Azure Container Service. Azure Container
Service can manage, orchestrate, and scale container-based applications in the cloud.
A need for high-performance and scalable systems
When your system needs the best possible performance and scalability, .NET Core and ASP.NET Core are your best options. High-performance server
runtime for Windows Server and Linux makes .NET a top performing web framework on TechEmpower benchmarks.
Performance and scalability are especially relevant for microservices architectures, where hundreds of microservices may be running. With ASP.NET
Core, systems run with a much lower number of servers/Virtual Machines (VM ). The reduced servers/VMs save costs in infrastructure and hosting.
A need for side by side of .NET versions per application level
To install applications with dependencies on different versions of .NET, we recommend .NET Core. .NET Core offers side-by-side installation of different
versions of the .NET Core runtime on the same machine. This side-by-side installation allows multiple services on the same server, each of them on its
own version of .NET Core. It also lowers risks and saves money in application upgrades and IT operations.

When to choose .NET Framework

.NET Core offers significant benefits for new applications and application patterns. However, the .NET Framework continues to be the natural choice for
many existing scenarios and as such the .NET Framework isn't replaced by .NET Core for all server applications.
Current .NET Framework applications
In most cases, you don’t need to migrate your existing applications to .NET Core. Instead, a recommended approach is to use .NET Core as you extend
an existing application, such as writing a new web service in ASP.NET Core.
A need to use third-party .NET libraries or NuGet packages not available for .NET Core
Libraries are quickly embracing .NET Standard. .NET Standard enables sharing code across all .NET implementations including .NET Core. With .NET
Standard 2.0, this is even easier:
The API surface became much larger.
Introduced a .NET Framework compatibility mode. This compatibility mode allows .NET Standard/.NET Core projects to reference .NET Framework
libraries. To learn more about the compatibility mode, see Announcing .NET Standard 2.0.
So only in cases where the libraries or NuGet packages use technologies that aren't available in .NET Standard/.NET Core, you need to use the .NET
Framework.
A need to use .NET technologies not available for .NET Core
Some .NET Framework technologies aren't available in .NET Core. Some of them might be available in later .NET Core releases. Others don’t apply to
the new application patterns targeted by .NET Core and may never be available. The following list shows the most common technologies not found in
.NET Core:
ASP.NET Web Forms applications: ASP.NET Web Forms are only available in the .NET Framework. ASP.NET Core cannot be used for ASP.NET
Web Forms. There are no plans to bring ASP.NET Web Forms to .NET Core.
ASP.NET Web Pages applications: ASP.NET Web Pages aren't included in ASP.NET Core. ASP.NET Core Razor Pages have many similarities with
Web Pages.
WCF services implementation. Even when there’s a WCF-Client library to consume WCF services from .NET Core, WCF server implementation
is currently only available in the .NET Framework. This scenario is not part of the current plan for .NET Core but it’s being considered for the
future.
Workflow-related services: Windows Workflow Foundation (WF ), Workflow Services (WCF + WF in a single service) and WCF Data Services
(formerly known as "ADO.NET Data Services") are only available in the .NET Framework. There are no plans to bring WF/WCF+WF/WCF Data
Services to .NET Core.
Language support: Visual Basic and F# are currently supported in .NET Core, but not for all project types. For a list of supported project
templates, see Template options for dotnet new.
In addition to the official roadmap, there are other frameworks to be ported to .NET Core. For a full list, see the CoreFX issues marked as port-to-core.
This list doesn’t represent a commitment from Microsoft to bring those components to .NET Core. They're simply capturing the desire from the
community to do so. If you care about any of the components marked as port-to-core , participate in the discussions on GitHub. And if you think
something is missing, file a new issue in the CoreFX repository.
A need to use a platform that doesn’t support .NET Core
Some Microsoft or third-party platforms don’t support .NET Core. For example, some Azure services such as Service Fabric Stateful Reliable Services
and Service Fabric Reliable Actors require .NET Framework. Some other services provide an SDK not yet available for consumption on .NET Core. This
is a transitional circumstance, as all of Azure services use .NET Core. In the meantime, you can always use the equivalent REST API instead of the client
SDK.

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"?
5/2/2018 • 2 minutes 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.

Intermediate Language & execution
What is "Intermediate Language" (or IL for short)? It is a product of compilation of code written in high-level .NET languages. Once you compile your
code written in one of these languages, you will get a binary that is made out of IL. It is important to note that the IL is independent from any specific
language that runs on top of the runtime; there is even a separate specification for it that you can read if you’re so inclined.
Once you produce IL from your high-level code, you will most likely want to run it. This is where the CLR takes over and starts the process of Just-InTime compiling, or JIT-ing your code from IL to machine code that can actually be run on a CPU. In this way, the CLR knows exactly what your code is
doing and can effectively manage it.
Intermediate Language is sometimes also called Common Intermediate Language (CIL ) or Microsoft Intermediate Language (MSIL ).

Unmanaged code interoperability
Of course, the CLR allows passing the boundaries between managed and unmanaged world, and there is a lot of code that does that, even in the Base
Class Libraries. This is called interoperability or just interop for short. These provisions would allow you to, for example, wrap up an unmanaged
library and call into it. However, it is important to note that once you do this, when the code passes the boundaries of the runtime, the actual
management of the execution is again in the hand of unmanaged code, and thus falls under the same restrictions.
Similar to this, C# is one language that allows you to use unmanaged constructs such as pointers directly in code by utilizing what is known as unsafe
context which designates a piece of code for which the execution is not managed by the CLR.

More resources
.NET Framework Conceptual Overview
Unsafe Code and Pointers
Interoperability (C# Programming guide)

Automatic Memory Management
5/2/2018 • 7 minutes 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.

Generations and Performance
To optimize the performance of the garbage collector, the managed heap is divided into three generations: 0, 1, and 2. The runtime's garbage collection
algorithm is based on several generalizations that the computer software industry has discovered to be true by experimenting with garbage collection
schemes. First, it is faster to compact the memory for a portion of the managed heap than for the entire managed heap. Secondly, newer objects will
have shorter lifetimes and older objects will have longer lifetimes. Lastly, newer objects tend to be related to each other and accessed by the application
around the same time.
The runtime's garbage collector stores new objects in generation 0. Objects created early in the application's lifetime that survive collections are
promoted and stored in generations 1 and 2. The process of object promotion is described later in this topic. Because it is faster to compact a portion of
the managed heap than the entire heap, this scheme allows the garbage collector to release the memory in a specific generation rather than release the
memory for the entire managed heap each time it performs a collection.
In reality, the garbage collector performs a collection when generation 0 is full. If an application attempts to create a new object when generation 0 is
full, the garbage collector discovers that there is no address space remaining in generation 0 to allocate for the object. The garbage collector performs a
collection in an attempt to free address space in generation 0 for the object. The garbage collector starts by examining the objects in generation 0 rather
than all objects in the managed heap. This is the most efficient approach, because new objects tend to have short lifetimes, and it is expected that many
of the objects in generation 0 will no longer be in use by the application when a collection is performed. In addition, a collection of generation 0 alone
often reclaims enough memory to allow the application to continue creating new objects.
After the garbage collector performs a collection of generation 0, it compacts the memory for the reachable objects as explained in Releasing Memory
earlier in this topic. The garbage collector then promotes these objects and considers this portion of the managed heap generation 1. Because objects
that survive collections tend to have longer lifetimes, it makes sense to promote them to a higher generation. As a result, the garbage collector does not
have to reexamine the objects in generations 1 and 2 each time it performs a collection of generation 0.
After the garbage collector performs its first collection of generation 0 and promotes the reachable objects to generation 1, it considers the remainder of

the managed heap generation 0. It continues to allocate memory for new objects in generation 0 until generation 0 is full and it is necessary to perform
another collection. At this point, the garbage collector's optimizing engine determines whether it is necessary to examine the objects in older
generations. For example, if a collection of generation 0 does not reclaim enough memory for the application to successfully complete its attempt to
create a new object, the garbage collector can perform a collection of generation 1, then generation 2. If this does not reclaim enough memory, the
garbage collector can perform a collection of generations 2, 1, and 0. After each collection, the garbage collector compacts the reachable objects in
generation 0 and promotes them to generation 1. Objects in generation 1 that survive collections are promoted to generation 2. Because the garbage
collector supports only three generations, objects in generation 2 that survive a collection remain in generation 2 until they are determined to be
unreachable in a future collection.

Releasing Memory for Unmanaged Resources
For the majority of the objects that your application creates, you can rely on the garbage collector to automatically perform the necessary memory
management tasks. However, unmanaged resources require explicit cleanup. The most common type of unmanaged resource is an object that wraps an
operating system resource, such as a file handle, window handle, or network connection. Although the garbage collector is able to track the lifetime of a
managed object that encapsulates an unmanaged resource, it does not have specific knowledge about how to clean up the resource. When you create
an object that encapsulates an unmanaged resource, it is recommended that you provide the necessary code to clean up the unmanaged resource in a
public Dispose method. By providing a Dispose method, you enable users of your object to explicitly free its memory when they are finished with the
object. When you use an object that encapsulates an unmanaged resource, you should be aware of Dispose and call it as necessary. For more
information about cleaning up unmanaged resources and an example of a design pattern for implementing Dispose, see Garbage Collection.

See Also
GC
Garbage Collection
Managed Execution Process

Common Language Runtime (CLR) overview
6/22/2018 • 4 minutes 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 crosslanguage 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 runtime 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.

CLR versions
The version number of the .NET Framework doesn't necessarily correspond to the version number of the CLR it includes. The following table shows
how the two version numbers correlate.

.NET FRAMEWORK VERSION

INCLUDES CLR VERSION

1.0

1.0

1.1

1.1

2.0

2.0

3.0

2.0

3.5

2.0

4

4

4.5 (including 4.5.1 and 4.5.2)

4

4.6 (including 4.6.1 and 4.6.2)

4

4.7 (including 4.7.1 and 4.7.2)

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.

Overview of the .NET Framework

Describes key .NET Framework concepts such as the common type system, crosslanguage 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
5/2/2018 • 68 minutes 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

CLS compliance rules
This section discusses the rules for creating a CLS-compliant component. For a complete list of rules, see Partition I, Clause 11 of the ECMA-335
Standard: Common Language Infrastructure.
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
type UInt16, the following code displays a compiler warning.

Person

class in the following example exposes an

Age

property of

using System;
[assembly: CLSCompliant(true)]
public class Person
{
private UInt16 personAge = 0;
public UInt16 Age
{ get { return personAge; } }
}
// The attempt to compile the example displays the following compiler warning:
//
Public1.cs(10,18): warning CS3003: Type of 'Person.Age' is not CLS-compliant


Public Class Person
Private personAge As UInt16
Public ReadOnly Property Age As UInt16
Get
Return personAge
End Get
End Property
End Class
' The attempt to compile the example displays the following compiler warning:
'
Public1.vb(9) : warning BC40027: Return type of function 'Age' is not CLS-compliant.
'
'
Public ReadOnly Property Age As UInt16
'
~~~

You can make the Person class CLS-compliant by changing the type of Age property from
integer. You do not have to change the type of the private personAge field.

UInt16

to Int16, which is a CLS-compliant, 16-bit signed

using System;
[assembly: CLSCompliant(true)]
public class Person
{
private Int16 personAge = 0;
public Int16 Age
{ get { return personAge; } }
}


Public Class Person
Private personAge As UInt16
Public ReadOnly Property Age As Int16
Get
Return CType(personAge, Int16)
End Get
End Property
End Class

A library's public interface consists of the following:
Definitions of public classes.
Definitions of the public members of public classes, and definitions of members accessible to derived classes (that is, protected members).
Parameters and return types of public methods of public classes, and parameters and return types of methods accessible to derived classes.
The rules for CLS compliance are listed in the following table. The text of the rules is taken verbatim from the ECMA-335 Standard: Common Language
Infrastructure, which is Copyright 2012 by Ecma International. More detailed information about these rules is found in the following sections.

CATEGORY

SEE

RULE

RULE NUMBER

Accessibility

Member accessibility

Accessibility shall not be changed when
overriding inherited methods, except
when overriding a method inherited
from a different assembly with
accessibility family-or-assembly . In
this case, the override shall have
accessibility family .

10

Accessibility

Member accessibility

The visibility and accessibility of types
and members shall be such that types
in the signature of any member shall
be visible and accessible whenever the
member itself is visible and accessible.
For example, a public method that is
visible outside its assembly shall not
have an argument whose type is visible
only within the assembly. The visibility
and accessibility of types composing an
instantiated generic type used in the
signature of any member shall be
visible and accessible whenever the
member itself is visible and accessible.
For example, an instantiated generic
type present in the signature of a
member that is visible outside its
assembly shall not have a generic
argument whose type is visible only
within the assembly.

12

Arrays

Arrays

Arrays shall have elements with a CLScompliant type, and all dimensions of
the array shall have lower bounds of
zero. Only the fact that an item is an
array and the element type of the array
shall be required to distinguish
between overloads. When overloading
is based on two or more array types
the element types shall be named
types.

16

Attributes

Attributes

Attributes shall be of type
System.Attribute, or a type inheriting
from it.

41

Attributes

Attributes

The CLS only allows a subset of the
encodings of custom attributes. The
only types that shall appear in these
encodings are (see Partition IV):
System.Type, System.String,
System.Char, System.Boolean,
System.Byte, System.Int16,
System.Int32, System.Int64,
System.Single, System.Double, and any
enumeration type based on a CLScompliant base integer type.

34

Attributes

Attributes

The CLS does not allow publicly visible
required modifiers ( modreq , see
Partition II), but does allow optional
modifiers ( modopt , see Partition II) it
does not understand.

35

Constructors

Constructors

An object constructor shall call some
instance constructor of its base class
before any access occurs to inherited
instance data. (This does not apply to
value types, which need not have
constructors.)

21

Constructors

Constructors

An object constructor shall not be
called except as part of the creation of
an object, and an object shall not be
initialized twice.

22

CATEGORY

SEE

RULE

RULE NUMBER

Enumerations

Enumerations

The underlying type of an enum shall
be a built-in CLS integer type, the
name of the field shall be "value__", and
that field shall be marked
RTSpecialName .

7

Enumerations

Enumerations

There are two distinct kinds of enums,
indicated by the presence or absence
of the System.FlagsAttribute (see
Partition IV Library) custom attribute.
One represents named integer values;
the other represents named bit flags
that can be combined to generate an
unnamed value. The value of an enum
is not limited to the specified values.

8

Enumerations

Enumerations

Literal static fields of an enum shall
have the type of the enum itself.

9

Events

Events

The methods that implement an event
shall be marked SpecialName in the
metadata.

29

Events

Events

The accessibility of an event and of its
accessors shall be identical.

30

Events

Events

The add and remove methods for
an event shall both either be present
or absent.

31

Events

Events

The add and remove methods for
an event shall each take one parameter
whose type defines the type of the
event and that shall be derived from
System.Delegate.

32

Events

Events

Events shall adhere to a specific
naming pattern. The SpecialName
attribute referred to in CLS rule 29
shall be ignored in appropriate name
comparisons and shall adhere to
identifier rules.

33

Exceptions

Exceptions

Objects that are thrown shall be of
type System.Exception or a type
inheriting from it. Nonetheless, CLScompliant methods are not required to
block the propagation of other types of
exceptions.

40

General

CLS compliance rules

CLS rules apply only to those parts of a
type that are accessible or visible
outsideof the defining assembly.

1

General

CLS compliance rules

Members of non-CLS compliant types
shall not be marked CLS-compliant.

2

Generics

Generic types and members

Nested types shall have at least as
many generic parameters as the
enclosing type. Generic parameters in a
nested type correspond by position to
the generic parameters in its enclosing
type.

42

Generics

Generic types and members

The name of a generic type shall
encode the number of type parameters
declared on the non-nested type, or
newly introduced to the type if nested,
according to the rules defined above.

43

Generics

Generic types and members

A generic type shall redeclare sufficient
constraints to guarantee that any
constraints on the base type, or
interfaces would be satisfied by the
generic type constraints.

44

CATEGORY

SEE

RULE

RULE NUMBER

Generics

Generic types and members

Types used as constraints on generic
parameters shall themselves be CLScompliant.

45

Generics

Generic types and members

The visibility and accessibility of
members (including nested types) in an
instantiated generic type shall be
considered to be scoped to the specific
instantiation rather than the generic
type declaration as a whole. Assuming
this, the visibility and accessibility rules
of CLS rule 12 still apply.

46

Generics

Generic types and members

For each abstract or virtual generic
method, there shall be a default
concrete (nonabstract) implementation

47

Interfaces

Interfaces

CLS-compliant interfaces shall not
require the definition of non-CLS
compliantmethods in order to
implement them.

18

Interfaces

Interfaces

CLS-compliant interfaces shall not
define static methods, nor shall they
define fields.

19

Members

Type members in general

Global static fields and methods are
not CLS-compliant.

36

Members

--

The value of a literal static is specified
through the use of field initialization
metadata. A CLS-compliant literal must
have a value specified in field
initialization metadata that is of exactly
the same type as the literal (or of the
underlying type, if that literal is an
enum ).

13

Members

Type members in general

The vararg constraint is not part of the
CLS, and the only calling convention
supported by the CLS is the standard
managed calling convention.

15

Naming conventions

Naming conventions

Assemblies shall follow Annex 7 of
Technical Report 15 of the Unicode
Standard3.0 governing the set of
characters permitted to start and be
included in identifiers, available online
at Unicode Normalization Forms.
Identifiers shall be in the canonical
format defined by Unicode
Normalization Form C. For CLS
purposes, two identifiersare the same if
their lowercase mappings (as specified
by the Unicode locale-insensitive, oneto-one lowercase mappings) are the
same. That is, for two identifiers to be
considered different under the CLS
they shall differ in more than simply
their case. However, in order to
override an inherited definition the CLI
requires the precise encoding of the
original declaration be used.

4

Overloading

Naming conventions

All names introduced in a CLScompliant scope shall be distinct
independent of kind, except where the
names are identical and resolved via
overloading. That is, while the CTS
allows a single type to use the same
name for a method and a field, the CLS
does not.

5

CATEGORY

SEE

RULE

RULE NUMBER

Overloading

Naming conventions

Fields and nested types shall be distinct
by identifier comparison alone,
eventhough the CTS allows distinct
signatures to be distinguished.
Methods, properties, and events that
have the same name (by identifier
comparison) shall differ by more than
just the return type,except as specified
in CLS Rule 39

6

Overloading

Overloads

Only properties and methods can be
overloaded.

37

Overloading

Overloads

Properties and methods can be
overloaded based only on the number
and types of their parameters, except
the conversion operators named
op_Implicit and op_Explicit ,
which can also be overloaded based on
their return type.

38

Overloading

--

If two or more CLS-compliant methods
declared in a type have the same
nameand, for a specific set of type
instantiations, they have the same
parameter and return types, then all
these methods shall be semantically
equivalent at those type instantiations.

48

Properties

Properties

The methods that implement the
getter and setter methods of a
property shall be marked
SpecialName in the metadata.

24

Properties

Properties

A property’s accessors shall all be
static, all be virtual, or all be instance.

26

Properties

Properties

The type of a property shall be the
return type of the getter and the type
of the last argument of the setter. The
types of the parameters of the
property shall be the types of the
parameters to the getter and the types
of all but the final parameter of the
setter. All of these types shall be CLScompliant, and shall not be managed
pointers (that is, shall not be passed by
reference).

27

Properties

Properties

Properties shall adhere to a specific
naming pattern. The SpecialName
attribute referred to in CLS rule 24
shall be ignored in appropriate name
comparisons and shall adhere to
identifier rules. A property shall have a
getter method, a setter method, or
both.

28

Type conversion

Type conversion

If either op_Implicit or op_Explicit is
provided, an alternate means of
providing the coercion shall be
provided.

39

Types

Types and type member signatures

Boxed value types are not CLScompliant.

3

Types

Types and type member signatures

All types appearing in a signature shall
be CLS-compliant. All types composing
an instantiated generic type shall be
CLS-compliant.

11

Types

Types and type member signatures

Typed references are not CLScompliant.

14

Types

Types and type member signatures

Unmanaged pointer types are not CLScompliant.

17

CATEGORY

SEE

RULE

RULE NUMBER

Types

Types and type member signatures

CLS-compliant classes, value types, and
interfaces shall not require the
implementation of non-CLS-compliant
members

20

Types

Types and type member signatures

System.Object is CLS-compliant. Any
other CLS-compliant class shall inherit
from a CLS-compliant class.

23

Types and type member signatures
The System.Object type is CLS-compliant and is the base type of all object types in the .NET Framework type system. Inheritance in the .NET
Framework is either implicit (for example, the String class implicitly inherits from the Object class) or explicit (for example, the
CultureNotFoundException class explicitly inherits from the ArgumentException class, which explicitly inherits from the Exception class. For a derived
type to be CLS compliant, its base type must also be CLS-compliant.
The following example shows a derived type whose base type is not CLS-compliant. It defines a base Counter class that uses an unsigned 32-bit
integer as a counter. Because the class provides counter functionality by wrapping an unsigned integer, the class is marked as non-CLS-compliant. As a
result, a derived class, NonZeroCounter , is also not CLS-compliant.
using System;
[assembly: CLSCompliant(true)]
[CLSCompliant(false)]
public class Counter
{
UInt32 ctr;
public Counter()
{
ctr = 0;
}
protected Counter(UInt32 ctr)
{
this.ctr = ctr;
}
public override string ToString()
{
return String.Format("{0}). ", ctr);
}
public UInt32 Value
{
get { return ctr; }
}
public void Increment()
{
ctr += (uint) 1;
}
}
public class NonZeroCounter : Counter
{
public NonZeroCounter(int startIndex) : this((uint) startIndex)
{
}
private NonZeroCounter(UInt32 startIndex) : base(startIndex)
{
}
}
// Compilation produces a compiler warning like the following:
//
Type3.cs(37,14): warning CS3009: 'NonZeroCounter': base type 'Counter' is not
//
CLS-compliant
//
Type3.cs(7,14): (Location of symbol related to previous warning)


 _
Public Class Counter
Dim ctr As UInt32
Public Sub New
ctr = 0
End Sub
Protected Sub New(ctr As UInt32)
ctr = ctr
End Sub
Public Overrides Function ToString() As String
Return String.Format("{0}). ", ctr)
End Function
Public ReadOnly Property Value As UInt32
Get
Return ctr
End Get
End Property
Public Sub Increment()
ctr += CType(1, UInt32)
End Sub
End Class
Public Class NonZeroCounter : Inherits Counter
Public Sub New(startIndex As Integer)
MyClass.New(CType(startIndex, UInt32))
End Sub
Private Sub New(startIndex As UInt32)
MyBase.New(CType(startIndex, UInt32))
End Sub
End Class
' Compilation produces a compiler warning like the following:
'
Type3.vb(34) : warning BC40026: 'NonZeroCounter' is not CLS-compliant
'
because it derives from 'Counter', which is not CLS-compliant.
'
'
Public Class NonZeroCounter : Inherits Counter
'
~~~~~~~~~~~~~~

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.
CLS-COMPLIANT TYPE

DESCRIPTION

Byte

8-bit unsigned integer

Int16

16-bit signed integer

Int32

32-bit signed integer

Int64

64-bit signed integer

Single

Single-precision floating-point value

Double

Double-precision floating-point value

Boolean

true or false value type

Char

UTF-16 encoded code unit

Decimal

Non-floating-point decimal number

IntPtr

Pointer or handle of a platform-defined size

String

Collection of zero, one, or more Char objects

The intrinsic types listed in the following table are not CLS-Compliant.

NON-COMPLIANT TYPE

DESCRIPTION

CLS-COMPLIANT ALTERNATIVE

SByte

8-bit signed integer data type

Int16

UInt16

16-bit unsigned integer

Int32

UInt32

32-bit unsigned integer

Int64

UInt64

64-bit unsigned integer

Int64 (may overflow), BigInteger, or Double

UIntPtr

Unsigned pointer or handle

IntPtr

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
value type, the compiler flags it as non-CLS-compliant.

int

* named

Value

. Because an

int

* is a boxed

using System;
[assembly:CLSCompliant(true)]
public unsafe class TestClass
{
private int* val;
public TestClass(int number)
{
val = (int*) number;
}
public int* Value {
get { return val; }
}
}
// The compiler generates the following output when compiling this example:
//
warning CS3003: Type of 'TestClass.Value' is not CLS-compliant

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
more information, see the CLSCompliantAttribute attribute section.

false

The following example illustrates the problem of CLS compliance in a method signature and in generic type instantiation. It defines an
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)]
public class InvoiceItem
{
private uint invId = 0;
private uint itemId = 0;
private Nullable qty;
public InvoiceItem(uint sku, Nullable quantity)
{
itemId = sku;
qty = quantity;
}
public Nullable Quantity
{
get { return qty; }
set { qty = value; }
}
public uint InvoiceId
{
get { return invId; }
set { invId = value; }
}
}
// The attempt to compile the example displays the following output:
//
Type1.cs(13,23): warning CS3001: Argument type 'uint' is not CLS-compliant
//
Type1.cs(13,33): warning CS3001: Argument type 'uint?' is not CLS-compliant
//
Type1.cs(19,26): warning CS3003: Type of 'InvoiceItem.Quantity' is not CLS-compliant
//
Type1.cs(25,16): warning CS3003: Type of 'InvoiceItem.InvoiceId' is not CLS-compliant

to it. For

InvoiceItem


Public Class InvoiceItem
Private invId As UInteger = 0
Private itemId As UInteger = 0
Private qty AS Nullable(Of UInteger)
Public Sub New(sku As UInteger, quantity As Nullable(Of UInteger))
itemId = sku
qty = quantity
End Sub
Public Property Quantity As Nullable(Of UInteger)
Get
Return qty
End Get
Set
qty = value
End Set
End Property
Public Property InvoiceId As UInteger
Get
Return invId
End Get
Set
invId = value
End Set
End Property
End Class
' The attempt to compile the example displays output similar to the following:
'
Type1.vb(13) : warning BC40028: Type of parameter 'sku' is not CLS-compliant.
'
'
Public Sub New(sku As UInteger, quantity As Nullable(Of UInteger))
'
~~~
'
Type1.vb(13) : warning BC40041: Type 'UInteger' is not CLS-compliant.
'
'
Public Sub New(sku As UInteger, quantity As Nullable(Of UInteger))
'
~~~~~~~~
'
Type1.vb(18) : warning BC40041: Type 'UInteger' is not CLS-compliant.
'
'
Public Property Quantity As Nullable(Of UInteger)
'
~~~~~~~~
'
Type1.vb(27) : warning BC40027: Return type of function 'InvoiceId' is not CLS-compliant.
'
'
Public Property InvoiceId As UInteger

To eliminate the compiler warnings, replace the non-CLS-compliant types in the

InvoiceItem

public interface with compliant types:

using System;
[assembly: CLSCompliant(true)]
public class InvoiceItem
{
private uint invId = 0;
private uint itemId = 0;
private Nullable qty;
public InvoiceItem(int sku, Nullable quantity)
{
if (sku <= 0)
throw new ArgumentOutOfRangeException("The item number is zero or negative.");
itemId = (uint) sku;
qty = quantity;
}
public Nullable Quantity
{
get { return qty; }
set { qty = value; }
}
public int InvoiceId
{
get { return (int) invId; }
set {
if (value <= 0)
throw new ArgumentOutOfRangeException("The invoice number is zero or negative.");
invId = (uint) value; }
}
}

Assembly: CLSCompliant(True)>
Public Class InvoiceItem
Private invId As UInteger = 0
Private itemId As UInteger = 0
Private qty AS Nullable(Of Integer)
Public Sub New(sku As Integer, quantity As Nullable(Of Integer))
If sku <= 0 Then
Throw New ArgumentOutOfRangeException("The item number is zero or negative.")
End If
itemId = CUInt(sku)
qty = quantity
End Sub
Public Property Quantity As Nullable(Of Integer)
Get
Return qty
End Get
Set
qty = value
End Set
End Property
Public Property InvoiceId As Integer
Get
Return CInt(invId)
End Get
Set
invId = CUInt(value)
End Set
End Property
End Class

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)]
public class ArrayHelper
{
unsafe public static Array CreateInstance(Type type, int* ptr, int items)
{
Array arr = Array.CreateInstance(type, items);
int* addr = ptr;
for (int ctr = 0; ctr < items; ctr++) {
int value = *addr;
arr.SetValue(value, ctr);
addr++;
}
return arr;
}
}
// The attempt to compile this example displays the following output:
//
UnmanagedPtr1.cs(8,57): warning CS3001: Argument type 'int*' is not CLS-compliant

using System;
[assembly: CLSCompliant(true)]
public class ArrayHelper
{
unsafe public static Array CreateInstance(Type type, int* ptr, int items)
{
Array arr = Array.CreateInstance(type, items);
int* addr = ptr;
for (int ctr = 0; ctr < items; ctr++) {
int value = *addr;
arr.SetValue(value, ctr);
addr++;
}
return arr;
}
}
// The attempt to compile this example displays the following output:
//
UnmanagedPtr1.cs(8,57): warning CS3001: Argument type 'int*' is not CLS-compliant

For CLS-compliant abstract classes (that is, classes marked as
Naming conventions

abstract

in C#), all members of the class must also be CLS-compliant.

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)]
public class Person : person
{
}
public class person
{
}
// 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 L ATIN CAPITAL LETTER A WITH RING ABOVE (U+00C5). The C# compiler flags 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)


Public Class Size
Private a1 As Double
Private a2 As Double
Public Property Å As Double
Get
Return a1
End Get
Set
a1 = value
End Set
End Property
Public Property Å As Double
Get
Return a2
End Get
Set
a2 = value
End Set
End Property
End Class
' Compilation produces a compiler warning like the following:
'
Naming1.vb(9) : error BC30269: 'Public Property Å As Double' has multiple definitions
'
with identical signatures.
'
'
Public Property Å 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)]
public class Converter
{
public double Conversion(int number)
{
return (double) number;
}
public float Conversion(int number)
{
return (float) number;
}
public double Conversion(long number)
{
return (double) number;
}
public bool Conversion
{
get { return true; }
}
}
// Compilation produces a compiler error like the following:
//
Naming3.cs(13,17): error CS0111: Type 'Converter' already defines a member called
//
'Conversion' with the same parameter types
//
Naming3.cs(8,18): (Location of symbol related to previous error)
//
Naming3.cs(23,16): error CS0102: The type 'Converter' already contains a definition for
//
'Conversion'
//
Naming3.cs(8,18): (Location of symbol related to previous error)


Public Class Converter
Public Function Conversion(number As Integer) As Double
Return CDbl(number)
End Function
Public Function Conversion(number As Integer) As Single
Return CSng(number)
End Function
Public Function Conversion(number As Long) As Double
Return CDbl(number)
End Function
Public ReadOnly Property Conversion As Boolean
Get
Return True
End Get
End Property
End Class
' Compilation produces a compiler error like the following:
'
Naming3.vb(8) : error BC30301: 'Public Function Conversion(number As Integer) As Double'
'
and 'Public Function Conversion(number As Integer) As Single' cannot
'
overload each other because they differ only by return types.
'
'
Public Function Conversion(number As Integer) As Double
'
~~~~~~~~~~
'
Naming3.vb(20) : error BC30260: 'Conversion' is already declared as 'Public Function
'
Conversion(number As Integer) As Single' in this class.
'
'
Public ReadOnly Property Conversion As Boolean
'
~~~~~~~~~~

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.
Public Class [case]
Private _id As Guid
Private name As String
Public Sub New(name As String)
_id = Guid.NewGuid()
Me.name = name
End Sub
Public ReadOnly Property ClientName As String
Get
Return name
End Get
End Property
End Class

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;
public class Example
{
public static void Main()
{
@case c = new @case("John");
Console.WriteLine(c.ClientName);
}
}

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;
public struct UDouble
{
private double number;
public UDouble(double value)
{
if (value < 0)
throw new InvalidCastException("A negative value cannot be converted to a UDouble.");
number = value;
}
public UDouble(float value)
{
if (value < 0)
throw new InvalidCastException("A negative value cannot be converted to a UDouble.");
number = value;
}
public static readonly UDouble MinValue = (UDouble) 0.0;
public static readonly UDouble MaxValue = (UDouble) Double.MaxValue;
public static explicit operator Double(UDouble value)
{
return value.number;
}
public static implicit operator Single(UDouble value)
{
if (value.number > (double) Single.MaxValue)
throw new InvalidCastException("A UDouble value is out of range of the Single type.");
return (float) value.number;
}
public static explicit operator UDouble(double value)
{
if (value < 0)
throw new InvalidCastException("A negative value cannot be converted to a UDouble.");
return new UDouble(value);
}
public static implicit operator UDouble(float value)
{
if (value < 0)
throw new InvalidCastException("A negative value cannot be converted to a UDouble.");
return new UDouble(value);
}
public static Double ToDouble(UDouble value)
{
return (Double) value;
}
public static float ToSingle(UDouble value)
{
return (float) value;
}
public static UDouble FromDouble(double value)
{
return new UDouble(value);
}
public static UDouble FromSingle(float value)
{
return new UDouble(value);
}
}

Public Structure UDouble
Private number As Double
Public Sub New(value As Double)
If value < 0 Then
Throw New InvalidCastException("A negative value cannot be converted to a UDouble.")
End If
number = value
End Sub
Public Sub New(value As Single)
If value < 0 Then
Throw New InvalidCastException("A negative value cannot be converted to a UDouble.")
End If
number = value
End Sub
Public Shared ReadOnly MinValue As UDouble = CType(0.0, UDouble)
Public Shared ReadOnly MaxValue As UDouble = Double.MaxValue
Public Shared Widening Operator CType(value As UDouble) As Double
Return value.number
End Operator
Public Shared Narrowing Operator CType(value As UDouble) As Single
If value.number > CDbl(Single.MaxValue) Then
Throw New InvalidCastException("A UDouble value is out of range of the Single type.")
End If
Return CSng(value.number)
End Operator
Public Shared Narrowing Operator CType(value As Double) As UDouble
If value < 0 Then
Throw New InvalidCastException("A negative value cannot be converted to a UDouble.")
End If
Return New UDouble(value)
End Operator
Public Shared Narrowing Operator CType(value As Single) As UDouble
If value < 0 Then
Throw New InvalidCastException("A negative value cannot be converted to a UDouble.")
End If
Return New UDouble(value)
End Operator
Public Shared Function ToDouble(value As UDouble) As Double
Return CType(value, Double)
End Function
Public Shared Function ToSingle(value As UDouble) As Single
Return CType(value, Single)
End Function
Public Shared Function FromDouble(value As Double) As UDouble
Return New UDouble(value)
End Function
Public Shared Function FromSingle(value As Single) As UDouble
Return New UDouble(value)
End Function
End Structure

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)]
public class Numbers
{
public static Array GetTenPrimes()
{
Array arr = Array.CreateInstance(typeof(Int32), new int[] {10}, new int[] {1});
arr.SetValue(1, 1);
arr.SetValue(2, 2);
arr.SetValue(3, 3);
arr.SetValue(5, 4);
arr.SetValue(7, 5);
arr.SetValue(11, 6);
arr.SetValue(13, 7);
arr.SetValue(17, 8);
arr.SetValue(19, 9);
arr.SetValue(23, 10);
return arr;
}
}


Public Class Numbers
Public Shared Function GetTenPrimes() As Array
Dim arr As Array = Array.CreateInstance(GetType(Int32), {10}, {1})
arr.SetValue(1, 1)
arr.SetValue(2, 2)
arr.SetValue(3, 3)
arr.SetValue(5, 4)
arr.SetValue(7, 5)
arr.SetValue(11, 6)
arr.SetValue(13, 7)
arr.SetValue(17, 8)
arr.SetValue(19, 9)
arr.SetValue(23, 10)
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)]
public class Numbers
{
public static UInt32[] GetTenPrimes()
{
uint[] arr = { 1u, 2u, 3u, 5u, 7u, 11u, 13u, 17u, 19u };
return arr;
}
public static Object[] GetFivePrimes()
{
Object[] arr = { 1, 2, 3, 5u, 7u };
return arr;
}
}
// Compilation produces a compiler warning like the following:
//
Array2.cs(8,27): warning CS3002: Return type of 'Numbers.GetTenPrimes()' is not
//
CLS-compliant


Public Class Numbers
Public Shared Function GetTenPrimes() As UInt32()
Return { 1ui, 2ui, 3ui, 5ui, 7ui, 11ui, 13ui, 17ui, 19ui }
End Function
Public Shared Function GetFivePrimes() As Object()
Dim arr() As Object = { 1, 2, 3, 5ui, 7ui }
Return arr
End Function
End Class
' Compilation produces a compiler warning like the following:
'
warning BC40027: Return type of function 'GetTenPrimes' is not CLS-compliant.

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)]
public class Numbers
{
public static byte[] GetSquares(byte[] numbers)
{
byte[] numbersOut = new byte[numbers.Length];
for (int ctr = 0; ctr < numbers.Length; ctr++) {
int square = ((int) numbers[ctr]) * ((int) numbers[ctr]);
if (square <= Byte.MaxValue)
numbersOut[ctr] = (byte) square;
// If there's an overflow, assign MaxValue to the corresponding
// element.
else
numbersOut[ctr] = Byte.MaxValue;
}
return numbersOut;
}
public static BigInteger[] GetSquares(BigInteger[] numbers)
{
BigInteger[] numbersOut = new BigInteger[numbers.Length];
for (int ctr = 0; ctr < numbers.Length; ctr++)
numbersOut[ctr] = numbers[ctr] * numbers[ctr];
return numbersOut;
}
}

Imports System.Numerics

Public Module Numbers
Public Function GetSquares(numbers As Byte()) As Byte()
Dim numbersOut(numbers.Length - 1) As Byte
For ctr As Integer = 0 To numbers.Length - 1
Dim square As Integer = (CInt(numbers(ctr)) * CInt(numbers(ctr)))
If square <= Byte.MaxValue Then
numbersOut(ctr) = CByte(square)
' If there's an overflow, assign MaxValue to the corresponding
' element.
Else
numbersOut(ctr) = Byte.MaxValue
End If
Next
Return numbersOut
End Function
Public Function GetSquares(numbers As BigInteger()) As BigInteger()
Dim numbersOut(numbers.Length - 1) As BigInteger
For ctr As Integer = 0 To numbers.Length - 1
numbersOut(ctr) = numbers(ctr) * numbers(ctr)
Next
Return numbersOut
End Function
End Module

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,
non-CLS-compliant. This example generates a compiler warning.

INumber.GetUnsigned

, that is marked as

using System;
[assembly:CLSCompliant(true)]
public interface INumber
{
int Length();
[CLSCompliant(false)] ulong GetUnsigned();
}
// Attempting to compile the example displays output like the following:
//
Interface2.cs(8,32): warning CS3010: 'INumber.GetUnsigned()': CLS-compliant interfaces
//
must have only CLS-compliant members


Public Interface INumber
Function Length As Integer
 Function GetUnsigned As ULong
End Interface
' Attempting to compile the example displays output like the following:
'
Interface2.vb(9) : warning BC40033: Non CLS-compliant 'function' is not allowed in a
'
CLS-compliant interface.
'
'
 Function GetUnsigned As ULong
'
~~~~~~~~~~~

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)]
public interface IFahrenheit
{
decimal GetTemperature();
}
public interface ICelsius
{
decimal GetTemperature();
}
public class Temperature : ICelsius, IFahrenheit
{
private decimal _value;
public Temperature(decimal value)
{
// We assume that this is the Celsius value.
_value = value;
}
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)>
Public Interface IFahrenheit
Function GetTemperature() As Decimal
End Interface
Public Interface ICelsius
Function GetTemperature() As Decimal
End Interface
Public Class Temperature : Implements ICelsius, IFahrenheit
Private _value As Decimal
Public Sub New(value As Decimal)
' We assume that this is the Celsius value.
_value = value
End Sub
Public Function GetFahrenheit() As Decimal _
Implements IFahrenheit.GetTemperature
Return _value * 9 / 5 + 32
End Function
Public Function GetCelsius() As Decimal _
Implements ICelsius.GetTemperature
Return _value
End Function
End Class
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)]
public enum Size : uint {
Unspecified = 0,
XSmall = 1,
Small = 2,
Medium = 3,
Large = 4,
XLarge = 5
};
public class Clothing
{
public string Name;
public string Type;
public string Size;
}
// The attempt to compile the example displays a compiler warning like the following:
//
Enum3.cs(6,13): warning CS3009: 'Size': base type 'uint' is not CLS-compliant


Public Enum Size As UInt32
Unspecified = 0
XSmall = 1
Small = 2
Medium = 3
Large = 4
XLarge = 5
End Enum
Public Class Clothing
Public Name As String
Public Type As String
Public Size As Size
End Class
' The attempt to compile the example displays a compiler warning like the following:
'
Enum3.vb(6) : warning BC40032: Underlying type 'UInt32' of Enum is not CLS-compliant.
'
'
Public Enum Size As UInt32
'
~~~~

An enumeration type must have a single instance field named
enables you to reference the field value implicitly.

Value__

that is marked with the

FieldAttributes.RTSpecialName

attribute. This

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 .
There are two kinds of enumerations:
An enumeration that represents a set of mutually exclusive, named integer values. This type of enumeration is indicated by the absence of
the System.FlagsAttribute custom attribute.
An enumeration that represents a set of bit flags that can combine to generate an unnamed value. This type of enumeration is indicated by
the presence of the System.FlagsAttribute custom attribute.
For more information, see the documentation for the Enum structure.
The value of an enumeration is not limited to the range of its specified values. In other words, the range of values in an enumeration is the range of
its underlying value. You can use the Enum.IsDefined method to determine whether a specified value is a member of an enumeration.
Type members in general
The Common Language Specification requires all fields and methods to be accessed as members of a particular class. Therefore, global static fields and
methods (that is, static fields or methods that are defined apart from a type) are not CLS-compliant. If you try to include a global field or method in your
source code, the C# compiler generates a compiler error.
The Common Language Specification supports only the standard managed calling convention. It doesn't support unmanaged calling conventions and
methods with variable argument lists marked with the varargs keyword. For variable argument lists that are compatible with the standard managed
calling convention, use the ParamArrayAttribute attribute or the individual language's implementation, such as the params keyword in C# and the
ParamArray keyword in Visual Basic.
Member accessibility
Overriding an inherited member cannot change the accessibility of that member. For example, a public method in a base class cannot be overridden by
a private method in a derived class. There is one exception: a protected internal (in C#) or Protected Friend (in Visual Basic) member in one assembly
that is overridden by a type in a different assembly. In that case, the accessibility of the override is Protected .
The following example illustrates the error that is generated when the CLSCompliantAttribute attribute is set to true , and Person , which is a class
derived from Animal , tries to change the accessibility of the Species property from public to private. The example compiles successfully if its
accessibility is changed to public.

using System;
[assembly: CLSCompliant(true)]
public class Animal
{
private string _species;
public Animal(string species)
{
_species = species;
}
public virtual string Species
{
get { return _species; }
}
public override string ToString()
{
return _species;
}
}
public class Human : Animal
{
private string _name;
public Human(string name) : base("Homo Sapiens")
{
_name = name;
}
public string Name
{
get { return _name; }
}
private override string Species
{
get { return base.Species; }
}
public override string ToString()
{
return _name;
}
}
public class Example
{
public static void Main()
{
Human p = new Human("John");
Console.WriteLine(p.Species);
Console.WriteLine(p.ToString());
}
}
// The example displays the following output:
//
error CS0621: 'Human.Species': virtual or abstract members cannot be private


Public Class Animal
Private _species As String
Public Sub New(species As String)
_species = species
End Sub
Public Overridable ReadOnly Property Species As String
Get
Return _species
End Get
End Property
Public Overrides Function ToString() As String
Return _species
End Function
End Class
Public Class Human : Inherits Animal
Private _name As String
Public Sub New(name As String)
MyBase.New("Homo Sapiens")
_name = name
End Sub
Public ReadOnly Property Name As String
Get
Return _name
End Get
End Property
Private Overrides ReadOnly Property Species As String
Get
Return MyBase.Species
End Get
End Property
Public Overrides Function ToString() As String
Return _name
End Function
End Class
Public Module Example
Public Sub Main()
Dim p As New Human("John")
Console.WriteLine(p.Species)
Console.WriteLine(p.ToString())
End Sub
End Module
' The example displays the following output:
'
'Private Overrides ReadOnly Property Species As String' cannot override
'
'Public Overridable ReadOnly Property Species As String' because
'
they have different access levels.
'
'
Private Overrides ReadOnly Property Species As String

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;
public class StringWrapper
{
string internalString;
StringBuilder internalSB = null;
bool useSB = false;
public StringWrapper(StringOperationType type)
{
if (type == StringOperationType.Normal) {
useSB = false;
}
else {
useSB = true;
internalSB = new StringBuilder();
}
}
// The remaining source code...
}
internal enum StringOperationType { Normal, Dynamic }
// The attempt to compile the example displays the following output:
//
error CS0051: Inconsistent accessibility: parameter type
//
'StringOperationType' is less accessible than method
//
'StringWrapper.StringWrapper(StringOperationType)'

Imports System.Text

Public Class StringWrapper
Dim internalString As String
Dim internalSB As StringBuilder = Nothing
Dim useSB As Boolean = False
Public Sub New(type As StringOperationType)
If type = StringOperationType.Normal Then
useSB = False
Else
internalSB = New StringBuilder()
useSB = True
End If
End Sub
' The remaining source code...
End Class
Friend Enum StringOperationType As Integer
Normal = 0
Dynamic = 1
End Enum
' The attempt to compile the example displays the following output:
'
error BC30909: 'type' cannot expose type 'StringOperationType'
'
outside the project through class 'StringWrapper'.
'
'
Public Sub New(type As StringOperationType)
'
~~~~~~~~~~~~~~~~~~~

Generic types and members
Nested types always have at least as many generic parameters as their enclosing type. These correspond by position to the generic parameters in the
enclosing type. The generic type can also include new generic parameters.
The relationship between the generic type parameters of a containing type and its nested types may be hidden by the syntax of individual languages. In
the following example, a generic type Outer contains two nested classes, Inner1A and Inner1B . The calls to the ToString method, which each
class inherits from Object.ToString , show that each nested class includes the type parameters of its containing class.

using System;
[assembly:CLSCompliant(true)]
public class Outer
{
T value;
public Outer(T value)
{
this.value = value;
}
public class Inner1A : Outer
{
public Inner1A(T value) : base(value)
{ }
}
public class Inner1B : Outer
{
U value2;
public Inner1B(T value1, U value2) : base(value1)
{
this.value2 = value2;
}
}
}
public class Example
{
public static void Main()
{
var inst1 = new Outer("This");
Console.WriteLine(inst1);
var inst2 = new Outer.Inner1A("Another");
Console.WriteLine(inst2);
var inst3 = new Outer.Inner1B("That", 2);
Console.WriteLine(inst3);
}
}
// The example displays the following output:
//
Outer`1[System.String]
//
Outer`1+Inner1A[System.String]
//
Outer`1+Inner1B`1[System.String,System.Int32]


Public Class Outer(Of T)
Dim value As T
Public Sub New(value As T)
Me.value = value
End Sub
Public Class Inner1A : Inherits Outer(Of T)
Public Sub New(value As T)
MyBase.New(value)
End Sub
End Class
Public Class Inner1B(Of U) : Inherits Outer(Of T)
Dim value2 As U
Public Sub New(value1 As T, value2 As U)
MyBase.New(value1)
Me.value2 = value2
End Sub
End Class
End Class
Public Module Example
Public Sub Main()
Dim inst1 As New Outer(Of String)("This")
Console.WriteLine(inst1)
Dim inst2 As New Outer(Of String).Inner1A("Another")
Console.WriteLine(inst2)
Dim inst3 As New Outer(Of String).Inner1B(Of Integer)("That", 2)
Console.WriteLine(inst3)
End Sub
End Module
' The example displays the following output:
'
Outer`1[System.String]
'
Outer`1+Inner1A[System.String]
'
Outer`1+Inner1B`1[System.String,System.Int32]

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)]
[CLSCompliant(false)] public class BaseClass
{}

public class BaseCollection where T : BaseClass
{}
// Attempting to compile the example displays the following output:
//
warning CS3024: Constraint type 'BaseClass' is not CLS-compliant

Assembly: CLSCompliant(True)>
 Public Class BaseClass
End Class

Public Class BaseCollection(Of T As BaseClass)
End Class
' Attempting to compile the example displays the following output:
'
warning BC40040: Generic parameter constraint type 'BaseClass' is not
'
CLS-compliant.
'
'
Public Class BaseCollection(Of T As BaseClass)
'
~~~~~~~~~

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 that can represent any numeric type. It also defines a FloatingPoint class that represents a
floating point value. However, the source code fails to compile, because it does not apply the constraint on Number (that T must be a value type) to

FloatingPoint

.

using System;
[assembly:CLSCompliant(true)]
public class Number where T : struct
{
// use Double as the underlying type, since its range is a superset of
// the ranges of all numeric types except BigInteger.
protected double number;
public Number(T value)
{
try {
this.number = Convert.ToDouble(value);
}
catch (OverflowException e) {
throw new ArgumentException("value is too large.", e);
}
catch (InvalidCastException e) {
throw new ArgumentException("The value parameter is not numeric.", e);
}
}
public T Add(T value)
{
return (T) Convert.ChangeType(number + Convert.ToDouble(value), typeof(T));
}
public T Subtract(T value)
{
return (T) Convert.ChangeType(number - Convert.ToDouble(value), typeof(T));
}
}
public class FloatingPoint : Number
{
public FloatingPoint(T number) : base(number)
{
if (typeof(float) == number.GetType() ||
typeof(double) == number.GetType() ||
typeof(decimal) == number.GetType())
this.number = Convert.ToDouble(number);
else
throw new ArgumentException("The number parameter is not a floating-point number.");
}
}
// The attempt to comple the example displays the following output:
//
error CS0453: The type 'T' must be a non-nullable value type in
//
order to use it as parameter 'T' in the generic type or method 'Number'


Public Class Number(Of
' Use Double as the
' the ranges of all
Protected number As

T As Structure)
underlying type, since its range is a superset of
numeric types except BigInteger.
Double

Public Sub New(value As T)
Try
Me.number = Convert.ToDouble(value)
Catch e As OverflowException
Throw New ArgumentException("value is too large.", e)
Catch e As InvalidCastException
Throw New ArgumentException("The value parameter is not numeric.", e)
End Try
End Sub
Public Function Add(value As T) As T
Return CType(Convert.ChangeType(number + Convert.ToDouble(value), GetType(T)), T)
End Function
Public Function Subtract(value As T) As T
Return CType(Convert.ChangeType(number - Convert.ToDouble(value), GetType(T)), T)
End Function
End Class
Public Class FloatingPoint(Of T) : Inherits Number(Of T)
Public Sub New(number As T)
MyBase.New(number)
If TypeOf number Is Single Or
TypeOf number Is Double Or
TypeOf number Is Decimal Then
Me.number = Convert.ToDouble(number)
Else
throw new ArgumentException("The number parameter
End If
End Sub
End Class
' The attempt to comple the example displays the following
'
error BC32105: Type argument 'T' does not satisfy the
'
constraint for type parameter 'T'.
'
'
Public Class FloatingPoint(Of T) : Inherits Number(Of
'

is not a floating-point number.")

output:
'Structure'

T)
~

The example compiles successfully if the constraint is added to the

FloatingPoint

class.

using System;
[assembly:CLSCompliant(true)]

public class Number where T : struct
{
// use Double as the underlying type, since its range is a superset of
// the ranges of all numeric types except BigInteger.
protected double number;
public Number(T value)
{
try {
this.number = Convert.ToDouble(value);
}
catch (OverflowException e) {
throw new ArgumentException("value is too large.", e);
}
catch (InvalidCastException e) {
throw new ArgumentException("The value parameter is not numeric.", e);
}
}
public T Add(T value)
{
return (T) Convert.ChangeType(number + Convert.ToDouble(value), typeof(T));
}
public T Subtract(T value)
{
return (T) Convert.ChangeType(number - Convert.ToDouble(value), typeof(T));
}
}
public class FloatingPoint : Number where T : struct
{
public FloatingPoint(T number) : base(number)
{
if (typeof(float) == number.GetType() ||
typeof(double) == number.GetType() ||
typeof(decimal) == number.GetType())
this.number = Convert.ToDouble(number);
else
throw new ArgumentException("The number parameter is not a floating-point number.");
}
}


Public Class Number(Of
' Use Double as the
' the ranges of all
Protected number As

T As Structure)
underlying type, since its range is a superset of
numeric types except BigInteger.
Double

Public Sub New(value As T)
Try
Me.number = Convert.ToDouble(value)
Catch e As OverflowException
Throw New ArgumentException("value is too large.", e)
Catch e As InvalidCastException
Throw New ArgumentException("The value parameter is not numeric.", e)
End Try
End Sub
Public Function Add(value As T) As T
Return CType(Convert.ChangeType(number + Convert.ToDouble(value), GetType(T)), T)
End Function
Public Function Subtract(value As T) As T
Return CType(Convert.ChangeType(number - Convert.ToDouble(value), GetType(T)), T)
End Function
End Class
Public Class FloatingPoint(Of T As Structure) : Inherits Number(Of T)
Public Sub New(number As T)
MyBase.New(number)
If TypeOf number Is Single Or
TypeOf number Is Double Or
TypeOf number Is Decimal Then
Me.number = Convert.ToDouble(number)
Else
throw new ArgumentException("The number parameter is not a floating-point number.")
End If
End Sub
End Class

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 , and a protected class, C1.N . C1 has two methods, M1 and M2 . However, M1 is not CLScompliant because it tries to return a C1.N object from C1 . A second class, C2 , is derived from C1 . It has two methods, M3 and M4 .
M3 is not CLS-compliant because it tries to return a C1.N object from a subclass of C1 . 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)]
public class C1
{
protected class N { }
protected void M1(C1.N n) { } //
//
//
protected void M2(C1.N n) { } //
//

Not CLS-compliant - C1.N not
accessible from within C1 in all
languages
CLS-compliant – C1.N accessible
inside C1

}
public class C2 : C1
{
protected void M3(C1.N n) { } // Not CLS-compliant – C1.N is not
// accessible in C2 (extends C1)
protected void M4(C1.N n) { } // CLS-compliant, C1.N is
// accessible in C2 (extends C1)
}
// Attempting to compile the example displays output like the following:
//
Generics4.cs(9,22): warning CS3001: Argument type 'C1.N' is not CLS-compliant
//
Generics4.cs(18,22): warning CS3001: Argument type 'C1.N' is not CLS-compliant


Public Class C1(Of T)
Protected Class N
End Class
Protected Sub M1(n As C1(Of Integer).N)
End Sub

Protected Sub M2(n As C1(Of T).N)
End Sub
End Class

' Not CLS-compliant - C1.N not
' accessible from within C1(Of T) in all
' languages

' CLS-compliant – C1(Of T).N accessible
' inside C1(Of T)

Public Class C2 : Inherits C1(Of Long)
Protected Sub M3(n As C1(Of Integer).N)
End Sub

' Not CLS-compliant – C1(Of Integer).N is not
' accessible in C2 (extends C1(Of Long))

Protected Sub M4(n As C1(Of Long).N)
End Sub
End Class
' Attempting to compile the example displays output like the following:
'
error BC30508: 'n' cannot expose type 'C1(Of Integer).N' in namespace
'
'' through class 'C1'.
'
'
Protected Sub M1(n As C1(Of Integer).N) ' Not CLS-compliant - C1.N not
'
~~~~~~~~~~~~~~~~
'
error BC30389: 'C1(Of T).N' is not accessible in this context because
'
it is 'Protected'.
'
'
Protected Sub M3(n As C1(Of Integer).N) ' Not CLS-compliant - C1(Of Integer).N is not
'
'
~~~~~~~~~~~~~~~~
'
'
error BC30389: 'C1(Of T).N' is not accessible in this context because it is 'Protected'.
'
'
Protected Sub M4(n As C1(Of Long).N)
'
~~~~~~~~~~~~~

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)]
public class Person
{
private string fName, lName, _id;
public Person(string firstName, string lastName, string id)
{
if (String.IsNullOrEmpty(firstName + lastName))
throw new ArgumentNullException("Either a first name or a last name must be provided.");
fName = firstName;
lName = lastName;
_id = id;
}
public string FirstName
{
get { return fName; }
}
public string LastName
{
get { return lName; }
}
public string Id
{
get { return _id; }
}
public override string ToString()
{
return String.Format("{0}{1}{2}", fName,
String.IsNullOrEmpty(fName) ? "" : " ",
lName);
}
}
public class Doctor : Person
{
public Doctor(string firstName, string lastName, string id)
{
}
public override string ToString()
{
return "Dr. " + base.ToString();
}
}
// Attempting to compile the example displays output like the following:
//
ctor1.cs(45,11): error CS1729: 'Person' does not contain a constructor that takes 0
//
arguments
//
ctor1.cs(10,11): (Location of symbol related to previous error)


Public Class Person
Private fName, lName, _id As String
Public Sub New(firstName As String, lastName As String, id As String)
If String.IsNullOrEmpty(firstName + lastName) Then
Throw New ArgumentNullException("Either a first name or a last name must be provided.")
End If
fName = firstName
lName = lastName
_id = id
End Sub
Public ReadOnly Property FirstName As String
Get
Return fName
End Get
End Property
Public ReadOnly Property LastName As String
Get
Return lName
End Get
End Property
Public ReadOnly Property Id As String
Get
Return _id
End Get
End Property
Public Overrides Function ToString() As String
Return String.Format("{0}{1}{2}", fName,
If(String.IsNullOrEmpty(fName), "", " "),
lName)
End Function
End Class
Public Class Doctor : Inherits Person
Public Sub New(firstName As String, lastName As String, id As String)
End Sub
Public Overrides Function ToString() As String
Return "Dr. " + MyBase.ToString()
End Function
End Class
' Attempting to compile the example displays output like the following:
'
Ctor1.vb(46) : error BC30148: First statement of this 'Sub New' must be a call
'
to 'MyBase.New' or 'MyClass.New' because base class 'Person' of 'Doctor' does
'
not have an accessible 'Sub New' that can be called with no arguments.
'
'
Public Sub New()
'
~~~

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
event is named add_StateChange .

add

A method for removing an event handler, named
is named remove_StateChange .

_EventName. For example, the event subscription method for the

remove

_EventName. For example, the removal method for the

DbConnection.StateChange

DbConnection.StateChange

event

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 class TemperatureChangedEventArgs : EventArgs
{
private Decimal originalTemp;
private Decimal newTemp;
private DateTimeOffset when;
public TemperatureChangedEventArgs(Decimal original, Decimal @new, DateTimeOffset time)
{
originalTemp = original;
newTemp = @new;
when = time;
}
public Decimal OldTemperature
{
get { return originalTemp; }
}
public Decimal CurrentTemperature
{
get { return newTemp; }
}
public DateTimeOffset Time
{
get { return when; }
}
}
public delegate void TemperatureChanged(Object sender, TemperatureChangedEventArgs e);
public class Temperature
{
private struct TemperatureInfo
{
public Decimal Temperature;
public DateTimeOffset Recorded;
}
public event TemperatureChanged TemperatureChanged;
private
private
private
private

Decimal previous;
Decimal current;
Decimal tolerance;
List tis = new List();

public Temperature(Decimal temperature, Decimal tolerance)
{
current = temperature;
TemperatureInfo ti = new TemperatureInfo();
ti.Temperature = temperature;
tis.Add(ti);
ti.Recorded = DateTimeOffset.UtcNow;
this.tolerance = tolerance;
}
public Decimal CurrentTemperature
{
get { return current; }
set {
TemperatureInfo ti = new TemperatureInfo();
ti.Temperature = value;
ti.Recorded = DateTimeOffset.UtcNow;
previous = current;
current = value;

if (Math.Abs(current - previous) >= tolerance)
raise_TemperatureChanged(new TemperatureChangedEventArgs(previous, current, ti.Recorded));
}
}
public void raise_TemperatureChanged(TemperatureChangedEventArgs eventArgs)
{
if (TemperatureChanged == null)
return;
foreach (TemperatureChanged d in TemperatureChanged.GetInvocationList()) {
if (d.Method.Name.Contains("Duplicate"))
Console.WriteLine("Duplicate event handler; event handler not executed.");
else
d.Invoke(this, eventArgs);
}
}
}
public class Example
{
public Temperature temp;
public static void Main()
{
Example ex = new Example();
}
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();
}
public void RecordTemperatures()
{
temp.TemperatureChanged += this.DuplicateTemperatureNotification;
temp.CurrentTemperature = 66;
temp.CurrentTemperature = 63;
}
internal void TemperatureNotification(Object sender, TemperatureChangedEventArgs e)
{
Console.WriteLine("Notification 1: The temperature changed from {0} to {1}", e.OldTemperature, e.CurrentTemperature);
}
public void DuplicateTemperatureNotification(Object sender, TemperatureChangedEventArgs e)
{
Console.WriteLine("Notification 2: The temperature changed from {0} to {1}", e.OldTemperature, e.CurrentTemperature);
}
}

Imports System.Collections
Imports System.Collections.Generic

Public Class TemperatureChangedEventArgs
Private originalTemp As Decimal
Private newTemp As Decimal
Private [when] As DateTimeOffset

: Inherits EventArgs

Public Sub New(original As Decimal, [new] As Decimal, [time] As DateTimeOffset)
originalTemp = original
newTemp = [new]
[when] = [time]
End Sub
Public ReadOnly Property OldTemperature As Decimal
Get
Return originalTemp
End Get
End Property
Public ReadOnly Property CurrentTemperature As Decimal
Get
Return newTemp
End Get
End Property

Public ReadOnly Property [Time] As DateTimeOffset
Get
Return [when]
End Get
End Property
End Class
Public Delegate Sub TemperatureChanged(sender As Object, e As TemperatureChangedEventArgs)
Public Class Temperature
Private Structure TemperatureInfo
Dim Temperature As Decimal
Dim Recorded As DateTimeOffset
End Structure
Public Event TemperatureChanged As TemperatureChanged
Private
Private
Private
Private

previous As Decimal
current As Decimal
tolerance As Decimal
tis As New List(Of TemperatureInfo)

Public Sub New(temperature As Decimal, tolerance As Decimal)
current = temperature
Dim ti As New TemperatureInfo()
ti.Temperature = temperature
ti.Recorded = DateTimeOffset.UtcNow
tis.Add(ti)
Me.tolerance = tolerance
End Sub
Public Property CurrentTemperature As Decimal
Get
Return current
End Get
Set
Dim ti As New TemperatureInfo
ti.Temperature = value
ti.Recorded = DateTimeOffset.UtcNow
previous = current
current = value
If Math.Abs(current - previous) >= tolerance Then
raise_TemperatureChanged(New TemperatureChangedEventArgs(previous, current, ti.Recorded))
End If
End Set
End Property
Public Sub raise_TemperatureChanged(eventArgs As TemperatureChangedEventArgs)
If TemperatureChangedEvent Is Nothing Then Exit Sub
Dim ListenerList() As System.Delegate = TemperatureChangedEvent.GetInvocationList()
For Each d As TemperatureChanged In TemperatureChangedEvent.GetInvocationList()
If d.Method.Name.Contains("Duplicate") Then
Console.WriteLine("Duplicate event handler; event handler not executed.")
Else
d.Invoke(Me, eventArgs)
End If
Next
End Sub
End Class
Public Class Example
Public WithEvents temp As Temperature
Public Shared Sub Main()
Dim ex As New Example()
End Sub
Public Sub New()
temp = New Temperature(65, 3)
RecordTemperatures()
Dim ex As New Example(temp)
ex.RecordTemperatures()
End Sub
Public Sub New(t As Temperature)
temp = t
RecordTemperatures()
End Sub
Public Sub RecordTemperatures()
temp.CurrentTemperature = 66
temp.CurrentTemperature = 63
End Sub
Friend Shared Sub TemperatureNotification(sender As Object, e As TemperatureChangedEventArgs) _
Handles temp.TemperatureChanged
Console.WriteLine("Notification 1: The temperature changed from {0} to {1}", e.OldTemperature, e.CurrentTemperature)
End Sub

End Sub
Friend Shared Sub DuplicateTemperatureNotification(sender As Object, e As TemperatureChangedEventArgs) _
Handles temp.TemperatureChanged
Console.WriteLine("Notification 2: The temperature changed from {0} to {1}", e.OldTemperature, e.CurrentTemperature)
End Sub
End Class

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)]
public class ErrorClass
{
string msg;
public ErrorClass(string errorMessage)
{
msg = errorMessage;
}
public string Message
{
get { return msg; }
}
}
public static class StringUtilities
{
public static string[] SplitString(this string value, int index)
{
if (index < 0 | index > value.Length) {
ErrorClass badIndex = new ErrorClass("The index is not within the string.");
throw badIndex;
}
string[] retVal = { value.Substring(0, index - 1),
value.Substring(index) };
return retVal;
}
}
// Compilation produces a compiler error like the following:
//
Exceptions1.cs(26,16): error CS0155: The type caught or thrown must be derived from
//
System.Exception

Imports System.Runtime.CompilerServices

Public Class ErrorClass
Dim msg As String
Public Sub New(errorMessage As String)
msg = errorMessage
End Sub
Public ReadOnly Property Message As String
Get
Return msg
End Get
End Property
End Class
Public Module StringUtilities
 Public Function SplitString(value As String, index As Integer) As String()
If index < 0 Or index > value.Length Then
Dim BadIndex As New ErrorClass("The index is not within the string.")
Throw BadIndex
End If
Dim retVal() As String = { value.Substring(0, index - 1),
value.Substring(index) }
Return retVal
End Function
End Module
' Compilation produces a compiler error like the following:
'
Exceptions1.vb(27) : error BC30665: 'Throw' operand must derive from 'System.Exception'.
'
'
Throw BadIndex
'
~~~~~~~~~~~~~~

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)]
public class ErrorClass : Exception
{
string msg;
public ErrorClass(string errorMessage)
{
msg = errorMessage;
}
public override string Message
{
get { return msg; }
}
}
public static class StringUtilities
{
public static string[] SplitString(this string value, int index)
{
if (index < 0 | index > value.Length) {
ErrorClass badIndex = new ErrorClass("The index is not within the string.");
throw badIndex;
}
string[] retVal = { value.Substring(0, index - 1),
value.Substring(index) };
return retVal;
}
}

Imports System.Runtime.CompilerServices

Public Class ErrorClass : Inherits Exception
Dim msg As String
Public Sub New(errorMessage As String)
msg = errorMessage
End Sub
Public Overrides ReadOnly Property Message As String
Get
Return msg
End Get
End Property
End Class
Public Module StringUtilities
 Public Function SplitString(value As String, index As Integer) As String()
If index < 0 Or index > value.Length Then
Dim BadIndex As New ErrorClass("The index is not within the string.")
Throw BadIndex
End If
Dim retVal() As String = { value.Substring(0, index - 1),
value.Substring(index) }
Return retVal
End Function
End Module

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
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;
public NumericAttribute(bool isNumeric)
{
_isNumeric = isNumeric;
}
public bool IsNumeric
{
get { return _isNumeric; }
}
}
[Numeric(true)] public struct UDouble
{
double Value;
}
// Compilation produces a compiler error like the following:
//
Attribute1.cs(22,2): error CS0616: 'NumericAttribute' is not an attribute class
//
Attribute1.cs(7,14): (Location of symbol related to previous error)

System.Attribute

. Note that a compiler error


 _
Public Class NumericAttribute
Private _isNumeric As Boolean
Public Sub New(isNumeric As Boolean)
_isNumeric = isNumeric
End Sub
Public ReadOnly Property IsNumeric As Boolean
Get
Return _isNumeric
End Get
End Property
End Class
 Public Structure UDouble
Dim Value As Double
End Structure
' Compilation produces a compiler error like the following:
'
error BC31504: 'NumericAttribute' cannot be used as an attribute because it
'
does not inherit from 'System.Attribute'.
'
'
 Public Structure UDouble
'
~~~~~~~~~~~~~

The constructor or the properties of a CLS-compliant attribute can expose only the following types:
Boolean
Byte
Char
Double
Int16
Int32
Int64
Single
String
Type
Any enumeration type whose underlying type is

Byte

,

Int16

,

Int32

, or

Int64

.

The following example defines a DescriptionAttribute class that derives from Attribute. The class constructor has a parameter of type
the class is not CLS-compliant. Note that the C# compiler emits a warning but compiles successfully.
using System;
[assembly:CLSCompliantAttribute(true)]
public enum DescriptorType { type, member };
public class Descriptor
{
public DescriptorType Type;
public String Description;
}
[AttributeUsage(AttributeTargets.All)]
public class DescriptionAttribute : Attribute
{
private Descriptor desc;
public DescriptionAttribute(Descriptor d)
{
desc = d;
}
public Descriptor Descriptor
{ get { return desc; } }
}
// Attempting to compile the example displays output like the following:
//
warning CS3015: 'DescriptionAttribute' has no accessible
//
constructors which use only CLS-compliant types

Descriptor

, so


Public Enum DescriptorType As Integer
Type = 0
Member = 1
End Enum
Public Class Descriptor
Public Type As DescriptorType
Public Description As String
End Class
 _
Public Class DescriptionAttribute : Inherits Attribute
Private desc As Descriptor
Public Sub New(d As Descriptor)
desc = d
End Sub
Public ReadOnly Property Descriptor As Descriptor
Get
Return desc
End Get
End Property
End Class

The CLSCompliantAttribute attribute
The CLSCompliantAttribute attribute is used to indicate whether a program element complies with the Common Language Specification. The
CLSCompliantAttribute.CLSCompliantAttribute(Boolean) constructor includes a single required parameter, isCompliant, that indicates whether the
program element is CLS-compliant.
At compile time, the compiler detects non-compliant elements that are presumed to be CLS-compliant and emits a warning. The compiler does not emit
warnings for types or members that are explicitly declared to be non-compliant.
Component developers can use the

CLSCompliantAttribute

attribute in two ways:

To define the parts of the public interface exposed by a component that are CLS-compliant and the parts that are not CLS-compliant. When the
attribute is used to mark particular program elements as CLS-compliant, its use guarantees that those elements are accessible from all languages
and tools that target the .NET Framework.
To ensure that the component library's public interface exposes only program elements that are CLS-compliant. If elements are not CLScompliant, compilers will generally issue a warning.
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
members are CLS-compliant.

CLSCompliantAttribute

attribute to indicate whether your assembly, its types, and its

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 nonCLS-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)]
public class CharacterUtilities
{
[CLSCompliant(false)] public static ushort ToUTF16(String s)
{
s = s.Normalize(NormalizationForm.FormC);
return Convert.ToUInt16(s[0]);
}
[CLSCompliant(false)] public static ushort ToUTF16(Char ch)
{
return Convert.ToUInt16(ch);
}
// CLS-compliant alternative for ToUTF16(String).
public static int ToUTF16CodeUnit(String s)
{
s = s.Normalize(NormalizationForm.FormC);
return (int) Convert.ToUInt16(s[0]);
}
// CLS-compliant alternative for ToUTF16(Char).
public static int ToUTF16CodeUnit(Char ch)
{
return Convert.ToInt32(ch);
}
public bool HasMultipleRepresentations(String s)
{
String s1 = s.Normalize(NormalizationForm.FormC);
return s.Equals(s1);
}
public int GetUnicodeCodePoint(Char ch)
{
if (Char.IsSurrogate(ch))
throw new ArgumentException("ch cannot be a high or low surrogate.");
return Char.ConvertToUtf32(ch.ToString(), 0);
}
public int GetUnicodeCodePoint(Char[] chars)
{
if (chars.Length > 2)
throw new ArgumentException("The array has too many characters.");
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

Public Class CharacterUtilities
 Public Shared Function ToUTF16(s As String) As UShort
s = s.Normalize(NormalizationForm.FormC)
Return Convert.ToUInt16(s(0))
End Function
 Public Shared Function ToUTF16(ch As Char) As UShort
Return Convert.ToUInt16(ch)
End Function
' CLS-compliant alternative for ToUTF16(String).
Public Shared Function ToUTF16CodeUnit(s As String) As Integer
s = s.Normalize(NormalizationForm.FormC)
Return CInt(Convert.ToInt16(s(0)))
End Function
' CLS-compliant alternative for ToUTF16(Char).
Public Shared Function ToUTF16CodeUnit(ch As Char) As Integer
Return Convert.ToInt32(ch)
End Function
Public Function HasMultipleRepresentations(s As String) As Boolean
Dim s1 As String = s.Normalize(NormalizationForm.FormC)
Return s.Equals(s1)
End Function
Public Function GetUnicodeCodePoint(ch As Char) As Integer
If Char.IsSurrogate(ch) Then
Throw New ArgumentException("ch cannot be a high or low surrogate.")
End If
Return Char.ConvertToUtf32(ch.ToString(), 0)
End Function
Public Function GetUnicodeCodePoint(chars() As Char) As Integer
If chars.Length > 2 Then
Throw New ArgumentException("The array has too many characters.")
End If
If chars.Length = 2 Then
If Not Char.IsSurrogatePair(chars(0), chars(1)) Then
Throw New ArgumentException("The array must contain a low and a high surrogate.")
Else
Return Char.ConvertToUtf32(chars(0), chars(1))
End If
Else
Return Char.ConvertToUtf32(chars.ToString(), 0)
End If
End Function
End Class

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
Public Module StringLib
Private exclusions As List(Of String)
Sub New()
Dim words() As String = { "a", "an", "and", "of", "the" }
exclusions = New List(Of String)
exclusions.AddRange(words)
End Sub
 _
Public Function ToTitleCase(title As String) As String
Dim words() As String = title.Split()
Dim result As String = String.Empty
For ctr As Integer = 0 To words.Length - 1
Dim word As String = words(ctr)
If ctr = 0 OrElse Not exclusions.Contains(word.ToLower()) Then
result += word.Substring(0, 1).ToUpper() + _
word.Substring(1).ToLower()
Else
result += word.ToLower()
End If
If ctr <= words.Length - 1 Then
result += " "
End If
Next
Return result
End Function
End Module

Here's the source code for NumberUtil.cs, which defines a

NumericLib

class that has two members,

IsEven

and

NearZero

.

using System;
public static class NumericLib
{
public static bool IsEven(this IConvertible number)
{
if (number is Byte ||
number is SByte ||
number is Int16 ||
number is UInt16 ||
number is Int32 ||
number is UInt32 ||
number is Int64)
return ((long) number) % 2 == 0;
else if (number is UInt64)
return ((ulong) number) %2 == 0;
else
throw new NotSupportedException("IsEven called for a non-integer value.");
}
public static bool NearZero(double number)
{
return number < .00001;
}
}

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:
vbc /t:module StringUtil.vb

To compile the C# source code file into a module, use this command:
csc /t:module NumberUtil.cs

You then use the Link tool (Link.exe) to compile the two modules into an assembly:
link numberutil.netmodule stringutil.netmodule /out:UtilityLib.dll /dll

The following example then calls the NumericLib.NearZero and
are able to access the methods in both classes.

StringLib.ToTitleCase

methods. Note that both the Visual Basic code and the C# code

using System;
public class Example
{
public static void Main()
{
Double dbl = 0.0 - Double.Epsilon;
Console.WriteLine(NumericLib.NearZero(dbl));
string s = "war and peace";
Console.WriteLine(s.ToTitleCase());
}
}
// The example displays the following output:
//
True
//
War and Peace

Module Example
Public Sub Main()
Dim dbl As Double = 0.0 - Double.Epsilon
Console.WriteLine(NumericLib.NearZero(dbl))
Dim s As String = "war and peace"
Console.WriteLine(s.ToTitleCase())
End Sub
End Module
' The example displays the following output:
'
True
'
War and Peace

To compile the Visual Basic code, use this command:
vbc example.vb /r:UtilityLib.dll

To compile with C#, change the name of the compiler from vbc to csc, and change the file extension from .vb to .cs:
csc example.cs /r:UtilityLib.dll

Language Independence and Language-Independent Components
5/2/2018 • 68 minutes to read • Edit Online

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

CLS compliance rules
This section discusses the rules for creating a CLS-compliant component. For a complete list of rules, see Partition I, Clause 11 of the ECMA-335
Standard: Common Language Infrastructure.
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
type UInt16, the following code displays a compiler warning.

Person

class in the following example exposes an

Age

property of

using System;
[assembly: CLSCompliant(true)]
public class Person
{
private UInt16 personAge = 0;
public UInt16 Age
{ get { return personAge; } }
}
// The attempt to compile the example displays the following compiler warning:
//
Public1.cs(10,18): warning CS3003: Type of 'Person.Age' is not CLS-compliant


Public Class Person
Private personAge As UInt16
Public ReadOnly Property Age As UInt16
Get
Return personAge
End Get
End Property
End Class
' The attempt to compile the example displays the following compiler warning:
'
Public1.vb(9) : warning BC40027: Return type of function 'Age' is not CLS-compliant.
'
'
Public ReadOnly Property Age As UInt16
'
~~~

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)]
public class Person
{
private Int16 personAge = 0;
public Int16 Age
{ get { return personAge; } }
}


Public Class Person
Private personAge As UInt16
Public ReadOnly Property Age As Int16
Get
Return CType(personAge, Int16)
End Get
End Property
End Class

A library's public interface consists of the following:
Definitions of public classes.
Definitions of the public members of public classes, and definitions of members accessible to derived classes (that is, protected members).
Parameters and return types of public methods of public classes, and parameters and return types of methods accessible to derived classes.
The rules for CLS compliance are listed in the following table. The text of the rules is taken verbatim from the ECMA-335 Standard: Common Language
Infrastructure, which is Copyright 2012 by Ecma International. More detailed information about these rules is found in the following sections.

CATEGORY

SEE

RULE

RULE NUMBER

Accessibility

Member accessibility

Accessibility shall not be changed when
overriding inherited methods, except
when overriding a method inherited
from a different assembly with
accessibility family-or-assembly . In
this case, the override shall have
accessibility family .

10

Accessibility

Member accessibility

The visibility and accessibility of types
and members shall be such that types
in the signature of any member shall
be visible and accessible whenever the
member itself is visible and accessible.
For example, a public method that is
visible outside its assembly shall not
have an argument whose type is visible
only within the assembly. The visibility
and accessibility of types composing an
instantiated generic type used in the
signature of any member shall be
visible and accessible whenever the
member itself is visible and accessible.
For example, an instantiated generic
type present in the signature of a
member that is visible outside its
assembly shall not have a generic
argument whose type is visible only
within the assembly.

12

Arrays

Arrays

Arrays shall have elements with a CLScompliant type, and all dimensions of
the array shall have lower bounds of
zero. Only the fact that an item is an
array and the element type of the array
shall be required to distinguish
between overloads. When overloading
is based on two or more array types
the element types shall be named
types.

16

Attributes

Attributes

Attributes shall be of type
System.Attribute, or a type inheriting
from it.

41

Attributes

Attributes

The CLS only allows a subset of the
encodings of custom attributes. The
only types that shall appear in these
encodings are (see Partition IV):
System.Type, System.String,
System.Char, System.Boolean,
System.Byte, System.Int16,
System.Int32, System.Int64,
System.Single, System.Double, and any
enumeration type based on a CLScompliant base integer type.

34

Attributes

Attributes

The CLS does not allow publicly visible
required modifiers ( modreq , see
Partition II), but does allow optional
modifiers ( modopt , see Partition II) it
does not understand.

35

Constructors

Constructors

An object constructor shall call some
instance constructor of its base class
before any access occurs to inherited
instance data. (This does not apply to
value types, which need not have
constructors.)

21

Constructors

Constructors

An object constructor shall not be
called except as part of the creation of
an object, and an object shall not be
initialized twice.

22

CATEGORY

SEE

RULE

RULE NUMBER

Enumerations

Enumerations

The underlying type of an enum shall
be a built-in CLS integer type, the
name of the field shall be "value__", and
that field shall be marked
RTSpecialName .

7

Enumerations

Enumerations

There are two distinct kinds of enums,
indicated by the presence or absence
of the System.FlagsAttribute (see
Partition IV Library) custom attribute.
One represents named integer values;
the other represents named bit flags
that can be combined to generate an
unnamed value. The value of an enum
is not limited to the specified values.

8

Enumerations

Enumerations

Literal static fields of an enum shall
have the type of the enum itself.

9

Events

Events

The methods that implement an event
shall be marked SpecialName in
themetadata.

29

Events

Events

The accessibility of an event and of its
accessors shall be identical.

30

Events

Events

The add and remove methods for
an event shall both either be present
or absent.

31

Events

Events

The add and remove methods for
an event shall each take one parameter
whose type defines the type of the
event and that shall be derived from
System.Delegate.

32

Events

Events

Events shall adhere to a specific
naming pattern. The SpecialName
attribute referred to in CLS rule 29
shall be ignored in appropriate name
comparisons and shall adhere to
identifier rules.

33

Exceptions

Exceptions

Objects that are thrown shall be of
type System.Exception or a type
inheriting from it. Nonetheless, CLScompliant methods are not required to
block the propagation of other types of
exceptions.

40

General

CLS compliance: the Rules

CLS rules apply only to those parts of a
type that are accessible or visible
outsideof the defining assembly.

1

General

CLS compliance: the Rules

Members of non-CLS compliant types
shall not be marked CLS-compliant.

2

Generics

Generic types and members

Nested types shall have at least as
many generic parameters as the
enclosing type. Generic parameters in a
nested type correspond by position to
the generic parameters in its enclosing
type.

42

Generics

Generic types and members

The name of a generic type shall
encode the number of type parameters
declared on the non-nested type, or
newly introduced to the type if nested,
according to the rules defined above.

43

Generics

Generic types and members

A generic type shall redeclare sufficient
constraints to guarantee that any
constraints on the base type, or
interfaces would be satisfied by the
generic type constraints.

4444

CATEGORY

SEE

RULE

RULE NUMBER

Generics

Generic types and members

Types used as constraints on generic
parameters shall themselves be CLScompliant.

45

Generics

Generic types and members

The visibility and accessibility of
members (including nested types) in an
instantiated generic type shall be
considered to be scoped to the specific
instantiation rather than the generic
type declaration as a whole. Assuming
this, the visibility and accessibility rules
of CLS rule 12 still apply.

46

Generics

Generic types and members

For each abstract or virtual generic
method, there shall be a default
concrete (nonabstract) implementation.

47

Interfaces

Interfaces

CLS-compliant interfaces shall not
require the definition of non-CLS
compliantmethods in order to
implement them.

18

Interfaces

Interfaces

CLS-compliant interfaces shall not
define static methods, nor shall they
define fields.

19

Members

Type members in general

Global static fields and methods are
not CLS-compliant.

36

Members

--

The value of a literal static is specified
through the use of field initialization
metadata. A CLS-compliant literal must
have a value specified in field
initialization metadata that is of exactly
the same type as the literal (or of the
underlying type, if that literal is an
enum ).

13

Members

Type members in general

The vararg constraint is not part of the
CLS, and the only calling convention
supported by the CLS is the standard
managed calling convention.

15

Naming conventions

Naming conventions

Assemblies shall follow Annex 7 of
Technical Report 15 of the Unicode
Standard3.0 governing the set of
characters permitted to start and be
included in identifiers, available onlineat
http://www.unicode.org/unicode/report
s/tr15/tr15-18.html. Identifiers shall be
in thecanonical format defined by
Unicode Normalization Form C. For
CLS purposes, two identifiersare the
same if their lowercase mappings (as
specified by the Unicode localeinsensitive, one-toonelowercase
mappings) are the same. That is, for
two identifiers to be considered
differentunder the CLS they shall differ
in more than simply their case.
However, in order to override
aninherited definition the CLI requires
the precise encoding of the original
declaration be used.

4

Overloading

Naming conventions

All names introduced in a CLScompliant scope shall be distinct
independent ofkind, except where the
names are identical and resolved via
overloading. That is, while the
CTSallows a single type to use the
same name for a method and a field,
the CLS does not.

5

CATEGORY

SEE

RULE

RULE NUMBER

Overloading

Naming conventions

Fields and nested types shall be distinct
by identifier comparison alone,
eventhough the CTS allows distinct
signatures to be distinguished.
Methods, properties, and eventsthat
have the same name (by identifier
comparison) shall differ by more than
just the return type,except as specified
in CLS Rule 39.

6

Overloading

Overloads

Only properties and methods can be
overloaded.

37

Overloading

Overloads

Properties and methods can be
overloaded based only on the number
and types of their parameters, except
the conversion operators named
op_Implicit and op_Explicit ,
which can also be overloaded based on
their return type.

38

Overloading

--

If two or more CLS-compliant methods
declared in a type have the same
nameand, for a specific set of type
instantiations, they have the same
parameter and return types, thenall
these methods shall be semantically
equivalent at those type instantiations.

48

Types

Type and type member signatures

System.Object is CLS-compliant. Any
other CLS-compliant class shall inherit
from a CLS-compliant class.

23

Properties

Properties

The methods that implement the
getter and setter methods of a
property shallbe marked
SpecialName in the metadata.

24

Properties

Properties

A property’s accessors shall all be
static, all be virtual, or all be instance.

26

Properties

Properties

The type of a property shall be the
return type of the getter and the type
of the last argument of the setter. The
types of the parameters of the
property shall be the types of the
parameters to the getter and the types
of all but the final parameter of the
setter. All of these types shall be CLScompliant, and shall not be managed
pointers (i.e., shall not be passed by
reference).

27

Properties

Properties

Properties shall adhere to a specific
naming pattern. The SpecialName
attribute referred to in CLS rule 24
shall be ignored in appropriate name
comparisons and shall adhere to
identifier rules. A property shall have a
getter method, a setter method, or
both.

28

Type conversion

Type conversion

If either

or
is provided, an alternate
means of providing the coercion shall
be provided.

39

op_Implicit

op_Explicit

Types

Type and type member signatures

Boxed value types are not CLScompliant.

3

Types

Type and type member signatures

All types appearing in a signature shall
be CLS-compliant. All types composing
an instantiated generic type shall be
CLS-compliant.

11

CATEGORY

SEE

RULE

RULE NUMBER

Types

Type and type member signatures

Typed references are not CLScompliant.

14

Types

Type and type member signatures

Unmanaged pointer types are not CLScompliant.

17

Types

Type and type member signatures

CLS-compliant classes, value types, and
interfaces shall not require the
implementation of non-CLS-compliant
members.

20

Types and type member signatures
The System.Object type is CLS-compliant and is the base type of all object types in the .NET Framework type system. Inheritance in the .NET
Framework is either implicit (for example, the String class implicitly inherits from the Object class) or explicit (for example, the
CultureNotFoundException class explicitly inherits from the ArgumentException class, which explicitly inherits from the SystemException class, which
explicitly inherits from the Exception class). For a derived type to be CLS compliant, its base type must also be CLS-compliant.
The following example shows a derived type whose base type is not CLS-compliant. It defines a base Counter class that uses an unsigned 32-bit
integer as a counter. Because the class provides counter functionality by wrapping an unsigned integer, the class is marked as non-CLS-compliant. As a
result, a derived class, NonZeroCounter , is also not CLS-compliant.
using System;
[assembly: CLSCompliant(true)]
[CLSCompliant(false)]
public class Counter
{
UInt32 ctr;
public Counter()
{
ctr = 0;
}
protected Counter(UInt32 ctr)
{
this.ctr = ctr;
}
public override string ToString()
{
return String.Format("{0}). ", ctr);
}
public UInt32 Value
{
get { return ctr; }
}
public void Increment()
{
ctr += (uint) 1;
}
}
public class NonZeroCounter : Counter
{
public NonZeroCounter(int startIndex) : this((uint) startIndex)
{
}
private NonZeroCounter(UInt32 startIndex) : base(startIndex)
{
}
}
// Compilation produces a compiler warning like the following:
//
Type3.cs(37,14): warning CS3009: 'NonZeroCounter': base type 'Counter' is not
//
CLS-compliant
//
Type3.cs(7,14): (Location of symbol related to previous warning)


 _
Public Class Counter
Dim ctr As UInt32
Public Sub New
ctr = 0
End Sub
Protected Sub New(ctr As UInt32)
ctr = ctr
End Sub
Public Overrides Function ToString() As String
Return String.Format("{0}). ", ctr)
End Function
Public ReadOnly Property Value As UInt32
Get
Return ctr
End Get
End Property
Public Sub Increment()
ctr += CType(1, UInt32)
End Sub
End Class
Public Class NonZeroCounter : Inherits Counter
Public Sub New(startIndex As Integer)
MyClass.New(CType(startIndex, UInt32))
End Sub
Private Sub New(startIndex As UInt32)
MyBase.New(CType(startIndex, UInt32))
End Sub
End Class
' Compilation produces a compiler warning like the following:
'
Type3.vb(34) : warning BC40026: 'NonZeroCounter' is not CLS-compliant
'
because it derives from 'Counter', which is not CLS-compliant.
'
'
Public Class NonZeroCounter : Inherits Counter
'
~~~~~~~~~~~~~~

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.
CLS-COMPLIANT TYPE

DESCRIPTION

Byte

8-bit unsigned integer

Int16

16-bit signed integer

Int32

32-bit signed integer

Int64

64-bit signed integer

Single

Single-precision floating-point value

Double

Double-precision floating-point value

Boolean

true

or

false

value type

Char

UTF-16 encoded code unit

Decimal

Non-floating-point decimal number

IntPtr

Pointer or handle of a platform-defined size

String

Collection of zero, one, or more Char objects

The intrinsic types listed in the following table are not CLS-Compliant.

NON-COMPLIANT TYPE

DESCRIPTION

CLS-COMPLIANT ALTERNATIVE

SByte

8-bit signed integer data type

Int16

TypedReference

Pointer to an object and its runtime type

None

UInt16

16-bit unsigned integer

Int32

UInt32

32-bit unsigned integer

Int64

UInt64

64-bit unsigned integer

Int64 (may overflow), BigInteger, or Double

UIntPtr

Unsigned pointer or handle

IntPtr

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
value type, the compiler flags it as non-CLS-compliant.

int*

named

Value

. Because an

int*

is a boxed

using System;
[assembly:CLSCompliant(true)]
public unsafe class TestClass
{
private int* val;
public TestClass(int number)
{
val = (int*) number;
}
public int* Value {
get { return val; }
}
}
// The compiler generates the following output when compiling this example:
//
warning CS3003: Type of 'TestClass.Value' is not CLS-compliant

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
see The CLSCompliantAttribute attribute section.

isCompliant

value of

false

to it. For more information,

The following example illustrates the problem of CLS compliance in a method signature and in generic type instantiation. It defines an
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.

InvoiceItem

using System;
[assembly: CLSCompliant(true)]
public class InvoiceItem
{
private uint invId = 0;
private uint itemId = 0;
private Nullable qty;
public InvoiceItem(uint sku, Nullable quantity)
{
itemId = sku;
qty = quantity;
}
public Nullable Quantity
{
get { return qty; }
set { qty = value; }
}
public uint InvoiceId
{
get { return invId; }
set { invId = value; }
}
}
// The attempt to compile the example displays the following output:
//
Type1.cs(13,23): warning CS3001: Argument type 'uint' is not CLS-compliant
//
Type1.cs(13,33): warning CS3001: Argument type 'uint?' is not CLS-compliant
//
Type1.cs(19,26): warning CS3003: Type of 'InvoiceItem.Quantity' is not CLS-compliant
//
Type1.cs(25,16): warning CS3003: Type of 'InvoiceItem.InvoiceId' is not CLS-compliant


Public Class InvoiceItem
Private invId As UInteger = 0
Private itemId As UInteger = 0
Private qty AS Nullable(Of UInteger)
Public Sub New(sku As UInteger, quantity As Nullable(Of UInteger))
itemId = sku
qty = quantity
End Sub
Public Property Quantity As Nullable(Of UInteger)
Get
Return qty
End Get
Set
qty = value
End Set
End Property
Public Property InvoiceId As UInteger
Get
Return invId
End Get
Set
invId = value
End Set
End Property
End Class
' The attempt to compile the example displays output similar to the following:
'
Type1.vb(13) : warning BC40028: Type of parameter 'sku' is not CLS-compliant.
'
'
Public Sub New(sku As UInteger, quantity As Nullable(Of UInteger))
'
~~~
'
Type1.vb(13) : warning BC40041: Type 'UInteger' is not CLS-compliant.
'
'
Public Sub New(sku As UInteger, quantity As Nullable(Of UInteger))
'
~~~~~~~~
'
Type1.vb(18) : warning BC40041: Type 'UInteger' is not CLS-compliant.
'
'
Public Property Quantity As Nullable(Of UInteger)
'
~~~~~~~~
'
Type1.vb(27) : warning BC40027: Return type of function 'InvoiceId' is not CLS-compliant.
'
'
Public Property InvoiceId As UInteger
'
~~~~~~~~~

To eliminate the compiler warnings, replace the non-CLS-compliant types in the

InvoiceItem

public interface with compliant types:

using System;
[assembly: CLSCompliant(true)]
public class InvoiceItem
{
private uint invId = 0;
private uint itemId = 0;
private Nullable qty;
public InvoiceItem(int sku, Nullable quantity)
{
if (sku <= 0)
throw new ArgumentOutOfRangeException("The item number is zero or negative.");
itemId = (uint) sku;
qty = quantity;
}
public Nullable Quantity
{
get { return qty; }
set { qty = value; }
}
public int InvoiceId
{
get { return (int) invId; }
set {
if (value <= 0)
throw new ArgumentOutOfRangeException("The invoice number is zero or negative.");
invId = (uint) value; }
}
}


Public Class InvoiceItem
Private invId As UInteger = 0
Private itemId As UInteger = 0
Private qty AS Nullable(Of Integer)
Public Sub New(sku As Integer, quantity As Nullable(Of Integer))
If sku <= 0 Then
Throw New ArgumentOutOfRangeException("The item number is zero or negative.")
End If
itemId = CUInt(sku)
qty = quantity
End Sub
Public Property Quantity As Nullable(Of Integer)
Get
Return qty
End Get
Set
qty = value
End Set
End Property
Public Property InvoiceId As Integer
Get
Return CInt(invId)
End Get
Set
invId = CUInt(value)
End Set
End Property
End Class

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)]
public class ArrayHelper
{
unsafe public static Array CreateInstance(Type type, int* ptr, int items)
{
Array arr = Array.CreateInstance(type, items);
int* addr = ptr;
for (int ctr = 0; ctr < items; ctr++) {
int value = *addr;
arr.SetValue(value, ctr);
addr++;
}
return arr;
}
}
// The attempt to compile this example displays the following output:
//
UnmanagedPtr1.cs(8,57): warning CS3001: Argument type 'int*' is not CLS-compliant

For CLS-compliant abstract classes (that is, classes marked as
CLS-compliant.

abstract

in C# or as

MustInherit

in Visual Basic), all members of the class must also be

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)]
public class Person : person
{
}
public class person
{
}
// 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 L ATIN 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)


Public Class Size
Private a1 As Double
Private a2 As Double
Public Property Å As Double
Get
Return a1
End Get
Set
a1 = value
End Set
End Property
Public Property Å As Double
Get
Return a2
End Get
Set
a2 = value
End Set
End Property
End Class
' Compilation produces a compiler warning like the following:
'
Naming1.vb(9) : error BC30269: 'Public Property Å As Double' has multiple definitions
'
with identical signatures.
'
'
Public Property Å 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)]
public class Converter
{
public double Conversion(int number)
{
return (double) number;
}
public float Conversion(int number)
{
return (float) number;
}
public double Conversion(long number)
{
return (double) number;
}
public bool Conversion
{
get { return true; }
}
}
// Compilation produces a compiler error like the following:
//
Naming3.cs(13,17): error CS0111: Type 'Converter' already defines a member called
//
'Conversion' with the same parameter types
//
Naming3.cs(8,18): (Location of symbol related to previous error)
//
Naming3.cs(23,16): error CS0102: The type 'Converter' already contains a definition for
//
'Conversion'
//
Naming3.cs(8,18): (Location of symbol related to previous error)


Public Class Converter
Public Function Conversion(number As Integer) As Double
Return CDbl(number)
End Function
Public Function Conversion(number As Integer) As Single
Return CSng(number)
End Function
Public Function Conversion(number As Long) As Double
Return CDbl(number)
End Function
Public ReadOnly Property Conversion As Boolean
Get
Return True
End Get
End Property
End Class
' Compilation produces a compiler error like the following:
'
Naming3.vb(8) : error BC30301: 'Public Function Conversion(number As Integer) As Double'
'
and 'Public Function Conversion(number As Integer) As Single' cannot
'
overload each other because they differ only by return types.
'
'
Public Function Conversion(number As Integer) As Double
'
~~~~~~~~~~
'
Naming3.vb(20) : error BC30260: 'Conversion' is already declared as 'Public Function
'
Conversion(number As Integer) As Single' in this class.
'
'
Public ReadOnly Property Conversion As Boolean
'
~~~~~~~~~~

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.

Public Class [case]
Private _id As Guid
Private name As String
Public Sub New(name As String)
_id = Guid.NewGuid()
Me.name = name
End Sub
Public ReadOnly Property ClientName As String
Get
Return name
End Get
End Property
End Class

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;
public class Example
{
public static void Main()
{
@case c = new @case("John");
Console.WriteLine(c.ClientName);
}
}

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.

, 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.
op_Explicit

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;
public struct UDouble
{
private double number;
public UDouble(double value)
{
if (value < 0)
throw new InvalidCastException("A negative value cannot be converted to a UDouble.");
number = value;
}
public UDouble(float value)
{
if (value < 0)
throw new InvalidCastException("A negative value cannot be converted to a UDouble.");
number = value;
}
public static readonly UDouble MinValue = (UDouble) 0.0;
public static readonly UDouble MaxValue = (UDouble) Double.MaxValue;
public static explicit operator Double(UDouble value)
{
return value.number;
}
public static implicit operator Single(UDouble value)
{
if (value.number > (double) Single.MaxValue)
throw new InvalidCastException("A UDouble value is out of range of the Single type.");
return (float) value.number;
}
public static explicit operator UDouble(double value)
{
if (value < 0)
throw new InvalidCastException("A negative value cannot be converted to a UDouble.");
return new UDouble(value);
}
public static implicit operator UDouble(float value)
{
if (value < 0)
throw new InvalidCastException("A negative value cannot be converted to a UDouble.");
return new UDouble(value);
}
public static Double ToDouble(UDouble value)
{
return (Double) value;
}
public static float ToSingle(UDouble value)
{
return (float) value;
}
public static UDouble FromDouble(double value)
{
return new UDouble(value);
}
public static UDouble FromSingle(float value)
{
return new UDouble(value);
}
}

Public Structure UDouble
Private number As Double
Public Sub New(value As Double)
If value < 0 Then
Throw New InvalidCastException("A negative value cannot be converted to a UDouble.")
End If
number = value
End Sub
Public Sub New(value As Single)
If value < 0 Then
Throw New InvalidCastException("A negative value cannot be converted to a UDouble.")
End If
number = value
End Sub
Public Shared ReadOnly MinValue As UDouble = CType(0.0, UDouble)
Public Shared ReadOnly MaxValue As UDouble = Double.MaxValue
Public Shared Widening Operator CType(value As UDouble) As Double
Return value.number
End Operator
Public Shared Narrowing Operator CType(value As UDouble) As Single
If value.number > CDbl(Single.MaxValue) Then
Throw New InvalidCastException("A UDouble value is out of range of the Single type.")
End If
Return CSng(value.number)
End Operator
Public Shared Narrowing Operator CType(value As Double) As UDouble
If value < 0 Then
Throw New InvalidCastException("A negative value cannot be converted to a UDouble.")
End If
Return New UDouble(value)
End Operator
Public Shared Narrowing Operator CType(value As Single) As UDouble
If value < 0 Then
Throw New InvalidCastException("A negative value cannot be converted to a UDouble.")
End If
Return New UDouble(value)
End Operator
Public Shared Function ToDouble(value As UDouble) As Double
Return CType(value, Double)
End Function
Public Shared Function ToSingle(value As UDouble) As Single
Return CType(value, Single)
End Function
Public Shared Function FromDouble(value As Double) As UDouble
Return New UDouble(value)
End Function
Public Shared Function FromSingle(value As Single) As UDouble
Return New UDouble(value)
End Function
End Structure

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)]
public class Numbers
{
public static Array GetTenPrimes()
{
Array arr = Array.CreateInstance(typeof(Int32), new int[] {10}, new int[] {1});
arr.SetValue(1, 1);
arr.SetValue(2, 2);
arr.SetValue(3, 3);
arr.SetValue(5, 4);
arr.SetValue(7, 5);
arr.SetValue(11, 6);
arr.SetValue(13, 7);
arr.SetValue(17, 8);
arr.SetValue(19, 9);
arr.SetValue(23, 10);
return arr;
}
}


Public Class Numbers
Public Shared Function GetTenPrimes() As Array
Dim arr As Array = Array.CreateInstance(GetType(Int32), {10}, {1})
arr.SetValue(1, 1)
arr.SetValue(2, 2)
arr.SetValue(3, 3)
arr.SetValue(5, 4)
arr.SetValue(7, 5)
arr.SetValue(11, 6)
arr.SetValue(13, 7)
arr.SetValue(17, 8)
arr.SetValue(19, 9)
arr.SetValue(23, 10)
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)]
public class Numbers
{
public static UInt32[] GetTenPrimes()
{
uint[] arr = { 1u, 2u, 3u, 5u, 7u, 11u, 13u, 17u, 19u };
return arr;
}
public static Object[] GetFivePrimes()
{
Object[] arr = { 1, 2, 3, 5u, 7u };
return arr;
}
}
// Compilation produces a compiler warning like the following:
//
Array2.cs(8,27): warning CS3002: Return type of 'Numbers.GetTenPrimes()' is not
//
CLS-compliant


Public Class Numbers
Public Shared Function GetTenPrimes() As UInt32()
Return { 1ui, 2ui, 3ui, 5ui, 7ui, 11ui, 13ui, 17ui, 19ui }
End Function
Public Shared Function GetFivePrimes() As Object()
Dim arr() As Object = { 1, 2, 3, 5ui, 7ui }
Return arr
End Function
End Class
' Compilation produces a compiler warning like the following:
'
warning BC40027: Return type of function 'GetTenPrimes' is not CLS-compliant.
'
'
Public Shared Function GetTenPrimes() As UInt32()
'
~~~~~~~~~~~~

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)]
public class Numbers
{
public static byte[] GetSquares(byte[] numbers)
{
byte[] numbersOut = new byte[numbers.Length];
for (int ctr = 0; ctr < numbers.Length; ctr++) {
int square = ((int) numbers[ctr]) * ((int) numbers[ctr]);
if (square <= Byte.MaxValue)
numbersOut[ctr] = (byte) square;
// If there's an overflow, assign MaxValue to the corresponding
// element.
else
numbersOut[ctr] = Byte.MaxValue;
}
return numbersOut;
}
public static BigInteger[] GetSquares(BigInteger[] numbers)
{
BigInteger[] numbersOut = new BigInteger[numbers.Length];
for (int ctr = 0; ctr < numbers.Length; ctr++)
numbersOut[ctr] = numbers[ctr] * numbers[ctr];
return numbersOut;
}
}

Imports System.Numerics

Public Module Numbers
Public Function GetSquares(numbers As Byte()) As Byte()
Dim numbersOut(numbers.Length - 1) As Byte
For ctr As Integer = 0 To numbers.Length - 1
Dim square As Integer = (CInt(numbers(ctr)) * CInt(numbers(ctr)))
If square <= Byte.MaxValue Then
numbersOut(ctr) = CByte(square)
' If there's an overflow, assign MaxValue to the corresponding
' element.
Else
numbersOut(ctr) = Byte.MaxValue
End If
Next
Return numbersOut
End Function
Public Function GetSquares(numbers As BigInteger()) As BigInteger()
Dim numbersOut(numbers.Length - 1) As BigInteger
For ctr As Integer = 0 To numbers.Length - 1
numbersOut(ctr) = numbers(ctr) * numbers(ctr)
Next
Return numbersOut
End Function
End Module

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,
non-CLS-compliant. This example generates a compiler warning.

INumber.GetUnsigned

, that is marked as

using System;
[assembly:CLSCompliant(true)]
public interface INumber
{
int Length();
[CLSCompliant(false)] ulong GetUnsigned();
}
// Attempting to compile the example displays output like the following:
//
Interface2.cs(8,32): warning CS3010: 'INumber.GetUnsigned()': CLS-compliant interfaces
//
must have only CLS-compliant members


Public Interface INumber
Function Length As Integer
 Function GetUnsigned As ULong
End Interface
' Attempting to compile the example displays output like the following:
'
Interface2.vb(9) : warning BC40033: Non CLS-compliant 'function' is not allowed in a
'
CLS-compliant interface.
'
'
 Function GetUnsigned As ULong
'
~~~~~~~~~~~

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)]
public interface IFahrenheit
{
decimal GetTemperature();
}
public interface ICelsius
{
decimal GetTemperature();
}
public class Temperature : ICelsius, IFahrenheit
{
private decimal _value;
public Temperature(decimal value)
{
// We assume that this is the Celsius value.
_value = value;
}
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


Public Interface IFahrenheit
Function GetTemperature() As Decimal
End Interface
Public Interface ICelsius
Function GetTemperature() As Decimal
End Interface
Public Class Temperature : Implements ICelsius, IFahrenheit
Private _value As Decimal
Public Sub New(value As Decimal)
' We assume that this is the Celsius value.
_value = value
End Sub
Public Function GetFahrenheit() As Decimal _
Implements IFahrenheit.GetTemperature
Return _value * 9 / 5 + 32
End Function
Public Function GetCelsius() As Decimal _
Implements ICelsius.GetTemperature
Return _value
End Function
End Class
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)]
public enum Size : uint {
Unspecified = 0,
XSmall = 1,
Small = 2,
Medium = 3,
Large = 4,
XLarge = 5
};
public class Clothing
{
public string Name;
public string Type;
public string Size;
}
// The attempt to compile the example displays a compiler warning like the following:
//
Enum3.cs(6,13): warning CS3009: 'Size': base type 'uint' is not CLS-compliant


Public Enum Size As UInt32
Unspecified = 0
XSmall = 1
Small = 2
Medium = 3
Large = 4
XLarge = 5
End Enum
Public Class Clothing
Public Name As String
Public Type As String
Public Size As Size
End Class
' The attempt to compile the example displays a compiler warning like the following:
'
Enum3.vb(6) : warning BC40032: Underlying type 'UInt32' of Enum is not CLS-compliant.
'
'
Public Enum Size As UInt32
'
~~~~

An enumeration type must have a single instance field named
enables you to reference the field value implicitly.

Value__

that is marked with the FieldAttributes.RTSpecialName attribute. This

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 .
There are two kinds of enumerations:
An enumeration that represents a set of mutually exclusive, named integer values. This type of enumeration is indicated by the absence of
the System.FlagsAttribute custom attribute.
An enumeration that represents a set of bit flags that can combine to generate an unnamed value. This type of enumeration is indicated by
the presence of the System.FlagsAttribute custom attribute.
For more information, see the documentation for the Enum structure.
The value of an enumeration is not limited to the range of its specified values. In other words, the range of values in an enumeration is the range
of its underlying value. You can use the Enum.IsDefined method to determine whether a specified value is a member of an enumeration.
Type members in general
The Common Language Specification requires all fields and methods to be accessed as members of a particular class. Therefore, global static fields and
methods (that is, static fields or methods that are defined apart from a type) are not CLS-compliant. If you try to include a global field or method in your
source code, both the C# and Visual Basic compilers generate a compiler error.
The Common Language Specification supports only the standard managed calling convention. It doesn't support unmanaged calling conventions and
methods with variable argument lists marked with the varargs keyword. For variable argument lists that are compatible with the standard managed
calling convention, use the ParamArrayAttribute attribute or the individual language's implementation, such as the params keyword in C# and the
ParamArray keyword in Visual Basic.
Member accessibility
Overriding an inherited member cannot change the accessibility of that member. For example, a public method in a base class cannot be overridden by
a private method in a derived class. There is one exception: a protected internal (in C#) or Protected Friend (in Visual Basic) member in one assembly
that is overridden by a type in a different assembly. In that case, the accessibility of the override is Protected .
The following example illustrates the error that is generated when the CLSCompliantAttribute attribute is set to true , and Person , which is a class
derived from Animal , tries to change the accessibility of the Species property from public to private. The example compiles successfully if its
accessibility is changed to public.

using System;
[assembly: CLSCompliant(true)]
public class Animal
{
private string _species;
public Animal(string species)
{
_species = species;
}
public virtual string Species
{
get { return _species; }
}
public override string ToString()
{
return _species;
}
}
public class Human : Animal
{
private string _name;
public Human(string name) : base("Homo Sapiens")
{
_name = name;
}
public string Name
{
get { return _name; }
}
private override string Species
{
get { return base.Species; }
}
public override string ToString()
{
return _name;
}
}
public class Example
{
public static void Main()
{
Human p = new Human("John");
Console.WriteLine(p.Species);
Console.WriteLine(p.ToString());
}
}
// The example displays the following output:
//
error CS0621: 'Human.Species': virtual or abstract members cannot be private


Public Class Animal
Private _species As String
Public Sub New(species As String)
_species = species
End Sub
Public Overridable ReadOnly Property Species As String
Get
Return _species
End Get
End Property
Public Overrides Function ToString() As String
Return _species
End Function
End Class
Public Class Human : Inherits Animal
Private _name As String
Public Sub New(name As String)
MyBase.New("Homo Sapiens")
_name = name
End Sub
Public ReadOnly Property Name As String
Get
Return _name
End Get
End Property
Private Overrides ReadOnly Property Species As String
Get
Return MyBase.Species
End Get
End Property
Public Overrides Function ToString() As String
Return _name
End Function
End Class
Public Module Example
Public Sub Main()
Dim p As New Human("John")
Console.WriteLine(p.Species)
Console.WriteLine(p.ToString())
End Sub
End Module
' The example displays the following output:
'
'Private Overrides ReadOnly Property Species As String' cannot override
'
'Public Overridable ReadOnly Property Species As String' because
'
they have different access levels.
'
'
Private Overrides ReadOnly Property Species As String

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;
public class StringWrapper
{
string internalString;
StringBuilder internalSB = null;
bool useSB = false;
public StringWrapper(StringOperationType type)
{
if (type == StringOperationType.Normal) {
useSB = false;
}
else {
useSB = true;
internalSB = new StringBuilder();
}
}
// The remaining source code...
}
internal enum StringOperationType { Normal, Dynamic }
// The attempt to compile the example displays the following output:
//
error CS0051: Inconsistent accessibility: parameter type
//
'StringOperationType' is less accessible than method
//
'StringWrapper.StringWrapper(StringOperationType)'

Imports System.Text

Public Class StringWrapper
Dim internalString As String
Dim internalSB As StringBuilder = Nothing
Dim useSB As Boolean = False
Public Sub New(type As StringOperationType)
If type = StringOperationType.Normal Then
useSB = False
Else
internalSB = New StringBuilder()
useSB = True
End If
End Sub
' The remaining source code...
End Class
Friend Enum StringOperationType As Integer
Normal = 0
Dynamic = 1
End Enum
' The attempt to compile the example displays the following output:
'
error BC30909: 'type' cannot expose type 'StringOperationType'
'
outside the project through class 'StringWrapper'.
'
'
Public Sub New(type As StringOperationType)
'
~~~~~~~~~~~~~~~~~~~

Generic types and members
Nested types always have at least as many generic parameters as their enclosing type. These correspond by position to the generic parameters in the
enclosing type. The generic type can also include new generic parameters.
The relationship between the generic type parameters of a containing type and its nested types may be hidden by the syntax of individual languages. In
the following example, a generic type Outer contains two nested classes, Inner1A and Inner1B . The calls to the ToString method, which each
class inherits from Object.ToString, show that each nested class includes the type parameters of its containing class.

using System;
[assembly:CLSCompliant(true)]
public class Outer
{
T value;
public Outer(T value)
{
this.value = value;
}
public class Inner1A : Outer
{
public Inner1A(T value) : base(value)
{ }
}
public class Inner1B : Outer
{
U value2;
public Inner1B(T value1, U value2) : base(value1)
{
this.value2 = value2;
}
}
}
public class Example
{
public static void Main()
{
var inst1 = new Outer("This");
Console.WriteLine(inst1);
var inst2 = new Outer.Inner1A("Another");
Console.WriteLine(inst2);
var inst3 = new Outer.Inner1B("That", 2);
Console.WriteLine(inst3);
}
}
// The example displays the following output:
//
Outer`1[System.String]
//
Outer`1+Inner1A[System.String]
//
Outer`1+Inner1B`1[System.String,System.Int32]


Public Class Outer(Of T)
Dim value As T
Public Sub New(value As T)
Me.value = value
End Sub
Public Class Inner1A : Inherits Outer(Of T)
Public Sub New(value As T)
MyBase.New(value)
End Sub
End Class
Public Class Inner1B(Of U) : Inherits Outer(Of T)
Dim value2 As U
Public Sub New(value1 As T, value2 As U)
MyBase.New(value1)
Me.value2 = value2
End Sub
End Class
End Class
Public Module Example
Public Sub Main()
Dim inst1 As New Outer(Of String)("This")
Console.WriteLine(inst1)
Dim inst2 As New Outer(Of String).Inner1A("Another")
Console.WriteLine(inst2)
Dim inst3 As New Outer(Of String).Inner1B(Of Integer)("That", 2)
Console.WriteLine(inst3)
End Sub
End Module
' The example displays the following output:
'
Outer`1[System.String]
'
Outer`1+Inner1A[System.String]
'
Outer`1+Inner1B`1[System.String,System.Int32]

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)]
[CLSCompliant(false)] public class BaseClass
{}

public class BaseCollection where T : BaseClass
{}
// Attempting to compile the example displays the following output:
//
warning CS3024: Constraint type 'BaseClass' is not CLS-compliant


 Public Class BaseClass
End Class

Public Class BaseCollection(Of T As BaseClass)
End Class
' Attempting to compile the example displays the following output:
'
warning BC40040: Generic parameter constraint type 'BaseClass' is not
'
CLS-compliant.
'
'
Public Class BaseCollection(Of T As BaseClass)
'
~~~~~~~~~

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 that can represent any numeric type. It also defines a FloatingPoint class that represents a
floating point value. However, the source code fails to compile, because it does not apply the constraint on Number (that T must be a value type) to

FloatingPoint

.

using System;
[assembly:CLSCompliant(true)]
public class Number where T : struct
{
// use Double as the underlying type, since its range is a superset of
// the ranges of all numeric types except BigInteger.
protected double number;
public Number(T value)
{
try {
this.number = Convert.ToDouble(value);
}
catch (OverflowException e) {
throw new ArgumentException("value is too large.", e);
}
catch (InvalidCastException e) {
throw new ArgumentException("The value parameter is not numeric.", e);
}
}
public T Add(T value)
{
return (T) Convert.ChangeType(number + Convert.ToDouble(value), typeof(T));
}
public T Subtract(T value)
{
return (T) Convert.ChangeType(number - Convert.ToDouble(value), typeof(T));
}
}
public class FloatingPoint : Number
{
public FloatingPoint(T number) : base(number)
{
if (typeof(float) == number.GetType() ||
typeof(double) == number.GetType() ||
typeof(decimal) == number.GetType())
this.number = Convert.ToDouble(number);
else
throw new ArgumentException("The number parameter is not a floating-point number.");
}
}
// The attempt to comple the example displays the following output:
//
error CS0453: The type 'T' must be a non-nullable value type in
//
order to use it as parameter 'T' in the generic type or method 'Number'


Public Class Number(Of
' Use Double as the
' the ranges of all
Protected number As

T As Structure)
underlying type, since its range is a superset of
numeric types except BigInteger.
Double

Public Sub New(value As T)
Try
Me.number = Convert.ToDouble(value)
Catch e As OverflowException
Throw New ArgumentException("value is too large.", e)
Catch e As InvalidCastException
Throw New ArgumentException("The value parameter is not numeric.", e)
End Try
End Sub
Public Function Add(value As T) As T
Return CType(Convert.ChangeType(number + Convert.ToDouble(value), GetType(T)), T)
End Function
Public Function Subtract(value As T) As T
Return CType(Convert.ChangeType(number - Convert.ToDouble(value), GetType(T)), T)
End Function
End Class
Public Class FloatingPoint(Of T) : Inherits Number(Of T)
Public Sub New(number As T)
MyBase.New(number)
If TypeOf number Is Single Or
TypeOf number Is Double Or
TypeOf number Is Decimal Then
Me.number = Convert.ToDouble(number)
Else
throw new ArgumentException("The number parameter
End If
End Sub
End Class
' The attempt to comple the example displays the following
'
error BC32105: Type argument 'T' does not satisfy the
'
constraint for type parameter 'T'.
'
'
Public Class FloatingPoint(Of T) : Inherits Number(Of
'

is not a floating-point number.")

output:
'Structure'

T)
~

The example compiles successfully if the constraint is added to the

FloatingPoint

class.

using System;
[assembly:CLSCompliant(true)]

public class Number where T : struct
{
// use Double as the underlying type, since its range is a superset of
// the ranges of all numeric types except BigInteger.
protected double number;
public Number(T value)
{
try {
this.number = Convert.ToDouble(value);
}
catch (OverflowException e) {
throw new ArgumentException("value is too large.", e);
}
catch (InvalidCastException e) {
throw new ArgumentException("The value parameter is not numeric.", e);
}
}
public T Add(T value)
{
return (T) Convert.ChangeType(number + Convert.ToDouble(value), typeof(T));
}
public T Subtract(T value)
{
return (T) Convert.ChangeType(number - Convert.ToDouble(value), typeof(T));
}
}
public class FloatingPoint : Number where T : struct
{
public FloatingPoint(T number) : base(number)
{
if (typeof(float) == number.GetType() ||
typeof(double) == number.GetType() ||
typeof(decimal) == number.GetType())
this.number = Convert.ToDouble(number);
else
throw new ArgumentException("The number parameter is not a floating-point number.");
}
}


Public Class Number(Of
' Use Double as the
' the ranges of all
Protected number As

T As Structure)
underlying type, since its range is a superset of
numeric types except BigInteger.
Double

Public Sub New(value As T)
Try
Me.number = Convert.ToDouble(value)
Catch e As OverflowException
Throw New ArgumentException("value is too large.", e)
Catch e As InvalidCastException
Throw New ArgumentException("The value parameter is not numeric.", e)
End Try
End Sub
Public Function Add(value As T) As T
Return CType(Convert.ChangeType(number + Convert.ToDouble(value), GetType(T)), T)
End Function
Public Function Subtract(value As T) As T
Return CType(Convert.ChangeType(number - Convert.ToDouble(value), GetType(T)), T)
End Function
End Class
Public Class FloatingPoint(Of T As Structure) : Inherits Number(Of T)
Public Sub New(number As T)
MyBase.New(number)
If TypeOf number Is Single Or
TypeOf number Is Double Or
TypeOf number Is Decimal Then
Me.number = Convert.ToDouble(number)
Else
throw new ArgumentException("The number parameter is not a floating-point number.")
End If
End Sub
End Class

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 (or C1(Of T) in Visual Basic), and a protected class, C1.N (or C1(Of T).N in Visual Basic).
C1 has two methods, M1 and M2 . However, M1 is not CLS-compliant because it tries to return a C1.N (or C1(Of Integer).N ) object from
C1 (or C1(Of T) ). A second class, C2 , is derived from C1 (or C1(Of Long) ). It has two methods, M3 and M4 . M3 is not CLS-compliant
because it tries to return a C1.N (or C1(Of Integer).N ) object from a subclass of C1 . 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)]
public class C1
{
protected class N { }
protected void M1(C1.N n) { } //
//
//
protected void M2(C1.N n) { } //
//

Not CLS-compliant - C1.N not
accessible from within C1 in all
languages
CLS-compliant – C1.N accessible
inside C1

}
public class C2 : C1
{
protected void M3(C1.N n) { } // Not CLS-compliant – C1.N is not
// accessible in C2 (extends C1)
protected void M4(C1.N n) { } // CLS-compliant, C1.N is
// accessible in C2 (extends C1)
}
// Attempting to compile the example displays output like the following:
//
Generics4.cs(9,22): warning CS3001: Argument type 'C1.N' is not CLS-compliant
//
Generics4.cs(18,22): warning CS3001: Argument type 'C1.N' is not CLS-compliant


Public Class C1(Of T)
Protected Class N
End Class
Protected Sub M1(n As C1(Of Integer).N)
End Sub

Protected Sub M2(n As C1(Of T).N)
End Sub
End Class

' Not CLS-compliant - C1.N not
' accessible from within C1(Of T) in all
' languages

' CLS-compliant – C1(Of T).N accessible
' inside C1(Of T)

Public Class C2 : Inherits C1(Of Long)
Protected Sub M3(n As C1(Of Integer).N)
End Sub

' Not CLS-compliant – C1(Of Integer).N is not
' accessible in C2 (extends C1(Of Long))

Protected Sub M4(n As C1(Of Long).N)
End Sub
End Class
' Attempting to compile the example displays output like the following:
'
error BC30508: 'n' cannot expose type 'C1(Of Integer).N' in namespace
'
'' through class 'C1'.
'
'
Protected Sub M1(n As C1(Of Integer).N) ' Not CLS-compliant - C1.N not
'
~~~~~~~~~~~~~~~~
'
error BC30389: 'C1(Of T).N' is not accessible in this context because
'
it is 'Protected'.
'
'
Protected Sub M3(n As C1(Of Integer).N) ' Not CLS-compliant - C1(Of Integer).N is not
'
'
~~~~~~~~~~~~~~~~
'
'
error BC30389: 'C1(Of T).N' is not accessible in this context because it is 'Protected'.
'
'
Protected Sub M4(n As C1(Of Long).N)
'
~~~~~~~~~~~~~

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)]
public class Person
{
private string fName, lName, _id;
public Person(string firstName, string lastName, string id)
{
if (String.IsNullOrEmpty(firstName + lastName))
throw new ArgumentNullException("Either a first name or a last name must be provided.");
fName = firstName;
lName = lastName;
_id = id;
}
public string FirstName
{
get { return fName; }
}
public string LastName
{
get { return lName; }
}
public string Id
{
get { return _id; }
}
public override string ToString()
{
return String.Format("{0}{1}{2}", fName,
String.IsNullOrEmpty(fName) ? "" : " ",
lName);
}
}
public class Doctor : Person
{
public Doctor(string firstName, string lastName, string id)
{
}
public override string ToString()
{
return "Dr. " + base.ToString();
}
}
// Attempting to compile the example displays output like the following:
//
ctor1.cs(45,11): error CS1729: 'Person' does not contain a constructor that takes 0
//
arguments
//
ctor1.cs(10,11): (Location of symbol related to previous error)


Public Class Person
Private fName, lName, _id As String
Public Sub New(firstName As String, lastName As String, id As String)
If String.IsNullOrEmpty(firstName + lastName) Then
Throw New ArgumentNullException("Either a first name or a last name must be provided.")
End If
fName = firstName
lName = lastName
_id = id
End Sub
Public ReadOnly Property FirstName As String
Get
Return fName
End Get
End Property
Public ReadOnly Property LastName As String
Get
Return lName
End Get
End Property
Public ReadOnly Property Id As String
Get
Return _id
End Get
End Property
Public Overrides Function ToString() As String
Return String.Format("{0}{1}{2}", fName,
If(String.IsNullOrEmpty(fName), "", " "),
lName)
End Function
End Class
Public Class Doctor : Inherits Person
Public Sub New(firstName As String, lastName As String, id As String)
End Sub
Public Overrides Function ToString() As String
Return "Dr. " + MyBase.ToString()
End Function
End Class
' Attempting to compile the example displays output like the following:
'
Ctor1.vb(46) : error BC30148: First statement of this 'Sub New' must be a call
'
to 'MyBase.New' or 'MyClass.New' because base class 'Person' of 'Doctor' does
'
not have an accessible 'Sub New' that can be called with no arguments.
'
'
Public Sub New()
'
~~~

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 and deserialization methods such as 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
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
AppDomain.AssemblyResolve event is named

add_

EventName. For example, the event subscription method for the
.

add_AssemblyResolve

A method for removing an event handler, named
event is named remove_AssemblyResolve .

remove_

EventName. For example, the removal method for the AppDomain.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 class TemperatureChangedEventArgs : EventArgs
{
private Decimal originalTemp;
private Decimal newTemp;
private DateTimeOffset when;
public TemperatureChangedEventArgs(Decimal original, Decimal @new, DateTimeOffset time)
{
originalTemp = original;
newTemp = @new;
when = time;
}
public Decimal OldTemperature
{
get { return originalTemp; }
}
public Decimal CurrentTemperature
{
get { return newTemp; }
}
public DateTimeOffset Time
{
get { return when; }
}
}
public delegate void TemperatureChanged(Object sender, TemperatureChangedEventArgs e);
public class Temperature
{
private struct TemperatureInfo
{
public Decimal Temperature;
public DateTimeOffset Recorded;
}
public event TemperatureChanged TemperatureChanged;
private
private
private
private

Decimal previous;
Decimal current;
Decimal tolerance;
List tis = new List();

public Temperature(Decimal temperature, Decimal tolerance)
{
current = temperature;
TemperatureInfo ti = new TemperatureInfo();
ti.Temperature = temperature;
tis.Add(ti);
ti.Recorded = DateTimeOffset.UtcNow;
this.tolerance = tolerance;
}
public Decimal CurrentTemperature
{
get { return current; }
set {
TemperatureInfo ti = new TemperatureInfo();
ti.Temperature = value;
ti.Recorded = DateTimeOffset.UtcNow;
previous = current;
current = value;

if (Math.Abs(current - previous) >= tolerance)
raise_TemperatureChanged(new TemperatureChangedEventArgs(previous, current, ti.Recorded));
}
}
public void raise_TemperatureChanged(TemperatureChangedEventArgs eventArgs)
{
if (TemperatureChanged == null)
return;
foreach (TemperatureChanged d in TemperatureChanged.GetInvocationList()) {
if (d.Method.Name.Contains("Duplicate"))
Console.WriteLine("Duplicate event handler; event handler not executed.");
else
d.Invoke(this, eventArgs);
}
}
}
public class Example
{
public Temperature temp;
public static void Main()
{
Example ex = new Example();
}
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();
}
public void RecordTemperatures()
{
temp.TemperatureChanged += this.DuplicateTemperatureNotification;
temp.CurrentTemperature = 66;
temp.CurrentTemperature = 63;
}
internal void TemperatureNotification(Object sender, TemperatureChangedEventArgs e)
{
Console.WriteLine("Notification 1: The temperature changed from {0} to {1}", e.OldTemperature, e.CurrentTemperature);
}
public void DuplicateTemperatureNotification(Object sender, TemperatureChangedEventArgs e)
{
Console.WriteLine("Notification 2: The temperature changed from {0} to {1}", e.OldTemperature, e.CurrentTemperature);
}
}

Imports System.Collections
Imports System.Collections.Generic

Public Class TemperatureChangedEventArgs
Private originalTemp As Decimal
Private newTemp As Decimal
Private [when] As DateTimeOffset

: Inherits EventArgs

Public Sub New(original As Decimal, [new] As Decimal, [time] As DateTimeOffset)
originalTemp = original
newTemp = [new]
[when] = [time]
End Sub
Public ReadOnly Property OldTemperature As Decimal
Get
Return originalTemp
End Get
End Property
Public ReadOnly Property CurrentTemperature As Decimal
Get
Return newTemp
End Get
End Property

Public ReadOnly Property [Time] As DateTimeOffset
Get
Return [when]
End Get
End Property
End Class
Public Delegate Sub TemperatureChanged(sender As Object, e As TemperatureChangedEventArgs)
Public Class Temperature
Private Structure TemperatureInfo
Dim Temperature As Decimal
Dim Recorded As DateTimeOffset
End Structure
Public Event TemperatureChanged As TemperatureChanged
Private
Private
Private
Private

previous As Decimal
current As Decimal
tolerance As Decimal
tis As New List(Of TemperatureInfo)

Public Sub New(temperature As Decimal, tolerance As Decimal)
current = temperature
Dim ti As New TemperatureInfo()
ti.Temperature = temperature
ti.Recorded = DateTimeOffset.UtcNow
tis.Add(ti)
Me.tolerance = tolerance
End Sub
Public Property CurrentTemperature As Decimal
Get
Return current
End Get
Set
Dim ti As New TemperatureInfo
ti.Temperature = value
ti.Recorded = DateTimeOffset.UtcNow
previous = current
current = value
If Math.Abs(current - previous) >= tolerance Then
raise_TemperatureChanged(New TemperatureChangedEventArgs(previous, current, ti.Recorded))
End If
End Set
End Property
Public Sub raise_TemperatureChanged(eventArgs As TemperatureChangedEventArgs)
If TemperatureChangedEvent Is Nothing Then Exit Sub
Dim ListenerList() As System.Delegate = TemperatureChangedEvent.GetInvocationList()
For Each d As TemperatureChanged In TemperatureChangedEvent.GetInvocationList()
If d.Method.Name.Contains("Duplicate") Then
Console.WriteLine("Duplicate event handler; event handler not executed.")
Else
d.Invoke(Me, eventArgs)
End If
Next
End Sub
End Class
Public Class Example
Public WithEvents temp As Temperature
Public Shared Sub Main()
Dim ex As New Example()
End Sub
Public Sub New()
temp = New Temperature(65, 3)
RecordTemperatures()
Dim ex As New Example(temp)
ex.RecordTemperatures()
End Sub
Public Sub New(t As Temperature)
temp = t
RecordTemperatures()
End Sub
Public Sub RecordTemperatures()
temp.CurrentTemperature = 66
temp.CurrentTemperature = 63
End Sub
Friend Shared Sub TemperatureNotification(sender As Object, e As TemperatureChangedEventArgs) _
Handles temp.TemperatureChanged
Console.WriteLine("Notification 1: The temperature changed from {0} to {1}", e.OldTemperature, e.CurrentTemperature)
End Sub

End Sub
Friend Shared Sub DuplicateTemperatureNotification(sender As Object, e As TemperatureChangedEventArgs) _
Handles temp.TemperatureChanged
Console.WriteLine("Notification 2: The temperature changed from {0} to {1}", e.OldTemperature, e.CurrentTemperature)
End Sub
End Class

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)]
public class ErrorClass
{
string msg;
public ErrorClass(string errorMessage)
{
msg = errorMessage;
}
public string Message
{
get { return msg; }
}
}
public static class StringUtilities
{
public static string[] SplitString(this string value, int index)
{
if (index < 0 | index > value.Length) {
ErrorClass badIndex = new ErrorClass("The index is not within the string.");
throw badIndex;
}
string[] retVal = { value.Substring(0, index - 1),
value.Substring(index) };
return retVal;
}
}
// Compilation produces a compiler error like the following:
//
Exceptions1.cs(26,16): error CS0155: The type caught or thrown must be derived from
//
System.Exception

Imports System.Runtime.CompilerServices

Public Class ErrorClass
Dim msg As String
Public Sub New(errorMessage As String)
msg = errorMessage
End Sub
Public ReadOnly Property Message As String
Get
Return msg
End Get
End Property
End Class
Public Module StringUtilities
 Public Function SplitString(value As String, index As Integer) As String()
If index < 0 Or index > value.Length Then
Dim BadIndex As New ErrorClass("The index is not within the string.")
Throw BadIndex
End If
Dim retVal() As String = { value.Substring(0, index - 1),
value.Substring(index) }
Return retVal
End Function
End Module
' Compilation produces a compiler error like the following:
'
Exceptions1.vb(27) : error BC30665: 'Throw' operand must derive from 'System.Exception'.
'
'
Throw BadIndex
'
~~~~~~~~~~~~~~

To correct this error, the ErrorClass class must inherit from System.Exception. In addition, the
example corrects these errors to define an ErrorClass class that is CLS-compliant.
using System;
[assembly: CLSCompliant(true)]
public class ErrorClass : Exception
{
string msg;
public ErrorClass(string errorMessage)
{
msg = errorMessage;
}
public override string Message
{
get { return msg; }
}
}
public static class StringUtilities
{
public static string[] SplitString(this string value, int index)
{
if (index < 0 | index > value.Length) {
ErrorClass badIndex = new ErrorClass("The index is not within the string.");
throw badIndex;
}
string[] retVal = { value.Substring(0, index - 1),
value.Substring(index) };
return retVal;
}
}

Message

property must be overridden. The following

Imports System.Runtime.CompilerServices

Public Class ErrorClass : Inherits Exception
Dim msg As String
Public Sub New(errorMessage As String)
msg = errorMessage
End Sub
Public Overrides ReadOnly Property Message As String
Get
Return msg
End Get
End Property
End Class
Public Module StringUtilities
 Public Function SplitString(value As String, index As Integer) As String()
If index < 0 Or index > value.Length Then
Dim BadIndex As New ErrorClass("The index is not within the string.")
Throw BadIndex
End If
Dim retVal() As String = { value.Substring(0, index - 1),
value.Substring(index) }
Return retVal
End Function
End Module

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;
public NumericAttribute(bool isNumeric)
{
_isNumeric = isNumeric;
}
public bool IsNumeric
{
get { return _isNumeric; }
}
}
[Numeric(true)] public struct UDouble
{
double Value;
}
// Compilation produces a compiler error like the following:
//
Attribute1.cs(22,2): error CS0616: 'NumericAttribute' is not an attribute class
//
Attribute1.cs(7,14): (Location of symbol related to previous error)


 _
Public Class NumericAttribute
Private _isNumeric As Boolean
Public Sub New(isNumeric As Boolean)
_isNumeric = isNumeric
End Sub
Public ReadOnly Property IsNumeric As Boolean
Get
Return _isNumeric
End Get
End Property
End Class
 Public Structure UDouble
Dim Value As Double
End Structure
' Compilation produces a compiler error like the following:
'
error BC31504: 'NumericAttribute' cannot be used as an attribute because it
'
does not inherit from 'System.Attribute'.
'
'
 Public Structure UDouble
'
~~~~~~~~~~~~~

The constructor or the properties of a CLS-compliant attribute can expose only the following types:
Boolean
Byte
Char
Double
Int16
Int32
Int64
Single
String
Type
Any enumeration type whose underlying type is Byte, Int16, Int32, or Int64.
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, whereas the Visual Basic compiler emits neither a
warning nor an error.
using System;
[assembly:CLSCompliantAttribute(true)]
public enum DescriptorType { type, member };
public class Descriptor
{
public DescriptorType Type;
public String Description;
}
[AttributeUsage(AttributeTargets.All)]
public class DescriptionAttribute : Attribute
{
private Descriptor desc;
public DescriptionAttribute(Descriptor d)
{
desc = d;
}
public Descriptor Descriptor
{ get { return desc; } }
}
// Attempting to compile the example displays output like the following:
//
warning CS3015: 'DescriptionAttribute' has no accessible
//
constructors which use only CLS-compliant types


Public Enum DescriptorType As Integer
Type = 0
Member = 1
End Enum
Public Class Descriptor
Public Type As DescriptorType
Public Description As String
End Class
 _
Public Class DescriptionAttribute : Inherits Attribute
Private desc As Descriptor
Public Sub New(d As Descriptor)
desc = d
End Sub
Public ReadOnly Property Descriptor As Descriptor
Get
Return desc
End Get
End Property
End Class

The CLSCompliantAttribute attribute
The CLSCompliantAttribute attribute is used to indicate whether a program element complies with the Common Language Specification. The
CLSCompliantAttribute.CLSCompliantAttribute(Boolean) constructor includes a single required parameter, isCompliant , that indicates whether the
program element is CLS-compliant.
At compile time, the compiler detects non-compliant elements that are presumed to be CLS-compliant and emits a warning. The compiler does not emit
warnings for types or members that are explicitly declared to be non-compliant.
Component developers can use the CLSCompliantAttribute attribute in two ways:
To define the parts of the public interface exposed by a component that are CLS-compliant and the parts that are not CLS-compliant. When the
attribute is used to mark particular program elements as CLS-compliant, its use guarantees that those elements are accessible from all languages
and tools that target the .NET Framework.
To ensure that the component library's public interface exposes only program elements that are CLS-compliant. If elements are not CLScompliant, compilers will generally issue a warning.
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. In this regard, 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 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 CLScompliant 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)]
public class CharacterUtilities
{
[CLSCompliant(false)] public static ushort ToUTF16(String s)
{
s = s.Normalize(NormalizationForm.FormC);
return Convert.ToUInt16(s[0]);
}
[CLSCompliant(false)] public static ushort ToUTF16(Char ch)
{
return Convert.ToUInt16(ch);
}
// CLS-compliant alternative for ToUTF16(String).
public static int ToUTF16CodeUnit(String s)
{
s = s.Normalize(NormalizationForm.FormC);
return (int) Convert.ToUInt16(s[0]);
}
// CLS-compliant alternative for ToUTF16(Char).
public static int ToUTF16CodeUnit(Char ch)
{
return Convert.ToInt32(ch);
}
public bool HasMultipleRepresentations(String s)
{
String s1 = s.Normalize(NormalizationForm.FormC);
return s.Equals(s1);
}
public int GetUnicodeCodePoint(Char ch)
{
if (Char.IsSurrogate(ch))
throw new ArgumentException("ch cannot be a high or low surrogate.");
return Char.ConvertToUtf32(ch.ToString(), 0);
}
public int GetUnicodeCodePoint(Char[] chars)
{
if (chars.Length > 2)
throw new ArgumentException("The array has too many characters.");
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

Public Class CharacterUtilities
 Public Shared Function ToUTF16(s As String) As UShort
s = s.Normalize(NormalizationForm.FormC)
Return Convert.ToUInt16(s(0))
End Function
 Public Shared Function ToUTF16(ch As Char) As UShort
Return Convert.ToUInt16(ch)
End Function
' CLS-compliant alternative for ToUTF16(String).
Public Shared Function ToUTF16CodeUnit(s As String) As Integer
s = s.Normalize(NormalizationForm.FormC)
Return CInt(Convert.ToInt16(s(0)))
End Function
' CLS-compliant alternative for ToUTF16(Char).
Public Shared Function ToUTF16CodeUnit(ch As Char) As Integer
Return Convert.ToInt32(ch)
End Function
Public Function HasMultipleRepresentations(s As String) As Boolean
Dim s1 As String = s.Normalize(NormalizationForm.FormC)
Return s.Equals(s1)
End Function
Public Function GetUnicodeCodePoint(ch As Char) As Integer
If Char.IsSurrogate(ch) Then
Throw New ArgumentException("ch cannot be a high or low surrogate.")
End If
Return Char.ConvertToUtf32(ch.ToString(), 0)
End Function
Public Function GetUnicodeCodePoint(chars() As Char) As Integer
If chars.Length > 2 Then
Throw New ArgumentException("The array has too many characters.")
End If
If chars.Length = 2 Then
If Not Char.IsSurrogatePair(chars(0), chars(1)) Then
Throw New ArgumentException("The array must contain a low and a high surrogate.")
Else
Return Char.ConvertToUtf32(chars(0), chars(1))
End If
Else
Return Char.ConvertToUtf32(chars.ToString(), 0)
End If
End Function
End Class

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 LanguageIndependent 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
Public Module StringLib
Private exclusions As List(Of String)
Sub New()
Dim words() As String = { "a", "an", "and", "of", "the" }
exclusions = New List(Of String)
exclusions.AddRange(words)
End Sub
 _
Public Function ToTitleCase(title As String) As String
Dim words() As String = title.Split()
Dim result As String = String.Empty
For ctr As Integer = 0 To words.Length - 1
Dim word As String = words(ctr)
If ctr = 0 OrElse Not exclusions.Contains(word.ToLower()) Then
result += word.Substring(0, 1).ToUpper() + _
word.Substring(1).ToLower()
Else
result += word.ToLower()
End If
If ctr <= words.Length - 1 Then
result += " "
End If
Next
Return result
End Function
End Module

Here's the source code for NumberUtil.cs, which defines a

NumericLib

class that has two members,

IsEven

and

NearZero

.

using System;
public static class NumericLib
{
public static bool IsEven(this IConvertible number)
{
if (number is Byte ||
number is SByte ||
number is Int16 ||
number is UInt16 ||
number is Int32 ||
number is UInt32 ||
number is Int64)
return Convert.ToInt64(number) % 2 == 0;
else if (number is UInt64)
return ((ulong) number) % 2 == 0;
else
throw new NotSupportedException("IsEven called for a non-integer value.");
}
public static bool NearZero(double number)
{
return Math.Abs(number) < .00001;
}
}

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:
vbc /t:module StringUtil.vb

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:
csc /t:module NumberUtil.cs

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:
link numberutil.netmodule stringutil.netmodule /out:UtilityLib.dll /dll

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;
public class Example
{
public static void Main()
{
Double dbl = 0.0 - Double.Epsilon;
Console.WriteLine(NumericLib.NearZero(dbl));
string s = "war and peace";
Console.WriteLine(s.ToTitleCase());
}
}
// The example displays the following output:
//
True
//
War and Peace

Module Example
Public Sub Main()
Dim dbl As Double = 0.0 - Double.Epsilon
Console.WriteLine(NumericLib.NearZero(dbl))
Dim s As String = "war and peace"
Console.WriteLine(s.ToTitleCase())
End Sub
End Module
' The example displays the following output:
'
True
'
War and Peace

To compile the Visual Basic code, use this command:
vbc example.vb /r:UtilityLib.dll

To compile with C#, change the name of the compiler from vbc to csc, and change the file extension from .vb to .cs:
csc example.cs /r:UtilityLib.dll

See Also
CLSCompliantAttribute

Framework Libraries
5/2/2018 • 2 minutes 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.

Base Class Libraries
The BCL provides the most foundational types and utility functionality and are the base of all other .NET class libraries. They aim to provide very
general implementations without any bias to any workload. Performance is always an important consideration, since apps might prefer a particular
policy, such as low-latency to high-throughput or low-memory to low-CPU usage. These libraries are intended to be high-performance generally, and
take a middle-ground approach according to these various performance concerns. For most apps, this approach has been quite successful.

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 - Represents a strongly typed list of objects that can be accessed by index. Is automatically resized as needed.
Dictionary - 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 class library overview
6/19/2018 • 4 minutes to read • Edit Online

.NET implementations include classes, interfaces, delegates, and value types that expedite and optimize the development process and provide access to
system functionality. To facilitate interoperability between languages, most .NET types are CLS-compliant and can therefore be used from any
programming language whose compiler conforms to the common language specification (CLS ).
.NET types are the foundation on which .NET applications, components, and controls are built. .NET implementations include 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.
.NET 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 classes that implements the interface.

Naming conventions
.NET 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.Generic.List represents the List type, which belongs to the System.Collections.Generic namespace.
The types in System.Collections.Generic can be used to work with generic collections.
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 .NET. 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 .NET supplies, briefly describes each type, and indicates the corresponding type in Visual Basic, C#, C++,
and F#.
VISUAL BASIC DATA
TYPE

C# DATA TYPE

C++/CLI DATA TYPE

F# DATA TYPE

An 8-bit unsigned
integer.

Byte

byte

unsigned char

byte

An 8-bit signed
integer.

SByte

sbyte

char
-orsigned char

sbyte

Short

short

short

int16

CATEGORY

CLASS NAME

DESCRIPTION

Integer

Byte

SByte

Not CLS-compliant.
Int16

A 16-bit signed
integer.

CATEGORY

CLASS NAME

DESCRIPTION

Int32

A 32-bit signed
integer.

VISUAL BASIC DATA
TYPE

C# DATA TYPE

C++/CLI DATA TYPE

F# DATA TYPE

Integer

int

int

int

-orlong
Int64

A 64-bit signed
integer.

Long

long

__int64

int64

UInt16

A 16-bit unsigned
integer.

UShort

ushort

unsigned short

uint16

UInteger

uint

unsigned int
-orunsigned long

uint32

ULong

ulong

unsigned __int64

uint64

Not CLS-compliant.
UInt32

A 32-bit unsigned
integer.
Not CLS-compliant.

UInt64

A 64-bit unsigned
integer.
Not CLS-compliant.

Floating point

Single

A single-precision
(32-bit) floatingpoint number.

Single

float

float

float32
or
single

Double

A double-precision
(64-bit) floatingpoint number.

Double

double

double

float
or
double

Logical

Boolean

A Boolean value
(true or false).

Boolean

bool

bool

bool

Other

Char

A Unicode (16-bit)
character.

Char

char

wchar_t

char

Decimal

A decimal (128-bit)
value.

Decimal

decimal

Decimal

decimal

IntPtr

A signed integer
whose size depends
on the underlying
platform (a 32-bit
value on a 32-bit
platform and a 64bit value on a 64-bit
platform).

IntPtr

IntPtr

IntPtr

unativeint

No built-in type.

No built-in type.

No built-in type.

An unsigned integer
whose size depends
on the underlying
platform (a 32- bit
value on a 32-bit
platform and a 64bit value on a 64-bit
platform).

UIntPtr

UIntPtr

UIntPtr

No built-in type.

No built-in type.

No built-in type.

UIntPtr

unativeint

Not CLS-compliant.
Object

The root of the
object hierarchy.

Object

object

Object^

obj

String

An immutable,
fixed-length string
of Unicode
characters.

String

string

String^

string

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, use the .NET API Browser to browse the .NET Class Library. The API reference documentation provides

documentation on each namespace, its types, and each of their members.

See Also
Common Type System
.NET API Browser
Overview

Working with Base Types in .NET
5/2/2018 • 2 minutes 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
6/19/2018 • 3 minutes 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 Standard class libraries are a merger of the platform-specific and portable library concept into a single model that provides the best of both.

Platform-specific class libraries
Platform-specific libraries are bound to a single .NET implementation (for example, .NET Framework on Windows) and can therefore take significant
dependencies on a known execution environment. Such an environment will expose a known set of APIs (.NET and OS APIs) and will maintain and
expose expected state (for example, Windows registry).
Developers who create platform specific libraries can fully exploit the underlying platform. The libraries will only ever run on that given platform,
making platform checks or other forms of conditional code unnecessary (modulo single sourcing code for multiple platforms).
Platform-specific libraries have been the primary class library type for the .NET Framework. Even as other .NET implementations emerged, platformspecific libraries remained the dominant library type.

Portable class libraries
Portable libraries are supported on multiple .NET implementations. They can still take dependencies on a known execution environment, however, the
environment is a synthetic one that is generated by the intersection of a set of concrete .NET implementations. This means that exposed APIs and
platform assumptions are a subset of what would be available to a platform-specific library.
You choose a platform configuration when you create a portable library. These are the set of platforms that you need to support (for example, .NET
Framework 4.5+, Windows Phone 8.0+). The more platforms you opt to support, the fewer APIs and fewer platform assumptions you can make, the
lowest common denominator. This characteristic can be confusing at first, since people often think "more is better", but find that more supported
platforms results in fewer available APIs.
Many library developers have switched from producing multiple platform-specific libraries from one source (using conditional compilation directives)
to portable libraries. There are several approaches for accessing platform-specific functionality within portable libraries, with bait-and-switch being the
most widely accepted technique at this point.

.NET Standard class libraries
.NET Standard libraries are a replacement of the platform-specific and portable libraries concepts. They are platform-specific in the sense that they
expose all functionality from the underlying platform (no synthetic platforms or platform intersections). They are portable in the sense that they work on
all supporting platforms.
The .NET Standard exposes a set of library contracts. .NET implementations must support each contract fully or not at all. Each implementation,
therefore, supports a set of .NET Standard contracts. The corollary is that each .NET Standard class library is supported on the platforms that support
its contract dependencies.
The .NET Standard does not expose the entire functionality of the .NET Framework (nor is that a goal), however, they do expose many more APIs than
Portable Class Libraries. More APIs will be added over time.
The following platforms support .NET Standard libraries:
.NET Core
.NET Framework
Mono
Xamarin.iOS, Xamarin.Mac, Xamarin.Android
Universal Windows Platform (UWP )
Windows
Windows Phone
Windows Phone Silverlight
For more information, see the .NET Standard topic.

Mono class libraries

Class libraries are supported on Mono, including the three types of libraries described above. Mono has often been seen (correctly) as a cross-platform
implementation of the Microsoft .NET Framework. In part, this was because platform-specific .NET Framework libraries could run on the Mono runtime
without modification or recompilation. This characteristic was in place before the creation of portable class libraries, so was an obvious choice to enable
binary portability between the .NET Framework and Mono (although it only worked in one direction).

The Roslyn based Analyzers
5/2/2018 • 2 minutes to read • Edit Online

Roslyn-based analyzers use the .NET Compiler SDK (Roslyn APIs) to analyze your project's source code to find issues and suggest corrections. Different
analyzers look for different classes of issues, ranging from practices that are likely to cause bugs to security concerns to API compatibility.
Roslyn-based analyzers work both interactively and during builds. The analyzer provides different guidance when in Visual Studio or in command-line
builds.
While you edit code in Visual Studio, the analyzers run as you make changes, catching possible issues as soon as you create code that trigger concerns.
Any issues are highlighted with squiggles under any issue. Visual Studio displays a light bulb, and when you click on it the analyzer will suggest possible
fixes for that issue. When you build the project, either in Visual Studio or from the command line, all the source code is analyzed and the analyzer
provides a full list of potential issues. The following figure shows one example.

Roslyn-based analyzers report potential issues as errors, warnings, or information based on the severity of the issue.
You install Roslyn-based analyzers as NuGet packages in your project. The configured analyzers and any settings for each analyzer are restored and run
on any developer's machine for that project.
NOTE
The user experience for Roslyn-based analyzers is different than that of the Code Analysis libraries like the older versions of FxCop and the security analysis tools. You
don't need to explicitly run the Roslyn-based analyzers. There's no need to use the "Run Code Analysis" menu items on the "Analyze" menu in Visual Studio. Roslynbased analyzers run asychronously as you work.

More information on specific analyzers
The following analyzers are covered in this section:
API Analyzer: This analyzer examines your code for potential compatibility risks or uses of deprecated APIs.
Framework Analyzer: This analyzer examines your code to ensure it follows the guidelines for .NET Framework applications. These rules include several
security-based recommendations.

.NET API analyzer
6/1/2018 • 4 minutes to read • Edit Online

The .NET API Analyzer is a Roslyn analyzer that discovers potential compatibility risks for C# APIs on different platforms and detects calls to deprecated
APIs. It can be useful for all C# developers at any stage of development.
API Analyzer comes as a NuGet package Microsoft.DotNet.Analyzers.Compatibility. After you reference it in a project, it automatically monitors the
code and indicates problematic API usage. You can also get suggestions on possible fixes by clicking on the light bulb. The drop-down menu includes an
option to suppress the warnings.
NOTE
The .NET API analyzer is still a pre-release version.

Prerequisites
Visual Studio 2017 or Visual Studio for Mac (all versions).

Discovering deprecated APIs
What are deprecated APIs?
The .NET family is a set of large products that are constantly upgraded to better serve customer needs. It's natural to deprecate some APIs and replace
them with new ones. An API is considered deprecated when a better alternative exists. One way to inform that an API is deprecated and shouldn't be
used is to mark it with the ObsoleteAttribute attribute. The disadvantage of this approach is that there is only one diagnostic ID for all obsolete APIs (for
C#, CS0612). This means that:
It's impossible to have dedicated documents for each case.
It's impossible to suppress certain category of warnings. You can suppress either all or none of them.
To inform users of a new deprecation, a referenced assembly or targeting package has to be updated.
The API Analyzer uses API-specific error codes that begin with DE (which stands for Deprecation Error), which allows control over the display of
individual warnings. The deprecated APIs identified by the analyzer are defined in the dotnet/platform-compat repo.
Using the API Analyzer
When a deprecated API, such as WebClient, is used in a code, API Analyzer highlights it with a green squiggly line. When you hover over the API call, a
light bulb is displayed with information about the API deprecation, as in the following example:

The Error List window contains warnings with a unique ID per deprecated API, as shown in the following example ( DE004 ):

By clicking on the ID, you go to a webpage with detailed information about why the API was deprecated and suggestions regarding alternative APIs
that can be used.
Any warnings can be suppressed by right-clicking on the highlighted member and selecting Suppress . There are two ways to
suppress warnings:
locally (in source)
globally (in a suppression file) - recommended
Suppressing warnings locally
To suppress warnings locally, right-click on the member you want to suppress warnings for and then select Quick Actions and Refactorings >
Suppress diagnostic ID > in Source. The #pragma warning preprocessor directive is added to your source code in the scope
defined:

Suppressing warnings globally
To suppress warnings globally, right-click on the member you want to suppress warnings for and then select Quick Actions and Refactorings >
Suppress diagnostic ID > in Suppression File.

A GlobalSuppressions.cs file is added to your project after the first suppression. New global suppressions are appended to this file.

Global suppression is the recommended way to ensure consistency of API usage across projects.

Discovering cross-platform issues
Similar to deprecated APIs, the analyzer identifies all APIs that are not cross-platform. For example, Console.WindowWidth works on Windows but not
on Linux and macOS. The diagnostic ID is shown in the Error List window. You can suppress that warning by right-clicking and selecting Quick
Actions and Refactorings. Unlike deprecation cases where you have two options (either keep using the deprecated member and suppress warnings or
not use it at all), here if you're developing your code only for certain platforms, you can suppress all warnings for all other platforms you don't plan to
run your code on. To do so, you just need to edit your project file and add the PlatformCompatIgnore property that lists all platforms to be ignored. The
accepted values are: Linux , macOS , and Windows .

Linux;macOS


If your code targets multiple platforms and you want to take advantage of an API not supported on some of them, you can guard that part of the code
with an if statement:

if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
var w = Console.WindowWidth;
// More code
}

You can also conditionally compile per target framework/operating system, but you currently need to do that manually.

Supported diagnostics
Currently, the analyzer handles the following cases:
Usage of a .NET Standard API that throws PlatformNotSupportedException (PC001).
Usage of a .NET Standard API that isn't available on the .NET Framework 4.6.1 (PC002).
Usage of a native API that doesn’t exist in UWP (PC003).
Usage of an API that is marked as deprecated (DEXXXX).

CI machine
All these diagnostics are available not only in the IDE, but also on the command line as part of building your project, which includes the CI server.

Configuration
The user decides how the diagnostics should be treated: as warnings, errors, suggestions, or to be turned off. For example, as an architect, you can
decide that compatibility issues should be treated as errors, calls to some deprecated APIs generate warnings, while others only generate suggestions.
You can configure this separately by diagnostic ID and by project. To do so in Solution Explorer, navigate to the Dependencies node under your
project. Expand the nodes Dependencies > Analyzers > Microsoft.DotNet.Analyzers.Compatibility. Right click on the diagnostic ID, select Set
Rule Set Severity and pick the desired option.

See also
Introducing API Analyzer blog post.
API Analyzer demo video on YouTube.

The .NET Portability Analyzer
5/2/2018 • 2 minutes to read • Edit Online

Want to make your libraries multi-platform? Want to see how much work is required to make your application compatible with other .NET
implementations and profiles, including .NET Core, .NET Standard, UWP, and Xamarin for iOS, Android, and Mac? 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.

How to use Portability Analyzer
To begin using the .NET Portability Analyzer, you first need to download and install the extension from the Visual Studio Marketplace. It works on Visual
Studio 2015 and Visual Studio 2017. You can configure it in Visual Studio via Analyze > Portability Analyzer Settings and select your Target
Platforms.

To analyze your entire project, right-click on your project in Solution Explorer and select Analyze Assembly Portability. Otherwise, go to the
Analyze menu and select Analyze Assembly Portability. From there, select your project’s executable or DLL.

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.

The .NET Framework Analyzer
5/2/2018 • 4 minutes to read • Edit Online

You can use the .NET Framework Analyzer to find potential issues in your .NET Framework-based application code. This analyzer finds potential issues
and suggests fixes to them.
The analyzer runs interactively in Visual Studio as you write your code or as part of a CI build. You should add the analyzer to your project as early as
possible in your development. The sooner you find any potential issues in your code, the easier they are to fix. However, you can add it at any time in the
development cycle. It finds any issues with the existing code and warns about new issues as you keep developing.

Installing and configuring the .NET Framework Analyzer
The .NET Security Analyzers must be installed as a NuGet package on every project where you want them to run. Only one developer needs to add
them to the project. The analyzer package is a project dependency and will run on every developer's machine once it has the updated solution.
The .NET Framework Analyzer is delivered in the Microsoft.NetFramework.Analyzers NuGet package. This package provides only the analyzers specific
to the .NET Framework, which includes security analyzers. In most cases, you'll want the Microsoft.CodeAnalysis.FxCopAnalyzers NuGet package. The
FxCopAnalyzers aggregate package contains all the framework analyzers included in the Framework.Analyzers package as well as the following
analyzers:
Microsoft.CodeQuality.Analyzers: Provides general guidance and guidance for .NET Standard APIs
Microsoft.NetCore.Analyzers: Provides analyzers specific to .NET Core APIs.
Text.Analyzers: Provides guidance for text included as code, including comments.
To install it, right-click on the project, and select "Manage Dependencies". From the NuGet explorer, search for "NetFramework Analyzer", or if you
prefer, "Fx Cop Analyzer". Install the latest stable version in all projects in your solution.

Using the .NET Framework Analyzer
Once the NuGet package is installed, build your solution. The analyzer will report any issues it locates in your codebase. The issues are reported as
warnings in the Visual Studio Error List window, as shown in the following image:

As you write code, you see squiggles underneath any potential issue in your code. Hover over any issue and you see details about the issue, and
suggestions for any possible fix, as shown in the following image:

The analyzers examine the code in your solution and provide you with a list of warnings for any of these issues:
CA1058: Types should not extend certain base types
There are a small number of types in the .NET Framework that you should not derived from directly.
Category: Design
Severity: Warning
Additional information: CA:1058: Types should not extend certain base types
CA2153: Do not catch corrupted state exceptions
Catching corrupted state exceptions could mask errors (such as access violations), resulting in an inconsistent state of execution or making it easier for
attackers to compromise a system. Instead, catch and handle a more specific set of exception type(s) or re-throw the exception
Category: Security
Severity: Warning
Additional information: ## CA2153: Do not catch corrupted state exceptions
CA2229: Implement serialization constructors
The analyzer generates this warning when you create a type that implements the ISerializable interface but does not define the required serialization
constructor. To fix a violation of this rule, implement the serialization constructor. For a sealed class, make the constructor private; otherwise, make it
protected. The serialization constructor has the following signature:
public class MyItemType
{
// The special constructor is used to deserialize values.
public MyItemType(SerializationInfo info, StreamingContext context)
{
// implementation removed.
}
}

Category: Usage
Severity: Warning
Additional information: CA2229: Implement serialization constructors
CA2235: Mark all non-serializable fields
An instance field of a type that is not serializable is declared in a type that is serializable. You must explicitly mark that field with the
NonSerializedAttribute to fix this warning.
Category: Usage
Severity: Warning
Additional information: CA2235: Mark all non-serializable fields
CA2237: Mark ISerializable types with serializable
To be recognized by the common language runtime as serializable, types must be marked by using the SerializableAttribute attribute even when the
type uses a custom serialization routine by implementing the ISerializable interface.
Category: Usage
Severity: Warning
Additional information: CA2237: Mark ISerializable types with serializable
CA3075: Insecure DTD processing in XML
If you use insecure DtdProcessing instances or reference external entity sources, the parser may accept untrusted input and disclose sensitive
information to attackers.
Category: Security

Severity: Warning
Additional information: A3075: Insecure DTD processing in XML
CA5350: Do not use weak cryptographic algorithms
Cryptographic algorithms degrade over time as attacks become more advanced. Depending on the type and application of this cryptographic algorithm,
further degradation of its cryptographic strength may allow attackers to read enciphered messages, tamper with enciphered messages, forge digital
signatures, tamper with hashed content, or otherwise compromise any cryptosystem based on this algorithm. For encryption, use an AES algorithm
(AES-256, AES-192 and AES-128 are acceptable) with a key length greater than or equal to 128 bits. For hashing, use a hashing function in the SHA-2
family, such as SHA-2 512, SHA-2 384, or SHA-2 256.
Category: Security
Severity: Warning
Additional information: CA5350: Do not use weak cryptographic algorithms
CA5351: Do not use broken cryptographic algorithms
An attack making it computationally feasible to break this algorithm exists. This allows attackers to break the cryptographic guarantees it is designed to
provide. Depending on the type and application of this cryptographic algorithm, this may allow attackers to read enciphered messages, tamper with
enciphered messages, forge digital signatures, tamper with hashed content, or otherwise compromise any cryptosystem based on this algorithm. For
encryption, use an AES algorithm (AES-256, AES-192 and AES-128 are acceptable) with a key length greater than or equal to 128 bits. For hashing, use
a hashing function in the SHA-2 family, such as SHA512, SHA384, or SHA256. For digital signatures, use RSA with a key length greater than or equal
to 2048-bits, or ECDSA with a key length greater than or equal to 256 bits.
Category: Security
Severity: Warning
Additional Information: CA5351: Do not use broken cryptographic algorithms

Handling and throwing exceptions in .NET
6/21/2018 • 2 minutes 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 can't 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 can't 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.

Exceptions vs. traditional error-handling methods
Traditionally, a language's error-handling model relied on either the language's unique way of detecting errors and locating handlers for them, or on the
error-handling mechanism provided by the operating system. The way .NET implements exception handling provides the following advantages:
Exception throwing and handling works the same for .NET programming languages.
Doesn't require any particular language syntax for handling exceptions, but allows each language to define its own syntax.
Exceptions can be thrown across process and even machine boundaries.
Exception-handling code can be added to an application to increase program reliability.
Exceptions offer advantages over other methods of error notification, such as return codes. Failures don't go unnoticed because if an exception is thrown
and you don't handle it, the runtime terminates your application. Invalid values don't continue to propagate through the system as a result of code that
fails to check for a failure return code.

Common exceptions
The following table lists some common exceptions with examples of what can cause them.
EXCEPTION TYPE

DESCRIPTION

EXAMPLE

Exception

Base class for all exceptions.

None (use a derived class of this exception).

IndexOutOfRangeException

Thrown by the runtime only when an array is indexed
improperly.

Indexing an array outside its valid range:

NullReferenceException

Thrown by the runtime only when a null object is
referenced.

arr[arr.Length+1]

object o = null;
o.ToString();

InvalidOperationException

Thrown by methods when in an invalid state.

Calling Enumerator.MoveNext() after removing an
item from the underlying collection.

ArgumentException

Base class for all argument exceptions.

None (use a derived class of this exception).

ArgumentNullException

Thrown by methods that do not allow an argument
to be null.

String s = null;

Thrown by methods that verify that arguments are in
a given range.

String s = "string";

ArgumentOutOfRangeException

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

"Calculate".IndexOf(s);

s.Substring(s.Length+1);

Best Practices for Exceptions
What Every Dev needs to Know About Exceptions in the Runtime.

.NET Assembly File Format
5/2/2018 • 2 minutes 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 or 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 componentspecific 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.

Processing the Assemblies
It is possible to write tools or APIs to process assemblies. Assembly information enables making programmatic decisions at runtime, re-writing
assemblies, providing API IntelliSense in an editor and generating documentation. System.Reflection and Mono.Cecil are good examples of tools that
are frequently used for this purpose.

Memory Management and Garbage Collection in .NET
5/2/2018 • 2 minutes to read • Edit Online

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
5/2/2018 • 3 minutes 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 is a Generic Collection that can be declared and used with any type: List , List , List , 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 and only add Persons to List , 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
using
using
using

System;
System.Collections;
System.Collections.Generic;
System.Diagnostics;

namespace GenericsExample {
class Program {
static void Main(string[] args) {
//generic list
List ListGeneric = new List { 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");
//timer for non-generic list sort
Stopwatch s2 = Stopwatch.StartNew();
ListNonGeneric.Sort();
s2.Stop();
Console.WriteLine($"Non-Generic Sort: {ListNonGeneric} \n Time taken: {s2.Elapsed.TotalMilliseconds}ms");
Console.ReadLine();
}
}
}

This program yields the following output:
Generic Sort: System.Collections.Generic.List\`1[System.Int32] Time taken: 0.0789ms
Non-Generic Sort: System.Collections.ArrayList Time taken: 2.4324ms

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

Further reading and resources
An Introduction to C# Generics
C# Programming Guide - Generics

Delegates and lambdas
5/2/2018 • 4 minutes to read • Edit Online

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.
public class Program
{
public delegate string Reverse(string s);
static string ReverseString(string s)
{
return new string(s.Reverse().ToArray());
}
static void Main(string[] args)
{
Reverse rev = ReverseString;
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:
is used when there is a need to perform an action using the arguments of the delegate.
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 .
Action<>
Func<>

We can now take our example above and rewrite it using the
same.

Func<>

delegate instead of a custom type. The program will continue running exactly the

public class Program
{
static string ReverseString(string s)
{
return new string(s.Reverse().ToArray());
}
static void Main(string[] args)
{
Func rev = ReverseString;
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.

public class Program
{
public static void Main(string[] args)
{
List list = new List();
for (int i = 1; i <= 100; i++)
{
list.Add(i);
}
List result = list.FindAll(
delegate(int no)
{
return (no%2 == 0);
}
);
foreach (var item in result)
{
Console.WriteLine(item);
}
}
}

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 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.
public class Program
{
public static void Main(string[] args)
{
List list = new List();
for (int i = 1; i <= 100; i++)
{
list.Add(i);
}
List result = list.FindAll(i => i % 2 == 0);
foreach (var item in result)
{
Console.WriteLine(item);
}
}
}

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();
Loaded += (o, e) =>
{
this.Title = "Loaded";
};
}

Further reading and resources
Delegates
Anonymous Functions

Lambda expressions

LINQ (Language Integrated Query)
6/9/2018 • 5 minutes to read • Edit Online

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:
var linqExperts = from p in programmers
where p.IsNewToLINQ
select new LINQExpert(p);

Same example using the

IEnumerable

API:

var linqExperts = programmers.Where(p => p.IsNewToLINQ)
.Select(p => new LINQExpert(p));

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.

Traditional imperative code:
var petLookup = new Dictionary();
foreach (var pet in pets)
{
petLookup.Add(pet.RFID, pet);
}

The intention behind the code is not to create a new Dictionary

and add to it via a loop, it is to convert an existing list into a dictionary! LINQ

Equivalent LINQ expression:
var petLookup = pets.ToDictionary(pet => pet.RFID);

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?

LINQ Providers Simplify Data Access
For a significant chunk of software out in the wild, everything revolves around dealing with data from some source (Databases, JSON, XML, etc). Often
this involves learning a new API for each data source, which can be annoying. LINQ simplifies this by abstracting common elements of data access into
a query syntax which looks the same no matter which data source you pick.
Consider the following: finding all XML elements with a specific attribute value.
public static IEnumerable FindAllElementsWithAttribute(XElement documentRoot, string elementName,
string attributeName, string value)
{
return from el in documentRoot.Elements(elementName)
where (string)el.Element(attributeName) == value
select el;
}

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!

Why Use the Query Syntax?
This is a question which often comes up. After all, this,

var filteredItems = myItems.Where(item => item.Foo);

is a lot more concise than this:
var filteredItems = from item in myItems
where item.Foo
select item;

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);
// Using the query syntax
var queryGermanShepards = from dog in dogs
where dog.Breed == DogBreed.GermanShepard
select dog;
// Mapping a list from type A to type B
var cats = dogs.Select(dog => dog.TurnIntoACat());
// Using the query syntax
var queryCats = from dog in dogs
select dog.TurnIntoACat();
// Summing the lengths of a set of strings
int seed = 0;
int sumOfStrings = strings.Aggregate(seed, (s1, s2) => s1.Length + s2.Length);

Flattening a list of lists:
// Transforms the list of kennels into a list of all their dogs.
var allDogsFromKennels = kennels.SelectMany(kennel => kennel.Dogs);

Union between two sets (with custom comparator):

public class DogHairLengthComparer : IEqualityComparer
{
public bool Equals(Dog a, Dog b)
{
if (a == null && b == null)
{
return true;
}
else if ((a == null && b != null) ||
(a != null && b == null))
{
return false;
}
else
{
return a.HairLengthType == b.HairLengthType;
}
}
public int GetHashCode(Dog d)
{
// default hashcode is enough here, as these are simple objects.
return b.GetHashCode();
}
}
...
// Gets all the short-haired dogs between two different kennels
var allShortHairedDogs = kennel1.Dogs.Union(kennel2.Dogs, new DogHairLengthComparer());

Intersection between two sets:
// Gets the volunteers who spend share time with two humane societies.
var volunteers = humaneSociety1.Volunteers.Intersect(humaneSociety2.Volunteers,
new VolunteerTimeComparer());

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(this T self, T to, params string[] ignore) where T : class
{
if (self != null && to != null)
{
var type = typeof(T);
var ignoreList = new List(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();
}
return self == to;
}

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.
Consider the following:

public static string GetAllFacebookUserLikesMessage(IEnumerable facebookUsers)
{
var seed = default(UInt64);
Func threadAccumulator = (t1, t2) => t1 + t2;
Func threadResultAccumulator = (t1, t2) => t1 + t2;
Func resultSelector = total => $"Facebook has {total} likes!";
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
5/2/2018 • 2 minutes 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.

Common Type System
To start from the beginning, remember that a .NET implementation is language agnostic. This doesn’t just mean that a programmer can write her code
in any language that can be compiled to IL. It also means that she needs to be able to interact with code written in other languages that are able to be
used on a .NET implementation.
In order to do this transparently, there has to be a common way to describe all supported types. This is what the Common Type System (CTS ) is in
charge of doing. It was made to do several things:
Establish a framework for cross-language execution.
Provide an object-oriented model to support implementing various languages on a .NET implementation.
Define a set of rules that all languages must follow when it comes to working with types.
Provide a library that contains the basic primitive types that are used in application development (such as,

Boolean

,

Byte

,

Char

etc.)

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.

Common Language Specification
To enable full interoperability scenarios, all objects that are created in code must rely on some commonality in the languages that are consuming them
(are their callers). Since there are numerous different languages, .NET has specified those commonalities in something called the Common Language
Specification (CLS ). CLS defines a set of features that are needed by many common applications. It also provides a sort of recipe for any language
that is implemented on top of .NET on what it needs to support.
CLS is a subset of the CTS. This means that all of the rules in the CTS also apply to the CLS, unless the CLS rules are more strict. If a component is built
using only the rules in the CLS, that is, it exposes only the CLS features in its API, it is said to be CLS-compliant. For instance, the
 are CLS-compliant precisely because they need to work across all of the languages that are supported on .NET.
You can consult the documents in the More Resources section below to get an overview of all the features in the CLS.

More resources
Common Type System
Common Language Specification

Parallel Processing, Concurrency, and Async Programming in .NET
5/2/2018 • 2 minutes to read • Edit Online

.NET provides several ways for you to write asynchronous code to make your application more responsive to a user and write parallel code that uses
multiple threads of execution to maximize the performance of your user's computer.

In This Section
Asynchronous Programming
Describes mechanisms for asynchronous programming provided by .NET.
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.
Threading
Describes the basic concurrency and synchronization mechanisms provided by .NET.

Async Overview
6/28/2018 • 2 minutes 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#.

Why Write Async Code?
Modern apps make extensive use of file and networking I/O. I/O APIs traditionally block by default, resulting in poor user experiences and hardware
utilization unless you want to learn and use challenging patterns. Task-based async APIs and the language-level asynchronous programming model
invert this model, making async execution the default with few new concepts to learn.
Async code has the following characteristics:
Handles more server requests by yielding threads to handle more requests while waiting for I/O requests to return.
Enables UIs to be more responsive by yielding threads to UI interaction while waiting for I/O requests and by transitioning long-running work to
other CPU cores.
Many of the newer .NET APIs are asynchronous.
It's easy to write async code in .NET!

What's next?
For more information, see the Async in depth topic.
The Asynchronous Programming Patterns topic provides an overview of the three asynchronous programming patterns supported in .NET:
Asynchronous Programming Model (APM ) (legacy)
Event-based Asynchronous Pattern (EAP ) (legacy)
Task-based Asynchronous Pattern (TAP ) (recommended for new development)
For more information about recommended task-based programming model, see the Task-based asynchronous programming topic.

Async in depth
7/17/2018 • 9 minutes 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 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.

Task and Task
Tasks are constructs used to implement what is known as the Promise Model of Concurrency. In short, they offer you a "promise" that work will be
completed at a later point, letting you coordinate with the promise with a clean API.
Task

represents a single operation which does not return a value.
represents a single operation which returns a value of type

Task

T

.

It’s important to reason about tasks as abstractions of work happening asynchronously, and not an abstraction over threading. By default, tasks execute
on the current thread and delegate work to the Operating System, as appropriate. Optionally, tasks can be explicitly requested to run on a separate
thread via the Task.Run API.
Tasks expose an API protocol for monitoring, waiting upon and accessing the result value (in the case of
the await keyword, provides a higher-level abstraction for using tasks.

Task

) of a task. Language integration, with

Using await allows your application or service to perform useful work while a task is running by yielding control to its caller until the task is done. Your
code does not need to rely on callbacks or events to continue execution after the task has been completed. The language and task API integration does
that for you. If you’re using Task , the await keyword will additionally "unwrap" the value returned when the Task is complete. The details of how
this works are explained further below.
You can learn more about tasks and the different ways to interact with them in the Task-based Asynchronous Pattern (TAP ) topic.

Deeper Dive into Tasks for an I/O-Bound Operation
The following section describes a 10,000 foot view of what happens with a typical async I/O call. Let's start with a couple examples.
The first example calls an async method and returns an active task, likely yet to complete.
public Task GetHtmlAsync()
{
// Execution is synchronous here
var client = new HttpClient();
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 GetFirstCharactersCountAsync(string url, int count)
{
// Execution is synchronous here
var client = new HttpClient();
// Execution of GetFirstCharactersCountAsync() is yielded to the caller here
// GetStringAsync returns a Task, which is *awaited*
var page = await client.GetStringAsync("http://www.dotnetfoundation.org");
// Execution resumes when the client.GetStringAsync task completes,
// becoming synchronous again.
if (count > page.Length)
{
return page;
}
else
{
return page.Substring(0, count);
}
}

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

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 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
calling a thread-safe delegate).

async

methods, and does not require extra work (such as

Deeper Dive into Task and Task for a CPU-Bound Operation
CPU-bound async code is a bit different than I/O-bound async code. Because the work is done on the CPU, there's no way to get around dedicating a
thread to the computation. The use of async and await provides you with a clean way to interact with a background thread and keep the caller of the
async method responsive. Note that this does not provide any protection for shared data. If you are using shared data, you will still need to apply an
appropriate synchronization strategy.
Here's a 10,000 foot view of a CPU-bound async call:

public async Task CalculateResult(InputData data)
{
// This queues up the work on the threadpool.
var expensiveResultTask = Task.Run(() => DoExpensiveCalculation(data));
// Note that at this point, you can do some other work concurrently,
// as CalculateResult() is still executing!
// Execution of CalculateResult is yielded here!
var result = await expensiveResultTask;
return result;
}

executes on the thread it was called on. When it calls Task.Run , it queues the expensive CPU-bound operation,
, on the thread pool and receives a Task 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.
CalculateResult()

DoExpensiveCalculation()

Once

is encountered, the execution of CalculateResult() is yielded to its caller, allowing other work to be done with the current thread while
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() .
await

DoExpensiveCalculation()

Why does async help here?
async and await are the best practice managing CPU-bound work when you need responsiveness. There are multiple patterns for using async with
CPU-bound work. It's important to note that there is a small cost to using async and it's not recommended for tight loops. It's up to you to determine
how you write your code around this new capability.

See also
Asynchronous programming in C#
Asynchronous programming with async and await (C#)
Async Programming in F#
Asynchronous Programming with Async and Await (Visual Basic)

Asynchronous Programming Patterns
6/28/2018 • 2 minutes 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
a provided buffer starting at a specified offset:

Read

method that reads a specified amount of data into

public class MyClass
{
public int Read(byte [] buffer, int offset, int count);
}

The APM counterpart of this method would expose the

BeginRead

and

EndRead

methods:

public class MyClass
{
public IAsyncResult BeginRead(
byte [] buffer, int offset, int count,
AsyncCallback callback, object state);
public int EndRead(IAsyncResult asyncResult);
}

The EAP counterpart would expose the following set of types and members:
public class MyClass
{
public void ReadAsync(byte [] buffer, int offset, int count);
public event ReadCompletedEventHandler ReadCompleted;
}

The TAP counterpart would expose the following single

ReadAsync

method:

public class MyClass
{
public Task 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.

TITLE

DESCRIPTION

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)

Parallel Programming in .NET
5/2/2018 • 2 minutes to read • Edit Online

Many personal computers and workstations have several CPU cores 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

Task Parallel Library (TPL)

Provides documentation for the System.Threading.Tasks.Parallel class, which
includes parallel versions of For and ForEach loops, and also for the
System.Threading.Tasks.Task class, which represents the preferred way to express
asynchronous operations.

Parallel LINQ (PLINQ)

A parallel implementation of LINQ to Objects that significantly improves
performance in many scenarios.

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.

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.

For Further Reading

Provides links to additional information and sample resources for parallel
programming in .NET.

See also
Async Overview
Managed Threading

Managed Threading
5/2/2018 • 2 minutes 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.
Task-based Asynchronous Pattern (TAP )
Provides an overview of the recommended pattern for asynchronous programming in .NET.
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.

Native Interoperability
5/2/2018 • 10 minutes 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.

Platform Invoke (P/Invoke)
P/Invoke is a technology that allows you to access structs, callbacks and functions in unmanaged libraries from your managed code. Most of the
P/Invoke API is contained in two namespaces: System and System.Runtime.InteropServices . Using these two namespaces will allow you access to the
attributes that describe how you want to communicate with the native component.
Let’s start from the most common example, and that is calling unmanaged functions in your managed code. Let’s show a message box from a
command-line application:
using System.Runtime.InteropServices;
public class Program {
// Import user32.dll (containing the function we need) and define
// the method corresponding to the native function.
[DllImport("user32.dll")]
public static extern int MessageBox(IntPtr hWnd, String text, String caption, int options);
public static void Main(string[] args) {
// Invoke the function as a regular managed method.
MessageBox(IntPtr.Zero, "Command-line message box", "Attention!", 0);
}
}

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 libSystem shared library and define the method corresponding to the native function.
[DllImport("libSystem.dylib")]
private static extern int getpid();
public static void Main(string[] args){
// Invoke the function and get the process ID.
int pid = getpid();
Console.WriteLine(pid);
}
}
}

It is also similar on Linux. The function name is the same, since

getpid(2)

is a standard POSIX system call.

using System;
using System.Runtime.InteropServices;
namespace PInvokeSamples {
public static class Program {
// Import the libc shared library and define the method corresponding to the native function.
[DllImport("libc.so.6")]
private static extern int getpid();
public static void Main(string[] args){
// Invoke the function and get the process ID.
int pid = getpid();
Console.WriteLine(pid);
}
}
}

Invoking managed code from unmanaged code
Of course, the runtime allows communication to flow both ways which enables you to call into managed artifacts from native functions, using function
pointers. The closest thing to a function pointer in managed code is a delegate, so this is what is used to allow callbacks from native code into managed
code.
The way to use this feature is similar to managed to native process described above. For a given callback, you define a delegate that matches the
signature, and pass that into the external method. The runtime will take care of everything else.
using System;
using System.Runtime.InteropServices;
namespace ConsoleApplication1 {
class Program {
// Define a delegate that corresponds to the unmanaged function.
delegate bool EnumWC(IntPtr hwnd, IntPtr lParam);
// Import user32.dll (containing the function we need) and define
// the method corresponding to the native function.
[DllImport("user32.dll")]
static extern int EnumWindows(EnumWC lpEnumFunc, IntPtr lParam);
// 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;
}
static void Main(string[] args) {
// Invoke the method; note the delegate as a first parameter.
EnumWindows(OutputWindow, IntPtr.Zero);
}
}
}

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);
// Implement the above DirClbk delegate;
// this one just prints out the filename that is passed to it.
static int DisplayEntry(string fName, StatClass stat, int typeFlag) {
Console.WriteLine(fName);
return 0;
}
public static void Main(string[] args){
// Call the native function.
// Note the second parameter which represents the delegate (callback).
ftw(".", DisplayEntry, 10);
}
}
// The native callback takes a pointer to a struct. The below class
// represents that struct in managed code. You can find more information
// about this in the section on marshalling 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;
}
}

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);
// Implement the above DirClbk delegate;
// this one just prints out the filename that is passed to it.
static int DisplayEntry(string fName, StatClass stat, int typeFlag) {
Console.WriteLine(fName);
return 0;
}
public static void Main(string[] args){
// Call the native function.
// Note the second parameter which represents the delegate (callback).
ftw(".", DisplayEntry, 10);
}
}
// The native callback takes a pointer to a struct. The below class
// represents that struct in managed code. You can find more information
// about this in the section on marshalling 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;
}
}

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);

Marshalling classes and structs
Another aspect of type marshalling is how to pass in a struct to an unmanaged method. For instance, some of the unmanaged methods require a struct
as a parameter. In these cases, we need to create a corresponding struct or a class in managed part of the world to use it as a parameter. However, just
defining the class is not enough, we also need to instruct the marshaler how to map fields in the class to the unmanaged struct. This is where the
StructLayout attribute comes into play.

[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;
}
public static void Main(string[] args) {
SystemTime st = new SystemTime();
GetSystemTime(st);
Console.WriteLine(st.Year);
}

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:
typedef struct _SYSTEMTIME {
WORD wYear;
WORD wMonth;
WORD wDayOfWeek;
WORD wDay;
WORD wHour;
WORD wMinute;
WORD wSecond;
WORD wMilliseconds;
} SYSTEMTIME, *PSYSTEMTIME*;

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
5/2/2018 • 4 minutes 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.

Common collection features
All collections provide methods for adding, removing or finding items in the collection. In addition, all collections that directly or indirectly implement
the ICollection interface or the ICollection interface share these features:
The ability to enumerate the collection
.NET Framework collections either implement System.Collections.IEnumerable or System.Collections.Generic.IEnumerable to enable the
collection to be iterated through. An enumerator can be thought of as a movable pointer to any element in the collection. The foreach, in
statement and the For Each...Next Statement use the enumerator exposed by the GetEnumerator method and hide the complexity of
manipulating the enumerator. In addition, any collection that implements System.Collections.Generic.IEnumerable is considered a queryable
type and can be queried with LINQ. LINQ queries provide a common pattern for accessing data. They are typically more concise and readable
than standard foreach loops, and provide filtering, ordering and grouping capabilities. LINQ queries can also improve performance. For more
information, see LINQ to Objects, Parallel LINQ (PLINQ ) and Introduction to LINQ Queries (C#).
The ability to copy the collection contents to an array
All collections can be copied to an array using the CopyTo method; however, the order of the elements in the new array is based on the sequence
in which the enumerator returns them. The resulting array is always one-dimensional with a lower bound of zero.
In addition, many collection classes contain the following features:
Capacity and Count properties
The capacity of a collection is the number of elements it can contain. The count of a collection is the number of elements it actually contains.
Some collections hide the capacity or the count or both.
Most collections automatically expand in capacity when the current capacity is reached. The memory is reallocated, and the elements are copied
from the old collection to the new one. This reduces the code required to use the collection; however, the performance of the collection might be
negatively affected. For example, for List, If Count is less than Capacity, adding an item is an O (1) operation. If the capacity needs to be
increased to accommodate the new element, adding an item becomes an O (n) operation, where n is Count. The best way to avoid poor
performance caused by multiple reallocations is to set the initial capacity to be the estimated size of the collection.
A BitArray is a special case; its capacity is the same as its length, which is the same as its count.
A consistent lower bound
The lower bound of a collection is the index of its first element. All indexed collections in the System.Collections namespaces have a lower bound
of zero, meaning they are 0-indexed. Array has a lower bound of zero by default, but a different lower bound can be defined when creating an
instance of the Array class using Array.CreateInstance.
Synchronization for access from multiple threads (System.Collections classes only).
Non-generic collection types in the System.Collections namespace provide some thread safety with synchronization; typically exposed through
the SyncRoot and IsSynchronized members. These collections are not thread-safe by default. If you require scalable and efficient multi-threaded
access to a collection, use one of the classes in the System.Collections.Concurrent namespace or consider using an immutable collection. For
more information, see Thread-Safe Collections.

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.

I WANT TO…

GENERIC COLLECTION OPTIONS

NON-GENERIC COLLECTION OPTIONS

THREAD-SAFE OR IMMUTABLE
COLLECTION OPTIONS

Store items as key/value pairs for quick
look-up by key

Dictionary

Hashtable

ConcurrentDictionary

(A collection of key/value pairs that are
organize based on the hash code of
the key.)

ReadOnlyDictionary

Array

ImmutableList

ArrayList

ImmutableArray

Queue

ConcurrentQueue

Access items by index

Use items first-in-first-out (FIFO)

List

Queue

ImmutableDictionary

ImmutableQueue
Use data Last-In-First-Out (LIFO)

Stack

Stack

ConcurrentStack
ImmutableStack

Access items sequentially

LinkedList

No recommendation

No recommendation

Receive notifications when items are
removed or added to the collection.
(implements INotifyPropertyChanged
and INotifyCollectionChanged)

ObservableCollection

No recommendation

No recommendation

A sorted collection

SortedList

SortedList

ImmutableSortedDictionary
ImmutableSortedSet

A set for mathematical functions

HashSet

No recommendation

SortedSet

ImmutableHashSet
ImmutableSortedSet

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, and
System.Collections.Generic.Dictionary.

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.

Sorted Collection Types

Describes sorted collections performance and characteristics

Hashtable and Dictionary Collection Types

Describes the features of generic and non-generic hash-based dictionary types.

Thread-Safe Collections

Describes collection types such as
System.Collections.Concurrent.BlockingCollection and
System.Collections.Concurrent.ConcurrentBag that support safe and efficient
concurrent access from multiple threads.

System.Collections.Immutable

Introduces the immutable collections and provides links to the collection types.

Reference
System.Array
System.Collections
System.Collections.Concurrent
System.Collections.Generic
System.Collections.Specialized
System.Linq
System.Collections.Immutable

Numerics in the .NET Framework
5/2/2018 • 3 minutes to read • Edit Online

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

SIGNED/UNSIGNED

SIZE (BYTES)

MINIMUM VALUE

MAXIMUM VALUE

System.Byte

Unsigned

1

0

255

System.Int16

Signed

2

-32,768

32,767

System.Int32

Signed

4

-2,147,483,648

2,147,483,647

System.Int64

Signed

8

-9,223,372,036,854,775,808

9,223,372,036,854,775,807

System.SByte

Signed

1

-128

127

System.UInt16

Unsigned

2

0

65,535

System.UInt32

Unsigned

4

0

4,294,967,295

System.UInt64

Unsigned

8

0

18,446,744,073,709,551,615

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

8

-1.79769313486232e308

1.79769313486232e308

System.Single

4

-3.402823e38

3.402823e38

System.Decimal

16

79,228,162,514,264,337,593,543,950,
335

79,228,162,514,264,337,593,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, Decimal.GetBits and 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.

SIMD-enabled vector types
The System.Numerics namespace includes a set of SIMD-enabled vector types for the .NET Framework. SIMD (Single Instruction Multiple Data
operations) allows some operations to be parallelized at the hardware level, which results in huge performance improvements in mathematical,
scientific, and graphics apps that perform computations over vectors.
The SIMD-enabled vector types in the .NET Framework include the following: . In addition, System.Numerics.Vectors includes a Plane type and a
Quaternion type.
Vector2, Vector3, and Vector4 types, which are 2-, 3-, and 4-dimensional vectors of type Single.
Two matrix types, Matrix3x2, which represents a 3x2 matrix; and Matrix4x4, which represents a 4x4 matrix.
The Plane and Quaternion types.
The SimD-enabled vector types are implemented in IL, which allows them to be used on non-SimD-enabled hardware and JIT compilers. To take
advantage of SIMD instructions, your 64-bit apps must be compiled by the new 64-bit JIT Compiler for managed code, which is included with the .NET
Framework 4.6; it adds SIMD support when targeting x64 processors.
SIMD can also be downloaded as a NuGet package. The NuGET package also includes a generic Vector structure that allows you to create a vector
of any primitive numeric type. (The primitive numeric types include all numeric types in the System namespace except for Decimal.) In addition, the
Vector structure provides a library of convenience methods that you can call when working with vectors.

See Also
Application Essentials

Dates, times, and time zones
5/2/2018 • 2 minutes 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
5/2/2018 • 7 minutes 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.

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
method named OnThresholdReached .

ThresholdReached

. The event is associated with the EventHandler delegate and raised in a

class Counter
{
public event EventHandler ThresholdReached;
protected virtual void OnThresholdReached(EventArgs e)
{
EventHandler handler = ThresholdReached;
if (handler != null)
{
handler(this, e);
}
}
// provide remaining implementation for the class
}

Public Class Counter
Public Event ThresholdReached As EventHandler
Protected Overridable Sub OnThresholdReached(e As EventArgs)
RaiseEvent ThresholdReached(Me, e)
End Sub
' provide remaining implementation for the class
End Class

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 delegates to support most event scenarios. Use the EventHandler
delegate for all events that do not include event data. Use the EventHandler 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 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 .
public delegate void ThresholdReachedEventHandler(object sender, ThresholdReachedEventArgs e);

Public Delegate Sub ThresholdReachedEventHandler(sender As Object, e As ThresholdReachedEventArgs)

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

public class ThresholdReachedEventArgs : EventArgs
{
public int Threshold { get; set; }
public DateTime TimeReached { get; set; }
}

Public Class ThresholdReachedEventArgs
Inherits EventArgs
Public Property Threshold As Integer
Public Property TimeReached As DateTime
End Class

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
method subscribes to the ThresholdReached event.

c_ThresholdReached

class Program
{
static void Main(string[] args)
{
Counter c = new Counter();
c.ThresholdReached += c_ThresholdReached;
// provide remaining implementation for the class
}
static void c_ThresholdReached(object sender, EventArgs e)
{
Console.WriteLine("The threshold was reached.");
}
}

that matches the signature for the EventHandler delegate. The

Module Module1
Sub Main()
Dim c As Counter = New Counter()
AddHandler c.ThresholdReached, AddressOf c_ThresholdReached
' provide remaining implementation for the class
End Sub
Sub c_ThresholdReached(sender As Object, e As EventArgs)
Console.WriteLine("The threshold was reached.")
End Sub
End Module

Static and Dynamic Event Handlers
The .NET Framework allows subscribers to register for event notifications either statically or dynamically. Static event handlers are in effect for the
entire life of the class whose events they handle. Dynamic event handlers are explicitly activated and deactivated during program execution, usually in
response to some conditional program logic. For example, they can be used if event notifications are needed only under certain conditions or if an
application provides multiple event handlers and run-time conditions define the appropriate one to use. The example in the previous section shows how
to dynamically add an event handler. For more information, see Events and Events.

Raising Multiple Events
If your class raises multiple events, the compiler generates one field per event delegate instance. If the number of events is large, the storage cost of one
field per delegate may not be acceptable. For those situations, the .NET Framework provides event properties that you can use with another data
structure of your choice to store event delegates.
Event properties consist of event declarations accompanied by event accessors. Event accessors are methods that you define to add or remove event
delegate instances from the storage data structure. Note that event properties are slower than event fields, because each event delegate must be
retrieved before it can be invoked. The trade-off is between memory and speed. If your class defines many events that are infrequently raised, you will
want to implement event properties. For more information, see How to: Handle Multiple Events Using Event Properties.

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
EventArgs
Delegate
Events and routed events overview (UWP apps)
Events (Visual Basic)
Events (C# Programming Guide)

Managed Execution Process
5/2/2018 • 7 minutes 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 LanguageIndependent 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

Compiling MSIL to Native Code
Before you can run Microsoft intermediate language (MSIL ), it must be compiled against the common language runtime to native code for the target
machine architecture. The .NET Framework provides two ways to perform this conversion:
A .NET Framework just-in-time (JIT) compiler.
The .NET Framework Ngen.exe (Native Image Generator).
Compilation by the JIT Compiler
JIT compilation converts MSIL to native code on demand at application run time, when the contents of an assembly are loaded and executed. Because
the common language runtime supplies a JIT compiler for each supported CPU architecture, developers can build a set of MSIL assemblies that can be
JIT-compiled and run on different computers with different machine architectures. However, if your managed code calls platform-specific native APIs or
a platform-specific class library, it will run only on that operating system.
JIT compilation takes into account the possibility that some code might never be called during execution. Instead of using time and memory to convert
all the MSIL in a PE file to native code, it converts the MSIL as needed during execution and stores the resulting native code in memory so that it is

accessible for subsequent calls in the context of that process. The loader creates and attaches a stub to each method in a type when the type is loaded
and initialized. When a method is called for the first time, the stub passes control to the JIT compiler, which converts the MSIL for that method into
native code and modifies the stub to point directly to the generated native code. Therefore, subsequent calls to the JIT-compiled method go directly to
the native code.
Install-Time Code Generation Using NGen.exe
Because the JIT compiler converts an assembly's MSIL to native code when individual methods defined in that assembly are called, it affects
performance adversely at run time. In most cases, that diminished performance is acceptable. More importantly, the code generated by the JIT compiler
is bound to the process that triggered the compilation. It cannot be shared across multiple processes. To allow the generated code to be shared across
multiple invocations of an application or across multiple processes that share a set of assemblies, the common language runtime supports an ahead-oftime compilation mode. This ahead-of-time compilation mode uses the Ngen.exe (Native Image Generator) to convert MSIL assemblies to native code
much like the JIT compiler does. However, the operation of Ngen.exe differs from that of the JIT compiler in three ways:
It performs the conversion from MSIL to native code before running the application instead of while the application is running.
It compiles an entire assembly at a time, instead of one method at a time.
It persists the generated code in the Native Image Cache as a file on disk.
Code Verification
As part of its compilation to native code, the MSIL code must pass a verification process unless an administrator has established a security policy that
allows the code to bypass verification. Verification examines MSIL and metadata to find out whether the code is type safe, which means that it accesses
only the memory locations it is authorized to access. Type safety helps isolate objects from each other and helps protect them from inadvertent or
malicious corruption. It also provides assurance that security restrictions on code can be reliably enforced.
The runtime relies on the fact that the following statements are true for code that is verifiably type safe:
A reference to a type is strictly compatible with the type being referenced.
Only appropriately defined operations are invoked on an object.
Identities are what they claim to be.
During the verification process, MSIL code is examined in an attempt to confirm that the code can access memory locations and call methods only
through properly defined types. For example, code cannot allow an object's fields to be accessed in a manner that allows memory locations to be
overrun. Additionally, verification inspects code to determine whether the MSIL has been correctly generated, because incorrect MSIL can lead to a
violation of the type safety rules. The verification process passes a well-defined set of type-safe code, and it passes only code that is type safe. However,
some type-safe code might not pass verification because of some limitations of the verification process, and some languages, by design, do not produce
verifiably type-safe code. If type-safe code is required by the security policy but the code does not pass verification, an exception is thrown when the
code is run.
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 JITcompiled 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
5/2/2018 • 8 minutes 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.

Metadata and the PE File Structure
Metadata is stored in one section of a .NET Framework portable executable (PE ) file, while Microsoft intermediate language (MSIL ) is stored in another
section of the PE file. The metadata portion of the file contains a series of table and heap data structures. The MSIL portion contains MSIL and
metadata tokens that reference the metadata portion of the PE file. You might encounter metadata tokens when you use tools such as the MSIL
Disassembler (Ildasm.exe) to view your code's MSIL, for example.
Metadata Tables and Heaps
Each metadata table holds information about the elements of your program. For example, one metadata table describes the classes in your code,
another table describes the fields, and so on. If you have ten classes in your code, the class table will have tens rows, one for each class. Metadata tables
reference other tables and heaps. For example, the metadata table for classes references the table for methods.

Metadata also stores information in four heap structures: string, blob, user string, and GUID. All the strings used to name types and members are stored
in the string heap. For example, a method table does not directly store the name of a particular method, but points to the method's name stored in the
string heap.
Metadata Tokens
Each row of each metadata table is uniquely identified in the MSIL portion of the PE file by a metadata token. Metadata tokens are conceptually similar
to pointers, persisted in MSIL, that reference a particular metadata table.
A metadata token is a four-byte number. The top byte denotes the metadata table to which a particular token refers (method, type, and so on). The
remaining three bytes specify the row in the metadata table that corresponds to the programming element being described. If you define a method in
C# and compile it into a PE file, the following metadata token might exist in the MSIL portion of the PE file:
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 SECTION

CONTENTS OF PE SECTION

PE header

The index of the PE file's main sections and the address of the entry point.
The runtime uses this information to identify the file as a PE file and to determine
where execution starts when loading the program into memory.

MSIL instructions

The Microsoft intermediate language instructions (MSIL) that make up your code.
Many MSIL instructions are accompanied by metadata tokens.

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.

Run-Time Use of Metadata
To better understand metadata and its role in the common language runtime, it might be helpful to construct a simple program and illustrate how
metadata affects its run-time life. The following code example shows two methods inside a class called MyApp . The Main method is the program entry
point, while the Add method simply returns the sum of two integer arguments.
Public Class MyApp
Public Shared Sub Main()
Dim ValueOne As Integer = 10
Dim ValueTwo As Integer = 20
Console.WriteLine("The Value is: {0}", Add(ValueOne, ValueTwo))
End Sub
Public Shared Function Add(One As Integer, Two As Integer) As Integer
Return (One + Two)
End Function
End Class

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-intime (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
exist in this assembly and have their own unique values, only this table is discussed.

Add

method. While other metadata tables

NAME
ROW

RELATIVE VIRTUAL
ADDRESS (RVA)

IMPLFLAGS

FLAGS

(POINTS TO STRING
HEAP.)

1

0x00002050

IL

Public

.ctor (constructor)

Managed

ReuseSlot

SIGNATURE (POINTS TO
BLOB HEAP.)

SpecialName
RTSpecialName
.ctor
2

0x00002058

IL

Public

Managed

Static

Main

String

Add

int, int, int

ReuseSlot
3

0x0000208c

IL

Public

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

Attributes

Describes how to apply attributes, write custom attributes, and retrieve information
that is stored in attributes.

Building Console Applications in the .NET Framework
5/2/2018 • 2 minutes to read • Edit Online

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 Console.In property is a System.IO.TextReader object, whereas the values of the Console.Out and 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 Console.Out property to a
System.IO.StreamWriter, which encapsulates a System.IO.FileStream by means of the Console.SetOut method. The Console.In and 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

.NET Framework Application Essentials
5/2/2018 • 2 minutes 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
6/29/2018 • 7 minutes 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.

Files and Directories
You can use the types in the System.IO namespace to interact with files and directories. For example, you can get and set properties for files and
directories, and retrieve collections of files and directories based on search criteria.
For path naming conventions and the ways to express a file path for Windows systems, including with the DOS device syntax supported in .NET Core
1.1 and later and the .NET Framework 4.6.2 and later, see File path formats on Windows systems.
Here are some commonly used file and directory classes:
File - provides static methods for creating, copying, deleting, moving, and opening files, and helps create a FileStream object.
FileInfo - provides instance methods for creating, copying, deleting, moving, and opening files, and helps create a FileStream object.
Directory - provides static methods for creating, moving, and enumerating through directories and subdirectories.
DirectoryInfo - provides instance methods for creating, moving, and enumerating through directories and subdirectories.
Path - provides methods and properties for processing directory strings in a cross-platform manner.
In addition to using these classes, Visual Basic users can use the methods and properties provided by the Microsoft.VisualBasic.FileIO.FileSystem class
for file I/O.
See How to: Copy Directories, How to: Create a Directory Listing, and How to: Enumerate Directories and Files.

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.

Readers and Writers
The System.IO namespace also provides types for reading encoded characters from streams and writing them to streams. Typically, streams are

designed for byte input and output. The reader and writer types handle the conversion of the encoded characters to and from bytes so the stream can
complete the operation. Each reader and writer class is associated with a stream, which can be retrieved through the class's BaseStream property.
Here are some commonly used reader and writer classes:
BinaryReader and BinaryWriter – for reading and writing primitive data types as binary values.
StreamReader and StreamWriter – for reading and writing characters by using an encoding value to convert the characters to and from bytes.
StringReader and StringWriter – for reading and writing characters to and from strings.
TextReader and TextWriter – serve as the abstract base classes for other readers and writers that read and write characters and strings, but not
binary data.
See How to: Read Text from a File, How to: Write Text to a File, How to: Read Characters from a String, and How to: Write Characters to a String.

Asynchronous I/O Operations
Reading or writing a large amount of data can be resource-intensive. You should perform these tasks asynchronously if your application needs to
remain responsive to the user. With synchronous I/O operations, the UI thread is blocked until the resource-intensive operation has completed. Use
asynchronous I/O operations when developing Windows 8.x Store apps to prevent creating the impression that your app has stopped working.
The asynchronous members contain Async in their names, such as the CopyToAsync, FlushAsync, ReadAsync, and WriteAsync methods. You use these
methods with the async and await keywords.
For more information, 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.

I/O Operations in Windows Store apps
The .NET for Windows 8.x Store apps contains many of the types for reading from and writing to streams; however, this set does not include all the .NET
Framework I/O types.
Some important differences to note when using I/O operations in Windows 8.x Store apps:
Types specifically related to file operations, such as File, FileInfo, Directory and DirectoryInfo, are not included in the .NET for Windows 8.x Store
apps. Instead, use the types in the Windows.Storage namespace of the Windows Runtime, such as StorageFile and StorageFolder.
Isolated storage is not available; instead, use application data.

Use asynchronous methods, such as ReadAsync and WriteAsync, to prevent blocking the UI thread.
The path-based compression types ZipFile and ZipFileExtensions are not available. Instead, use the types in the Windows.Storage.Compression
namespace.
You can convert between .NET Framework streams and Windows Runtime streams, if necessary. For more information, see How to: Convert Between
.NET Framework Streams and Windows Runtime Streams or System.IO.WindowsRuntimeStreamExtensions.
For more information about I/O operations in a Windows 8.x Store app, see Quickstart: Reading and writing files.

I/O and Security
When you use the classes in the System.IO namespace, you must follow operating system security requirements such as access control lists (ACLs) to
control access to files and directories. This requirement is in addition to any FileIOPermission requirements. You can manage ACLs programmatically.
For more information, see How to: Add or Remove Access Control List Entries.
Default security policies prevent Internet or intranet applications from accessing files on the user’s computer. Therefore, do not use the I/O classes that
require a path to a physical file when writing code that will be downloaded over the Internet or intranet. Instead, use isolated storage for traditional .NET
Framework applications, or use application data for Windows 8.x Store apps.
A security check is performed only when the stream is constructed. Therefore, do not open a stream and then pass it to less-trusted code or application
domains.

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 applications
6/9/2018 • 2 minutes 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.
.NET provides extensive support for the development of world-ready and localized applications. In particular, many type members in the .NET class
library aid globalization by returning values that reflect the conventions of either the current user's culture or a specified culture. Also, .NET supports
satellite assemblies, which facilitate the process of localizing an application.
For additional information, see the Globalization documentation.

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 languageneutral.
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 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
5/2/2018 • 2 minutes 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

Applying Attributes

Describes how to apply an attribute to an element of your code.

Writing Custom Attributes

Describes how to design custom attribute classes.

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
5/2/2018 • 2 minutes 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
5/2/2018 • 2 minutes 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.

Security in .NET
6/2/2018 • 2 minutes to read • Edit Online

The common language runtime and the .NET 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
provide useful classes and services that facilitate the use of cryptography and role-based security.

In This Section
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 .NET. This section is of interest to developers.
Secure Coding Guidelines
Describes some of the best practices for creating reliable .NET 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.
Security Changes Describes important changes to the .NET Framework security 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.

Serialization in .NET
5/2/2018 • 2 minutes 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/20/2018 • 3 minutes to read • Edit Online

You can develop apps for both Microsoft and non-Microsoft platforms by using the .NET Framework and Visual Studio.

Options for cross-platform development
IMPORTANT
Because Portable Class Library projects target only a very specific subset of .NET implementations, we strongly discourage their use in new application development.
The recommended replacement is a .NET Standard library, which targets all .NET implementations that support a specific version of the .NET Standard. For more
information, see .NET Standard.

To develop for multiple platforms, you can share source code or binaries, and you can make calls between .NET Framework code and Windows
Runtime APIs.
IF YOU WANT TO...

USE...

Share source code between Windows Phone 8.1 and Windows 8.1 apps

Shared projects (Universal Apps template in Visual Studio 2013, Update 2).
- Currently no Visual Basic support.
- You can separate platform-specific code by using # if statements.
For details, see:
- Build apps that target Windows and Windows Phone by using Visual Studio
(MSDN article)
- Using Visual Studio to build Universal XAML Apps (blog post)
- Using Visual Studio to Build XAML Converged Apps (video)

Share binaries between apps that target different platforms

Portable Class Library projects for code that is platform-agnostic.
- This approach is typically used for code that implements business logic.
- You can use Visual Basic or C#.
- API support varies by platform.
- Portable Class Library projects that target Windows 8.1 and Windows Phone 8.1
support Windows Runtime APIs and XAML. These features aren't available in older
versions of the Portable Class Library.
- If needed, you can abstract out platform-specific code by using interfaces or
abstract classes.
For details, see:
- Portable Class Library
- How to Make Portable Class Libraries Work for You (blog post)
- Using Portable Class Library with MVVM
- App Resources for Libraries That Target Multiple Platforms
- .NET Portability Analyzer (Visual Studio extension)

Share source code between apps for platforms other than Windows 8.1 and
Windows Phone 8.1

Add as link feature.
- 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.
For details, see:
- Share code with Add as Link (MSDN article)
- How to: Add Existing Items to a Project (MSDN article)

IF YOU WANT TO...

USE...

Write Windows Store apps using the .NET Framework or call Windows Runtime
APIs from .NET Framework code

Windows Runtime APIs from your .NET Framework C# or 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.
For details, see:
- .NET Framework Support for Windows Store Apps and Windows Runtime
- Passing a URI to the Windows Runtime
- System.IO.WindowsRuntimeStreamExtensions (MSDN API reference page)
- System.WindowsRuntimeSystemExtensions (MSDN API reference page)

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.
For details, see:
- Portable Class Library now available on all platforms. (blog post)
- Xamarin documentation

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 crossplatform apps.
For details, see:
- JavaScript Project Templates
- Porting a Windows Runtime app using JavaScript to Windows Phone

.NET Core Guide
5/10/2018 • 8 minutes to read • Edit Online

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 (Roslyn and F#) 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#, Visual Basic, and F# languages 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#, Visual Basic, 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 and Ionide.
.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 platformspecific 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.

Comparisons to other .NET implementations
It is perhaps easiest to understand the size and shape of .NET Core by comparing it to existing .NET implementations.
Comparison with .NET Framework
.NET was first announced by Microsoft in 2000 and then evolved from there. The .NET Framework has been the primary .NET implementation
produced by Microsoft during that 15+ year span.
The major differences between .NET Core and the .NET Framework:
App-models -- .NET Core does not support all the .NET Framework app-models, in part because many of them are built on Windows technologies,
such as WPF (built on top of DirectX). The console and ASP.NET Core app-models are supported by both .NET Core and .NET Framework.
APIs -- .NET Core contains many of the same, but fewer, APIs as the .NET Framework, and with a different factoring (assembly names are different;
type shape differs in key cases). These differences currently typically require changes to port source to .NET Core. .NET Core implements the .NET
Standard API, which will grow to include more of the .NET Framework BCL API over time.
Subsystems -- .NET Core implements a subset of the subsystems in the .NET Framework, with the goal of a simpler implementation and
programming model. For example, Code Access Security (CAS ) is not supported, while reflection is supported.
Platforms -- The .NET Framework supports Windows and Windows Server while .NET Core also supports macOS and Linux.
Open Source -- .NET Core is open source, while a read-only subset of the .NET Framework is open source.
While .NET Core is unique and has significant differences to the .NET Framework and other .NET implementations, it is straightforward to share code,
using either source or binary sharing techniques.
Comparison with Mono
Mono is the original cross-platform and open source .NET implementation, first shipping in 2004. It can be thought of as a community clone of the
.NET Framework. The Mono project team relied on the open .NET standards (notably ECMA 335) published by Microsoft in order to provide a
compatible implementation.
The major differences between .NET Core and Mono:
App-models -- Mono supports a subset of the .NET Framework app-models (for example, Windows Forms) and some additional ones (for
example, Xamarin.iOS ) through the Xamarin product. .NET Core doesn't support these.
APIs -- Mono supports a large subset of the .NET Framework APIs, using the same assembly names and factoring.
Platforms -- Mono supports many platforms and CPUs.
Open Source -- Mono and .NET Core both use the MIT license and are .NET Foundation projects.
Focus -- The primary focus of Mono in recent years is mobile platforms, while .NET Core is focused on cloud workloads.

Get started with .NET Core
7/4/2018 • 2 minutes to read • Edit Online

This article provides information on getting started with .NET Core. .NET Core can be installed on Windows, Linux, and macOS. You can code in your
favorite text editor and produce cross-platform libraries and applications.
If you're unsure what .NET Core is, or how it relates to other .NET technologies, start with the What is .NET overview. Put simply, .NET Core is an opensource, cross-platform, implementation of .NET.

Create an application
First, download and install the .NET Core SDK on your computer.
Next, open a terminal such as PowerShell, Command Prompt, or bash. Type the following

dotnet

commands to create and run a C# application.

dotnet new console --output sample1
dotnet run --project sample1

You should see the following output:
Hello World!

Congratulations! You've created a simple .NET Core application. You can also use Visual Studio Code, Visual Studio 2017 (Windows only), or Visual
Studio for Mac (macOS only), to create a .NET Core application.

Tutorials
You can get started developing .NET Core applications by following these step-by-step tutorials.
Windows
Linux
macOS
Build a C# "Hello World" Application with .NET Core in Visual Studio 2017.
Build a C# class library with .NET Core in Visual Studio 2017.
Build a Visual Basic "Hello World" application with .NET Core in Visual Studio 2017.
Build a class library with Visual Basic and .NET Core in Visual Studio 2017.
Watch a video on how to install and use Visual Studio Code and .NET Core.
Watch a video on how to install and use Visual Studio 2017 and .NET Core.
Getting started with .NET Core using the command-line.
See the Prerequisites for Windows development article for a list of the supported Windows versions.

Get Started with C# and Visual Studio Code
7/20/2018 • 3 minutes to read • Edit Online

.NET Core gives you a fast and modular platform for creating applications that run on Windows, Linux, and macOS. Use Visual Studio Code with the C#
extension to get a powerful editing experience with full support for C# IntelliSense (smart code completion) and debugging.

Prerequisites
1. Install Visual Studio Code.
2. Install the .NET Core SDK.
3. Install the C# extension for Visual Studio Code. For more information about how to install extensions on Visual Studio Code, see VS Code Extension
Marketplace.

Hello World
Let's get started with a simple "Hello World" program on .NET Core:
1. Open a project:
Open Visual Studio Code.
Click on the Explorer icon on the left menu and then click Open Folder.
Select File > Open Folder from the main menu to open the folder you want your C# project to be in and click Select Folder. For our
example, we're creating a folder for our project named HelloWorld.

2. Initialize a C# project:
Open the Integrated Terminal from Visual Studio Code by selecting View > Integrated Terminal from the main menu.
In the terminal window, type dotnet new console .
This command creates a Program.cs file in your folder with a simple "Hello World" program already written, along with a C# project file
named HelloWorld.csproj .

3. Resolve the build assets:
For .NET Core 1.x, type
to build your project.

dotnet restore

. Running

dotnet restore

gives you access to the required .NET Core packages that are needed

NOTE
Starting with .NET Core 2.0, you don't have to run dotnet restore because it's run implicitly by all commands that require a restore to occur, such as
dotnet new , dotnet build and dotnet run . It's still a valid command in certain scenarios where doing an explicit restore makes sense, such as
continuous integration builds in Visual Studio Team Services or in build systems that need to explicitly control the time at which the restore occurs.

4. Run the "Hello World" program:
Type

dotnet run

.

You can also watch a short video tutorial for further setup help on Windows, macOS, or Linux.

Debug
1. Open Program.cs by clicking on it. The first time you open a C# file in Visual Studio Code, OmniSharp loads in the editor.

2. Visual Studio Code should prompt you to add the missing assets to build and debug your app. Select Yes.

3. To open the Debug view, click on the Debugging icon on the left side menu.

4. Locate the green arrow at the top of the pane. Make sure the drop-down next to it has

.NET Core Launch (console)

selected.

5. Add a breakpoint to your project by clicking on the editor margin, which is the space on the left of the line numbers in the editor, next to line 9,
or move the text cursor onto line 9 in the editor and press F9.

6. To start debugging, select F5 or the green arrow. The debugger stops execution of your program when it reaches the breakpoint you set in the
previous step.
While debugging, you can view your local variables in the top left pane or use the debug console.

7. Select the green arrow at the top to continue debugging, or select the red square at the top to stop.
TIP
For more information and troubleshooting tips on .NET Core debugging with OmniSharp in Visual Studio Code, see Instructions for setting up the .NET Core debugger.

8. If debugging doesn't work in Visual Studio Code, you might need to change some configurations. Open
configuration sections:
"name": ".NET Core Launch (console)"
"name": ".NET Core Launch (web)"
"name": ".NET Core Attach"

In the first section,

"name": ".NET Core Launch (console)"

, find the

"program"

field. Change its value to

"program": "${workspaceFolder}/app/bin/Debug/netcoreapp2.1/app.dll",

That section of your

.vscode/launch.json

should then look like this after the change:

.vscode/launcher.json

file; you'll see 3

{
"name": ".NET Core Launch (console)",
"type": "coreclr",
"request": "launch",
"preLaunchTask": "build",
"program": "${workspaceFolder}/app/bin/Debug/netcoreapp2.1/app.dll",
"args": [],
"cwd": "${workspaceFolder}",
"console": "internalConsole",
"stopAtEntry": false,
"internalConsoleOptions": "openOnSessionStart"
},

Debugging in Visual Studio Code should work after that change.

See also
Setting up Visual Studio Code
Debugging in Visual Studio Code

Build a C# Hello World application with .NET Core in Visual Studio 2017
5/4/2018 • 3 minutes to read • Edit Online

This topic provides a step-by-step introduction to building, debugging, and publishing a simple .NET Core console application using C# in Visual Studio
2017. Visual Studio 2017 provides a full-featured development environment for building .NET Core applications. As long as the application doesn't
have platform-specific dependencies, the application can run on any platform that .NET Core targets and on any system that has .NET Core installed.

Prerequisites
Visual Studio 2017 with the ".NET Core cross-platform development" workload installed. You can develop your app with either .NET Core 1.1 or .NET
Core 2.0.
For more information, see the Prerequisites for .NET Core on Windows topic.

A simple Hello World application
Begin by creating a simple "Hello World" console application. Follow these steps:
1. Launch Visual Studio 2017. Select File > New > Project from the menu bar. In the New Project* dialog, select the Visual C# node followed by
the .NET Core node. Then select the Console App (.NET Core) project template. In the Name text box, type "HelloWorld". Select the OK
button.

2. Visual Studio uses the template to create your project. The C# Console Application template for .NET Core automatically defines a class, Program
, with a single method, Main , that takes a String array as an argument. Main is the application entry point, the method that's called automatically
by the runtime when it launches the application. Any command-line arguments supplied when the application is launched are available in the
args array.

The template creates a simple "Hello World" application. It calls the Console.WriteLine(String) method to display the literal string "Hello World!"
in the console window. By selecting the HelloWorld button with the green arrow on the toolbar, you can run the program in Debug mode. If you
do, the console window is visible for only a brief time interval before it closes. This occurs because the Main method terminates and the
application ends as soon as the single statement in the Main method executes.
3. To cause the application to pause before it closes the console window, add the following code immediately after the call to the
Console.WriteLine(String) method:
Console.Write("Press any key to continue...");
Console.ReadKey(true);

This code prompts the user to press any key and then pauses the program until a key is pressed.
4. On the menu bar, select Build > Build Solution. This compiles your program into an intermediate language (IL ) that's converted into binary
code by a just-in-time (JIT) compiler.
5. Run the program by selecting the HelloWorld button with the green arrow on the toolbar.

6. Press any key to close the console window.

Enhancing the Hello World application
Enhance your application to prompt the user for their name and display it along with the date and time. To modify and test the program, do the
following:
1. Enter the following C# code in the code window immediately after the opening bracket that follows the
before the first closing bracket:

static void Main(string[] args)

line and

Console.WriteLine("\nWhat is your name? ");
var name = Console.ReadLine();
var date = DateTime.Now;
Console.WriteLine($"\nHello, {name}, on {date:d} at {date:t}!");
Console.Write("\nPress any key to exit...");
Console.ReadKey(true);

This code replaces the existing Console.WriteLine, Console.Write, and Console.ReadKey statements.

This code displays "What is your name?" in the console window and waits until the user enters a string followed by the Enter key. It stores this
string into a variable named name . It also retrieves the value of the DateTime.Now property, which contains the current local time, and assigns it
to a variable named date . Finally, it uses an interpolated string to display these values in the console window.
2. Compile the program by choosing Build > Build Solution.
3. Run the program in Debug mode in Visual Studio by selecting the green arrow on the toolbar, pressing F5, or choosing the Debug > Start
Debugging menu item. Respond to the prompt by entering a name and pressing the Enter key.

4. Press any key to close the console window.
You've created and run your application. To develop a professional application, take some additional steps to make your application ready for release:
For information on debugging your application, see Debugging your C# Hello World application with Visual Studio 2017.
For information on developing and publishing a distributable version of your application, see Publishing your C# Hello World application with
Visual Studio 2017.

Related topics
Instead of a console application, you can also build a class library with .NET Core and Visual Studio 2017. For a step-by-step introduction, see Building
a class library with C# and .NET Core in Visual Studio 2017.
You can also develop a .NET Core console app on Mac, Linux, and Windows by using Visual Studio Code, a downloadable code editor. For a step-bystep tutorial, see Getting Started with Visual Studio Code.

Build a Visual Basic Hello World application with .NET Core in Visual
Studio 2017
5/4/2018 • 3 minutes to read • Edit Online

This topic provides a step-by-step introduction to building, debugging, and publishing a simple .NET Core console application using Visual Basic in
Visual Studio 2017. Visual Studio 2017 provides a full-featured development environment for building .NET Core applications. As long as the
application doesn't have platform-specific dependencies, the application can run on any platform that .NET Core targets and on any system that has
.NET Core installed.

Prerequisites
Visual Studio 2017 with the ".NET Core cross-platform development" workload installed. You can develop your app with .NET Core 2.0.
For more information, see Prerequisites for .NET Core on Windows.

A simple Hello World application
Begin by creating a simple "Hello World" console application. Follow these steps:
1. Launch Visual Studio 2017. Select File > New > Project from the menu bar. In the New Project* dialog, select the Visual Basic node followed
by the .NET Core node. Then select the Console App (.NET Core) project template. In the Name text box, type "HelloWorld". Select the OK
button.

2. Visual Studio uses the template to create your project. The Visual Basic Console Application template for .NET Core automatically defines a class,
Program , with a single method, Main , that takes a String array as an argument. Main is the application entry point, the method that's called
automatically by the runtime when it launches the application. Any command-line arguments supplied when the application is launched are
available in the args array.

The template creates a simple "Hello World" application. It calls the Console.WriteLine(String) method to display the literal string "Hello World!"
in the console window. By selecting the HelloWorld button with the green arrow on the toolbar, you can run the program in Debug mode. If you
do, the console window is visible for only a brief time interval before it closes. This occurs because the Main method terminates and the
application ends as soon as the single statement in the Main method executes.
3. To cause the application to pause before it closes the console window, add the following code immediately after the call to the
Console.WriteLine(String) method:
Console.Write("Press any key to continue...")
Console.ReadKey(true)

This code prompts the user to press any key and then pauses the program until a key is pressed.
4. On the menu bar, select Build > Build Solution. This compiles your program into an intermediate language (IL ) that's converted into binary
code by a just-in-time (JIT) compiler.
5. Run the program by selecting the HelloWorld button with the green arrow on the toolbar.

6. Press any key to close the console window.

Enhancing the Hello World application
Enhance your application to prompt the user for his or her name and to display it along with the date and time. To modify and test the program, do the
following:
1. Enter the following Visual Basic code in the code window immediately after the opening bracket that follows the
and before the first closing bracket:
Console.WriteLine(vbCrLf + "What is your name? ")
Dim name = Console.ReadLine()
Dim currentDate = DateTime.Now
Console.WriteLine($"{vbCrLf}Hello, {name}, on {currentDate:d} at {currentDate:t}")
Console.Write(vbCrLf + "Press any key to exit... ")
Console.ReadKey(True)

Sub Main(args As String())

line

This code replaces the existing Console.WriteLine, Console.Write, and Console.ReadKey statements.

This code displays "What is your name?" in the console window and waits until the user enters a string followed by the Enter key. It stores this
string into a variable named name . It also retrieves the value of the DateTime.Now property, which contains the current local time, and assigns it
to a variable named currentDate . Finally, it uses an interpolated string to display these values in the console window.
2. Compile the program by choosing Build > Build Solution.
3. Run the program in Debug mode in Visual Studio by selecting the green arrow on the toolbar, pressing F5, or choosing the Debug > Start
Debugging menu item. Respond to the prompt by entering a name and pressing the Enter key.

4. Press any key to close the console window.
You've created and run your application. To develop a professional application, take some additional steps to make your application ready for release:
For information on debugging your application, see Debugging your C# Hello World application with Visual Studio 2017.
For information on developing and publishing a distributable version of your application, see Publishing your C# Hello World application with
Visual Studio 2017.

Building a class library with C# and .NET Core in Visual Studio 2017
5/4/2018 • 2 minutes to read • Edit Online

A class library defines types and methods that are called by an application. A class library that targets the .NET Standard 2.0 allows your library to be
called by any .NET implementation that supports that version of the .NET Standard. When you finish your class library, you can decide whether you
want to distribute it as a third-party component or whether you want to include it as a bundled component with one or more applications.
NOTE
For a list of the .NET Standard versions and the platforms they support, see .NET Standard.

In this topic, you'll create a simple utility library that contains a single string-handling method. You'll implement it as an extension method so that you
can call it as if it were a member of the String class.

Creating a class library solution
Start by creating a solution for your class library project and its related projects. A Visual Studio Solution just serves as a container for one or more
projects. To create the solution:
1. On the Visual Studio menu bar, choose File > New > Project.
2. In the New Project dialog, expand the Other Project Types node, and select Visual Studio Solutions. Name the solution
"ClassLibraryProjects" and select the OK button.

Creating the class library project
Create your class library project:
1. In Solution Explorer, right-click on the ClassLibraryProjects solution file and from the context menu, select Add > New Project.
2. In the Add New Project dialog, expand the Visual C# node, then select the .NET Standard node followed by the Class Library (.NET
Standard) project template. In the Name text box, enter "StringLibrary" as the name of the project. Select OK to create the class library project.

The code window then opens in the Visual Studio development environment.

3. Check to make sure that our library targets the correct version of the .NET Standard. Right-click on the library project in the Solution Explorer
windows, then select Properties. The Target Framework text box shows that we're targeting .NET Standard 2.0.

4. Replace the code in the code window with the following code and save the file:
using System;
namespace UtilityLibraries
{
public static class StringLibrary
{
public static bool StartsWithUpper(this String str)
{
if (String.IsNullOrWhiteSpace(str))
return false;
Char ch = str[0];
return Char.IsUpper(ch);
}
}
}

The class library, UtilityLibraries.StringLibrary , contains a method named StartsWithUpper , which returns a Boolean value that indicates
whether the current string instance begins with an uppercase character. The Unicode standard distinguishes uppercase characters from lowercase
characters. The Char.IsUpper(Char) method returns true if a character is uppercase.
5. On the menu bar, select Build > Build Solution. The project should compile without error.

Next step
You've successfully built the library. Because you haven't called any of its methods, you don't know whether it works as expected. The next step in
developing your library is to test it by using a Unit Test Project.

Building a class library with Visual Basic and .NET Core in Visual Studio
2017
5/4/2018 • 2 minutes to read • Edit Online

A class library defines types and methods that are called by an application. A class library that targets the .NET Standard 2.0 allows your library to be
called by any .NET implementation that supports that version of the .NET Standard. When you finish your class library, you can decide whether you
want to distribute it as a third-party component or whether you want to include it as a bundled component with one or more applications.
NOTE
For a list of the .NET Standard versions and the platforms they support, see .NET Standard.

In this topic, you'll create a simple utility library that contains a single string-handling method. You'll implement it as an extension method so that you
can call it as if it were a member of the String class.

Creating a class library solution
Start by creating a solution for your class library project and its related projects. A Visual Studio Solution just serves as a container for one or more
projects. To create the solution:
1. On the Visual Studio menu bar, choose File > New > Project.
2. In the New Project dialog, expand the Other Project Types node, and select Visual Studio Solutions. Name the solution
"ClassLibraryProjects" and select the OK button.

Creating the class library project
Create your class library project:
1. In Solution Explorer, right-click on the ClassLibraryProjects solution file and from the context menu, select Add > New Project.
2. In the Add New Project dialog, expand the Visual Basic node, then select the .NET Standard node followed by the Class Library (.NET
Standard) project template. In the Name text box, enter "StringLibrary" as the name of the project. Select OK to create the class library project.

The code window then opens in the Visual Studio development environment.

3. Check to make sure that the library targets the correct version of the .NET Standard. Right-click on the library project in the Solution Explorer
windows, then select Properties. The Target Framework text box shows that we're targeting .NET Standard 2.0.

4. Also in the Properties dialog, clear the text in the Root namespace text box. For each project, Visual Basic automatically creates a namespace
that corresponds to the project name, and any namespaces defined in source code files are parents of that namespace. We want to define a toplevel namespace by using the namespace keyword.
5. Replace the code in the code window with the following code and save the file:
Imports System.Runtime.CompilerServices
Namespace UtilityLibraries
Public Module StringLibrary

Public Function StartsWithUpper(str As String) As Boolean
If String.IsNullOrWhiteSpace(str) Then
Return False
End If
Dim ch As Char = str(0)
Return Char.IsUpper(ch)
End Function
End Module
End Namespace

The class library, UtilityLibraries.StringLibrary , contains a method named StartsWithUpper , which returns a Boolean value that indicates whether the
current string instance begins with an uppercase character. The Unicode standard distinguishes uppercase characters from lowercase characters. The
Char.IsUpper(Char) method returns true if a character is uppercase.
1. On the menu bar, select Build > Build Solution. The project should compile without error.

Next step
You've successfully built the library. Because you haven't called any of its methods, you don't know whether it works as expected. The next step in
developing your library is to test it by using a Unit Test Project.

Prerequisites for .NET Core on Windows
5/19/2018 • 3 minutes to read • Edit Online

This article shows the dependencies needed to develop .NET Core applications on Windows. The supported OS versions and dependencies that follow
apply to the three ways of developing .NET Core apps on Windows:
Command line
Visual Studio 2017
Visual Studio Code

.NET Core supported Windows versions
.NET Core is supported on the following versions of:
Windows 7 SP1
Windows 8.1
Windows 10 Anniversary Update (version 1607) or later versions
Windows Server 2008 R2 SP1 (Full Server or Server Core)
Windows Server 2012 SP1 (Full Server or Server Core)
Windows Server 2012 R2 (Full Server or Server Core)
Windows Server 2016 or later versions (Full Server, Server Core, or Nano Server)
The following articles have a complete list of .NET Core supported operating systems per version:
.NET Core 2.1 - Supported OS Versions
.NET Core 2.0 - Supported OS Versions
.NET Core 1.x - Supported OS Versions

.NET Core dependencies
.NET Core 1.1 and earlier versions require the Visual C++ Redistributable when running on Windows versions earlier than Windows 10 and Windows
Server 2016. This dependency is automatically installed by the .NET Core installer.
Microsoft Visual C++ 2015 Redistributable Update 3 must be manually installed when:
Installing .NET Core with the installer script.
Deploying a self-contained .NET Core application.
Building the product from source.
Installing .NET Core via a .zip file. This can include build/CI/CD servers.
NOTE
For Windows 8.1 and earlier versions, or Windows Server 2012 R2 and earlier versions:
Make sure that your Windows installation is up-to-date and includes KB2999226, which can be installed through Windows Update. If you don't have this update
installed, you'll see an error like the following when you launch a .NET Core application:
The program can't start because api-ms-win-crt-runtime-1-1-0.dll is missing from your computer. Try reinstalling the program to fix this
problem.

For Windows 7 or Windows Server 2008 R2:
In addition to KB2999226, make sure you also have KB2533623 installed. If you don't have this update installed, you'll see an error similar to the following when you
launch a .NET Core application: The library hostfxr.dll was found, but loading it from C:\\hostfxr.dll failed .

Prerequisites with Visual Studio 2017
You can use any editor to develop .NET Core applications using the .NET Core SDK. Visual Studio 2017 provides an integrated development
environment for .NET Core apps on Windows.
You can read more about the changes in Visual Studio 2017 in the release notes.
.NET Core 2.x
.NET Core 1.x
To develop .NET Core 2.x apps in Visual Studio 2017:
1. Download and install Visual Studio 2017 version 15.3.0 or higher with the .NET Core cross-platform development workload (in the Other
Toolsets section) selected.

After the .NET Core cross-platform development toolset is installed, Visual Studio 2017 uses .NET Core 1.x by default. Install the .NET Core 2.x SDK
to get .NET Core 2.x support in Visual Studio 2017.
2. Install the .NET Core 2.x SDK.
3. Retarget existing or new .NET Core 1.x projects to .NET Core 2.x using the following instructions:
On the Project menu, Choose Properties.
In the Target framework selection menu, set the value to .NET Core 2.0.

Once the .NET Core 2.x SDK is installed, Visual Studio 2017 uses the .NET Core SDK 2.x by default, and supports the following actions:
Open, build, and run existing .NET Core 1.x projects.
Retarget .NET Core 1.x projects to .NET Core 2.x, build, and run.
Create new .NET Core 2.x projects.

TIP
To verify your Visual Studio 2017 version:
On the Help menu, choose About Microsoft Visual Studio.
In the About Microsoft Visual Studio dialog, verify the version number.
For .NET Core 2.1 RC apps, Visual Studio 2017 version 15.7 or higher.
For .NET Core 2.0 apps, Visual Studio 2017 version 15.3 or higher.
For .NET Core 1.x apps, Visual Studio 2017 version 15.0 or higher.

Prerequisites for .NET Core on macOS
6/22/2018 • 2 minutes to read • Edit Online

This article shows you the supported macOS versions and .NET Core dependencies that you need to develop, deploy, and run .NET Core applications
on macOS machines. The supported OS versions and dependencies that follow apply to the three ways of developing .NET Core apps on a Mac: via the
command-line with your favorite editor, Visual Studio Code, and Visual Studio for Mac.

Supported macOS versions
.NET Core 2.x
.NET Core 1.x
.NET Core 2.x is supported on the following versions of macOS:
macOS 10.12 "Sierra" and later versions
See .NET Core 2.x Supported OS Versions for the complete list of .NET Core 2.x supported operating systems, out of support OS versions, and lifecycle
policy links.

.NET Core dependencies
.NET Core 2.x
.NET Core 1.x
Download and install the .NET Core SDK from .NET Downloads. If you have problems with the installation on macOS, consult the Known issues topic
for the version you have installed.

Increase the maximum open file limit (.NET Core versions before .NET Core SDK 2.0.2)
In older .NET Core versions (before .NET Core SDK 2.0.2), the default open file limit on macOS may not be sufficient for some .NET Core workloads,
such as restoring projects or running unit tests.
You can increase this limit by following these steps:
1. Using a text editor, create a new file /Library/LaunchDaemons/limit.maxfiles.plist, and save the file with this content:




Label
limit.maxfiles
ProgramArguments

launchctl
limit
maxfiles
2048
4096

RunAtLoad

ServiceIPC




2. In a terminal window, run the following command:
echo 'ulimit -n 2048' | sudo tee -a /etc/profile

3. Reboot your Mac to apply these settings.

Visual Studio for Mac
You can use any editor to develop .NET Core applications using the .NET Core SDK. However, if you want to develop .NET Core applications on a Mac
in an integrated development environment, you can use Visual Studio for Mac.
.NET Core development on macOS with Visual Studio for Mac requires:
A supported version of the macOS operating system

OpenSSL (.NET Core 1.x only; .NET Core 2.x uses security services available natively in macOS )
.NET Core SDK for Mac
Visual Studio for Mac

Prerequisites for .NET Core on Linux
7/18/2018 • 11 minutes to read • Edit Online

This article shows the dependencies needed to develop .NET Core applications on Linux. The supported Linux distributions/versions, and dependencies
that follow apply to the two ways of developing .NET Core apps on Linux:
Command-line with your favorite editor
Visual Studio Code
NOTE
The .NET Core SDK package is not required for production servers/environments. Only the .NET Core runtime package is needed for apps deployed to production
environments. The .NET Core runtime is deployed with apps as part of a self-contained deployment, however, it must be deployed for Framework-dependent deployed
apps separately. For more information about framework-dependent and self-contained deployment types, see .NET Core application deployment. Also see Selfcontained Linux applications for specific guidelines.

Supported Linux versions
.NET Core 2.x
.NET Core 1.x
.NET Core 2.x treats Linux as a single operating system. There is a single Linux build (per chip architecture) for supported Linux distributions.
NET Core 2.1
NET Core 2.1 is supported on the following Linux 64-bit ( x86_64 or

amd64

) distributions/versions:

Red Hat Enterprise Linux 7, 6
CentOS 7
Oracle Linux 7
Fedora 28, 27
Debian 9, 8.7 or later versions
Ubuntu 18.04, 17.10, 16.04, 14.04
Linux Mint 18, 17
openSUSE 42.3 or later versions
SUSE Enterprise Linux (SLES ) 12 Service Pack 2 or later
Alpine Linux 3.7 or later versions
See .NET Core 2.1 Supported OS Versions for the complete list of .NET Core 2.1 supported operating systems, distributions and versions, out of
support OS versions, and lifecycle policy links.
NET Core 2.0
NET Core 2.0 is supported on the following Linux 64-bit ( x86_64 or

amd64

) distributions/versions:

Red Hat Enterprise Linux 7
CentOS 7
Oracle Linux 7
Fedora 27
Debian 9, 8.7 or later versions
Ubuntu 18.04, 17.10, 16.04, 14.04
Linux Mint 18, 17
openSUSE 42.3 or later versions
SUSE Enterprise Linux (SLES ) 12 Service Pack 2 or later
See .NET Core 2.0 Supported OS Versions for the complete list of .NET Core 2.0 supported operating systems, distributions and versions, out of
support OS versions, and lifecycle policy links.

Linux distribution dependencies
The following are intended to be examples. The exact versions and names may vary slightly on your Linux distribution of choice.
Ubuntu
Ubuntu distributions require the following libraries installed:
liblttng-ust0
libcurl3

libssl1.0.0
libkrb5-3
zlib1g
libicu52 (for 14.x)
libicu55 (for 16.x)
libicu57 (for 17.x)
libicu60 (for 18.x)
For versions earlier than .NET Core 2.1, following dependencies are also required:
libunwind8
libuuid1
CentOS
CentOS distributions require the following libraries installed:
lttng-ust
libcurl
openssl-libs
krb5-libs
libicu
zlib
For versions earlier than .NET Core 2.1, following dependencies are also required:
libunwind
libuuid
For more information about the dependencies, see Self-contained Linux applications.

Installing .NET Core dependencies with the native installers
.NET Core native installers are available for supported Linux distributions/versions. The native installers require admin (sudo) access to the server. The
advantage of using a native installer is that all of the .NET Core native dependencies are installed. Native installers also install the .NET Core SDK
system-wide.
On Linux, there are two installer package choices:
Using a feed-based package manager, such as apt-get for Ubuntu, or yum for CentOS/RHEL.
Using the packages themselves, DEB or RPM.
Scripting Installs with the .NET Core installer script
The dotnet-install scripts are used to perform a non-admin install of the CLI toolchain and the shared runtime. You can download the script from
https://dot.net/v1/dotnet-install.sh.
The installer bash script is used in automation scenarios and non-admin installations. This script also reads PowerShell switches, so they can be used
with the script on Linux/OS X systems.

Install .NET Core for supported Red Hat Enterprise Linux (RHEL) versions
To install .NET Core on supported RHEL versions:
.NET Core 2.x
.NET Core 1.x
.NET Core 2.0
Install .NET Core 2.0 on supported RHEL versions:
.NET Core Runtime 2.0.8 install link
.NET Core Runtime 2.0.7 install link
.NET Core Runtime 2.0.6 install link
.NET Core Runtime 2.0.5 install link
.NET Core SDK 2.1.200 install link
.NET Core SDK 2.1.105 install link
.NET Core SDK 2.1.103 install link
.NET Core SDK 2.0.3 install link
.NET Core SDK 2.0.0 install link

Install .NET Core for supported Ubuntu and Linux Mint distributions/versions (64 bit)
.NET Core 2.x

.NET Core 1.x
1. Remove any previous preview versions of .NET Core from your system.
2. Install .NET Core 2.x on supported Ubuntu and Linux Mint distributions/versions (64 bit):
.NET Core 2.0
RUNTIMES / SDKS

UBUNTU 18.04

UBUNTU 17.10

UBUNTU 16.04 / LINUX MINT 18

UBUNTU 14.04 / LINUX MINT 17

.NET Core Runtime 2.0.8

Install link

Install link

Install link

Install link

.NET Core Runtime 2.0.7

Install link

Install link

Install link

Install link

.NET Core Runtime 2.0.6

Install link

Install link

Install link

Install link

.NET Core Runtime 2.0.5

Install link

Install link

Install link

Install link

.NET Core SDK 2.1.200

Install link

Install link

Install link

Install link

.NET Core SDK 2.1.105

Install link

Install link

Install link

Install link

.NET Core SDK 2.1.103

Install link

Install link

Install link

Install link

.NET Core SDK 2.0.3

Install link

Install link

Install link

Install link

.NET Core SDK 2.0.0

Install link

Install link

Install link

Install link

.NET Core 2.1
IMPORTANT
To use .NET Core 2.1 with Visual Studio, you need to install Visual Studio 2017 15.7 or newer.

RUNTIMES / SDKS

UBUNTU 18.04

UBUNTU 17.10

UBUNTU 16.04 / LINUX MINT 18

UBUNTU 14.04 / LINUX MINT 17

.NET Core Runtime 2.1.0

Install link

Install link

Install link

Install link

.NET Core SDK 2.1.300

Install link

Install link

Install link

Install link

Install .NET Core for supported Debian versions (64 bit)
To install .NET Core on supported Debian versions (64 bit):
NOTE
A user-controlled directory is required for Linux system installs from tar.gz.

.NET Core 2.x
.NET Core 1.x
1. Remove any previous preview versions of .NET Core from your system.
2. Install .NET Core 2.x on supported Debian versions (64 bit):
.NET Core 2.0
RUNTIMES / SDKS

DEBIAN 9

DEBIAN 8

.NET Core Runtime 2.0.8

Install link

Install link

.NET Core Runtime 2.0.7

Install link

Install link

.NET Core Runtime 2.0.6

Install link

Install link

.NET Core Runtime 2.0.5

Install link

Install link

.NET Core SDK 2.1.200

Install link

Install link

.NET Core SDK 2.1.105

Install link

Install link

RUNTIMES / SDKS

DEBIAN 9

DEBIAN 8

.NET Core SDK 2.1.103

Install link

Install link

.NET Core SDK 2.0.3

Install link

Install link

.NET Core SDK 2.0.0

Install link

Install link

.NET Core 2.1
IMPORTANT
To use .NET Core 2.1 with Visual Studio, you need to install Visual Studio 2017 15.7 or newer.

RUNTIMES / SDKS

DEBIAN 9

DEBIAN 8

.NET Core Runtime 2.1.0

Install link

Install link

.NET Core SDK 2.1.300

Install link

Install link

Install .NET Core for supported Fedora versions (64 bit)
To install .NET Core on supported Fedora versions:
NOTE
A user-controlled directory is required for Linux system installs from tar.gz.

.NET Core 2.x
.NET Core 1.x
1. Remove any previous preview versions of .NET Core from your system.
2. Install .NET Core 2.x on supported Fedora versions (64 bit):
.NET Core 2.0
RUNTIMES / SDKS

FEDORA 26 OR LATER

FEDORA 25 OR PREVIOUS

.NET Core Runtime 2.0.8

Install link

Install link

.NET Core Runtime 2.0.7

Install link

Install link

.NET Core Runtime 2.0.6

Install link

Install link

.NET Core Runtime 2.0.5

Install link

Install link

.NET Core SDK 2.1.200

Install link

Install link

.NET Core SDK 2.1.105

Install link

Install link

.NET Core SDK 2.1.103

Install link

Install link

.NET Core SDK 2.0.3

Install link

Install link

.NET Core 2.1
IMPORTANT
To use .NET Core 2.1 with Visual Studio, you need to install Visual Studio 2017 15.7 or newer.

RUNTIMES / SDKS

FEDORA 27

FEDORA 26

.NET Core Runtime 2.1.0

Install link

Install link

.NET Core SDK 2.1.300

Install link

Install link

Install .NET Core for supported CentOS and Oracle Linux distributions/versions (64 bit)
To install .NET Core for supported CentOS and Oracle Linux distributions/versions (64 bit):
NOTE
A user-controlled directory is required for Linux system installs from tar.gz.

.NET Core 2.x
.NET Core 1.x
1. Remove any previous preview versions of .NET Core from your system.
2. Install .NET Core 2.x on supported CentOS and Oracle Linux distributions/versions (64 bit):
.NET Core 2.0
.NET Core Runtime 2.0.8 install link
.NET Core Runtime 2.0.7 install link
.NET Core Runtime 2.0.6 install link
.NET Core Runtime 2.0.5 install link
.NET Core SDK 2.1.200 install link
.NET Core SDK 2.1.105 install link
.NET Core SDK 2.1.103 install link
.NET Core SDK 2.0.3 install link
.NET Core SDK 2.0.0 install link
.NET Core 2.1
IMPORTANT
To use .NET Core 2.1 with Visual Studio, you need to install Visual Studio 2017 15.7 or newer.

.NET Core Runtime 2.1.0 install link
.NET Core SDK 2.1.300 install link

Install .NET Core for supported SUSE Linux Enterprise Server and OpenSUSE
distributions/versions (64 bit)
To install .NET Core 2.x for supported SUSE Linux Enterprise Server and OpenSUSE distributions/versions (64 bit):
.NET Core 2.x
.NET Core 1.x
1. Remove any previous preview versions of .NET Core from your system.
2. Install .NET Core 2.x on supported SUSE Linux Enterprise Server and OpenSUSE distributions/versions (64 bit):
.NET Core 2.0
SUSE Linux Enterprise Server
.NET Core Runtime 2.0.8 install link
.NET Core Runtime 2.0.7 install link
.NET Core Runtime 2.0.6 install link
.NET Core Runtime 2.0.5 install link
.NET Core SDK 2.1.200 install link
.NET Core SDK 2.1.105 install link
.NET Core SDK 2.1.103 install link
.NET Core SDK 2.0.3 install link
.NET Core SDK 2.0.0 install link
openSUSE
.NET Core Runtime 2.0.8 install link
.NET Core Runtime 2.0.7 install link
.NET Core Runtime 2.0.6 install link
.NET Core Runtime 2.0.5 install link
.NET Core SDK 2.1.105 install link
.NET Core SDK 2.1.103 install link

.NET Core SDK 2.0.3 install link
.NET Core SDK 2.0.0 install link
.NET Core 2.1
IMPORTANT
To use .NET Core 2.1 with Visual Studio, you need to install Visual Studio 2017 15.7 or newer.

SUSE Linux Enterprise Server
.NET Core Runtime 2.1.0 install link
.NET Core SDK 2.1.300 install link
openSUSE
.NET Core Runtime 2.1.0 install link
.NET Core SDK 2.1.300 install link

Install .NET Core for supported Alpine Linux versions (64 bit)
NOTE
A user-controlled directory is required for Linux system installs from tar.gz.

Download and follow the .NET Core 2.1 installation instructions for supported Alpine Linux versions (64 bit) at the following links:
.NET Core Runtime 2.1.0 download link
.NET Core SDK 2.1.300 download link
IMPORTANT
If you have problems with a .NET Core installation on a supported Linux distribution/version, consult the following topics for your installed distributions/versions:
.NET Core 2.1 known issues
.NET Core 2.0 known issues
.NET Core 1.1 known issues
.NET Core 1.0 known issues

What's new in .NET Core
5/30/2018 • 2 minutes to read • Edit Online

This page provides a summary of new features in each release of .NET Core starting with .NET Core 2.0. The following links provide detailed
information on the major features added in each release.
.NET Core 2.1
.NET Core 2.0

See also
What's new in ASP.NET Core 2.0

What's new in .NET Core 2.1
7/6/2018 • 8 minutes to read • Edit Online

.NET Core 2.1 includes enhancements and new features in the following areas:
Tooling
Roll forward
Deployment
Windows Compatibility Pack
JIT compilation improvements
API changes

Tooling
The .NET Core 2.1 SDK (v 2.1.300), the tooling included with .NET Core 2.1, includes the following changes and enhancements:
Build performance improvements
A major focus of .NET Core 2.1 is improving build-time performance, particularly for incremental builds. These performance improvements apply to
both command-line builds using dotnet build and to builds in Visual Studio. Some individual areas of improvement include:
For package asset resolution, resolving only assets used by a build rather than all assets.
Caching of assembly references.
Use of long-running SDK build servers, which are processes that span across individual dotnet build invocations. They eliminate the need to
JIT-compile large blocks of code every time dotnet build is run. Build server processes can be automatically terminated with the following
command:
dotnet buildserver shutdown

New CLI commands
A number of tools that were available only on a per project basis using
tools include:

DotnetCliToolReference

are now available as part of the .NET Core SDK. These

dotnet watch provides a file system watcher that waits for a file to change before executing a designated set of commands. For example, the
following command automatically rebuilds the current project and generates verbose output whenever a file in it changes:

dotnet watch -- --verbose build

Note the -- option that precedes the
arguments that are passed to the child
dotnet build command.

option. It delimits the options passed directly to the dotnet watch command from the
process. Without it, the --verbose option applies to the dotnet watch command, not the

--verbose
dotnet

For more information, see Develop ASP.NET Core apps using dotnet watch
dotnet dev-certs

generates and manages certificates used during development in ASP.NET Core applications.

dotnet user-secrets
dotnet sql-cache

manages the secrets in a user secret store in ASP.NET Core applications.

creates a table and indexes in a Microsoft SQL Server database to be used for distributed caching.

dotnet ef is a tool for managing databases, DbContext objects, and migrations in Entity Framework Core applications. For more information,
see EF Core .NET Command-line Tools.

Global Tools
.NET Core 2.1 supports Global Tools -- that is, custom tools that are available globally from the command line. The extensibility model in previous
versions of .NET Core made custom tools available on a per project basis only by using DotnetCliToolReference .
To install a Global Tool, you use the dotnet tool install command. For example:
dotnet tool install -g dotnetsay

Once installed, the tool can be run from the command line by specifying the tool name. For more information, see .NET Core Global Tools overview.
Tool management with the

dotnet tool

command

In .NET Core SDK 2.1 (v 2.1.300), all tools operations use the
dotnet tool install

to install a tool.

dotnet tool

command. The following options are available:

dotnet tool update
dotnet tool list

to uninstall and reinstall a tool, which effectively updates it.

to list currently installed tools.

dotnet tool uninstall

to uninstall currently installed tools.

Roll forward
All .NET Core applications starting with the .NET Core 2.0 automatically roll forward to the latest minor version installed on a system.
Starting with .NET Core 2.0, if the version of .NET Core that an application was built with is not present at runtime, the application automatically runs
against the latest installed minor version of .NET Core. In other words, if an application is built with .NET Core 2.0, and .NET Core 2.0 is not present on
the host system but .NET Core 2.1 is, the application runs with .NET Core 2.1.
IMPORTANT
This roll-forward behavior doesn't apply to preview releases. Nor does it apply to major releases. For example, a .NET Core 1.0 application wouldn't roll forward to .NET
Core 2.0 or .NET Core 2.1.

You can also disable minor version roll forward in any of three ways:
Set the

DOTNET_ROLL_FORWARD_ON_NO_CANDIDATE_FX

environment variable to 0.

Add the following line to the runtimeconfig.json file:
"rollForwardOnNoCandidateFx" : 0

When using .NET Core CLI tools, include the following option with a .NET Core command such as

run

:

dotnet run --rollForwardOnNoCandidateFx=0

Deployment
Self-contained application servicing
dotnet publish now publishes self-contained applications with a serviced runtime version. When you publish a self-contained application with the .NET
Core 2.1 SDK (v 2.1.300), your application includes the latest serviced runtime version known by that SDK. When you upgrade to the latest SDK, you’ll
publish with the latest .NET Core runtime version. This applies for .NET Core 1.0 runtimes and later.
Self-contained publishing relies on runtime versions on NuGet.org. You do not need to have the serviced runtime on your machine.
Using the .NET Core 2.0 SDK, self-contained applications are published with the .NET Core 2.0.0 runtime unless a different version is specified via the
RuntimeFrameworkVersion property. With this new behavior, you’ll no longer need to set this property to select a higher runtime version for a selfcontained application. The easiest approach going forward is to always publish with .NET Core 2.1 SDK (v 2.1.300).

Windows Compatibility Pack
When you port existing code from the .NET Framework to .NET Core, you can use the Windows Compatibility Pack. It provides access to 20,000 more
APIs than are available in .NET Core. These APIs include types in the System.Drawing namespace, the EventLog class, WMI, Performance Counters,
Windows Services, and the Windows registry types and members.

JIT compiler improvements
.NET Core incorporates a new JIT compiler technology called tiered compilation (also known as adaptive optimization) that can significantly improve
performance. Tiered compilation is an opt-in setting.
One of the important tasks performed by the JIT compiler is optimizing code execution. For little-used code paths, however, the compiler may spend
more time optimizing code than the runtime spends running unoptimized code. Tiered compilation introduces two stages in JIT compilation:
A first tier, which generates code as quickly as possible.
A second tier, which generates optimized code for those methods that are executed frequently. The second tier of compilation is performed in
parallel for enhanced performance.
You can opt into tiered compilation in either of two ways.
To use tiered compilation in all projects that use the .NET Core 2.1 SDK, set the following environment variable:
COMPlus_TieredCompilation="1"

To use tiered compilation on a per-project basis, add the
file, as the following example shows:



property to the



section of the MSBuild project



true


API changes
Span

and

Memory

.NET Core 2.1 includes some new types that make working with arrays and other types of memory much more efficient. The new types include:
System.Span and System.ReadOnlySpan.
System.Memory and System.ReadOnlyMemory.
Without these types, when passing such items as a portion of an array or a section of a memory buffer, you have to make a copy of some portion of the
data before passing it to a method. These types provide a virtual view of that data that eliminates the need for the additional memory allocation and
copy operations.
The following example uses a Span instance to provide a virtual view of 10 elements of an array.
using System;
class Program
{
static void Main()
{
int[] numbers = new int[100];
for (int i = 0; i < 100; i++)
{
numbers[i] = i * 2;
}
var part = new Span(numbers, start: 10, length: 10);
foreach (var value in part)
Console.Write($"{value} ");
}
}
// The example displays the following output:
//
20 22 24 26 28 30 32 34 36 38

Brotli compression
.NET Core 2.1 adds support for Brotli compression and decompression. Brotli is a general-purpose lossless compression algorithm that is defined in
RFC 7932 and is supported by most web browsers and major web servers. You can use the stream-based System.IO.Compression.BrotliStream class or
the high-performance span-based System.IO.Compression.BrotliEncoder and System.IO.Compression.BrotliDecoder classes. The following example
illustrates compression with the BrotliStream class:
public static Stream DecompressWithBrotli(Stream toDecompress)
{
MemoryStream decompressedStream = new MemoryStream();
using (BrotliStream decompressionStream = new BrotliStream(toDecompress, CompressionMode.Decompress))
{
decompressionStream.CopyTo(decompressedStream);
}
decompressedStream.Position = 0;
return decompressedStream;
}

The BrotliStream behavior is the same as DeflateStream and GZipStream, which makes it easy to convert code that calls these APIs to BrotliStream.
New cryptography APIs and cryptography improvements
.NET Core 2.1 includes numerous enhancements to the cryptography APIs:
System.Security.Cryptography.Pkcs.SignedCms is available in the System.Security.Cryptography.Pkcs package. The implementation is the same
as the SignedCms class in the .NET Framework.
New overloads of the X509Certificate.GetCertHash and X509Certificate.GetCertHashString methods accept a hash algorithm identifier to
enable callers to get certificate thumbprint values using algorithms other than SHA-1.
New Span-based cryptography APIs are available for hashing, HMAC, cryptographic random number generation, asymmetric signature
generation, asymmetric signature processing, and RSA encryption.
The performance of System.Security.Cryptography.Rfc2898DeriveBytes has improved by about 15% by using a Span-based
implementation.
The new System.Security.Cryptography.CryptographicOperations class includes two new methods:

FixedTimeEquals takes a fixed amount of time to return for any two inputs of the same length, which makes it suitable for use in
cryptographic verification to avoid contributing to timing side-channel information.
ZeroMemory is a memory-clearing routine that cannot be optimized.
The static System.Security.Cryptography.RandomNumberGenerator.Fill method fills a Span with random values.
The System.Security.Cryptography.Pkcs.EnvelopedCms is now supported on Linux and maxOS.
Elliptic-Curve Diffie-Hellman (ECDH) is now available in the System.Security.Cryptography.ECDiffieHellman class family. The surface area is the
same as in the .NET Framework.
The instance returned by RSA.Create can encrypt or decrypt with OAEP using a SHA-2 digest, as well as generate or validate signatures using
RSA-PSS.
Sockets improvements
.NET Core includes a new type, System.Net.Http.SocketsHttpHandler, and a rewritten System.Net.Http.HttpMessageHandler, that form the basis of
higher-level networking APIs. System.Net.Http.SocketsHttpHandler, for example, is the basis of the HttpClient implementation. In previous versions of
.NET Core, higher-level APIs were based on native networking implementations.
The sockets implementation introduced in .NET Core 2.1 has a number of advantages:
A significant performance improvement when compared with the previous implementation.
Elimination of platform dependencies, which simplifies deployment and servicing.
Consistent behavior across all .NET Core platforms.
SocketsHttpHandler is the default implementation in .NET Core 2.1. However, you can configure your application to use the older HttpClientHandler
class by calling the SetSwitch method:
AppContext.SetSwitch("System.Net.Http.UseSocketsHttpHandler", false);

AppContext.SetSwitch("System.Net.Http.UseSocketsHttpHandler", False)

You can also use an environment variable to opt out of using sockets implementations based on SocketsHttpHandler. To do this, set the
DOTNET_SYSTEM_NET_HTTP_USESOCKETSHTTPHANDLER to either false or 0.
On Windows, you can also choose to use System.Net.Http.WinHttpHandler, which relies on a native implementation, or the SocketsHttpHandler class
by passing an instance of the class to the HttpClient constructor.
On Linux and macOS, you can only configure HttpClient on a per-process basis. On Linux, you need to deploy libcurl if you want to use the old
HttpClient implementation. (It is installed with .NET Core 2.0.)

See also
What's new in .NET Core
New features in EF Core 2.1
What's new in ASP.NET Core 2.1

What's new in .NET Core 2.0
5/30/2018 • 6 minutes to read • Edit Online

.NET Core 2.0 includes enhancements and new features in the following areas:
Tooling
Language support
Platform improvements
API changes
Visual Studio integration
Documentation improvements

Tooling
dotnet restore runs implicitly
In previous versions of .NET Core, you had to run the dotnet restore command to download dependencies immediately after you created a new project
with the dotnet new command, as well as whenever you added a new dependency to your project.
NOTE
Starting with .NET Core 2.0, you don't have to run dotnet restore because it's run implicitly by all commands that require a restore to occur, such as dotnet new ,
dotnet build and dotnet run . It's still a valid command in certain scenarios where doing an explicit restore makes sense, such as continuous integration builds in
Visual Studio Team Services or in build systems that need to explicitly control the time at which the restore occurs.

You can also disable the automatic invocation of
test commands.

dotnet restore

by passing the

--no-restore

switch to the

new

,

run

,

build

,

publish

,

pack

, and

Retargeting to .NET Core 2.0
If the .NET Core 2.0 SDK is installed, projects that target .NET Core 1.x can be retargeted to .NET Core 2.0.
To retarget to .NET Core 2.0, edit your project file by changing the value of the
have more than one target in your project file) from 1.x to 2.0:



element (or the



element if you


netcoreapp2.0


You can also retarget .NET Standard libraries to .NET Standard 2.0 the same way:

netstandard2.0


For more information about migrating your project to .NET Core 2.0, see Migrating from ASP.NET Core 1.x to ASP.NET Core 2.0.

Language support
In addition to supporting C# and F#, .NET Core 2.0 also supports Visual Basic.
Visual Basic
With version 2.0, .NET Core now supports Visual Basic 2017. You can use Visual Basic to create the following project types:
.NET Core console apps
.NET Core class libraries
.NET Standard class libraries
.NET Core unit test projects
.NET Core xUnit test projects
For example, to create a Visual Basic "Hello World" application, do the following steps from the command line:
1. Open a console window, create a directory for your project, and make it the current directory.
2. Enter the command

dotnet new console -lang vb

.

The command creates a project file with a .vbproj file extension, along with a Visual Basic source code file named Program.vb. This file contains
the source code to write the string "Hello World!" to the console window.

3. Enter the command dotnet run . The .NET Core CLI automatically compiles and executes the application, which displays the message "Hello
World!" in the console window.
Support for C# 7.1
.NET Core 2.0 supports C# 7.1, which adds a number of new features, including:
The Main method, the application entry point, can be marked with the async keyword.
Inferred tuple names.
Default expressions.

Platform improvements
.NET Core 2.0 includes a number of features that make it easier to install .NET Core and to use it on supported operating systems.
.NET Core for Linux is a single implementation
.NET Core 2.0 offers a single Linux implementation that works on multiple Linux distributions. .NET Core 1.x required that you download a distributionspecific Linux implementation.
You can also develop apps that target Linux as a single operating system. .NET Core 1.x required that you target each Linux distribution separately.
Support for the Apple cryptographic libraries
.NET Core 1.x on macOS required the OpenSSL toolkit's cryptographic library. .NET Core 2.0 uses the Apple cryptographic libraries and doesn't require
OpenSSL, so you no longer need to install it.

API changes and library support
Support for .NET Standard 2.0
The .NET Standard defines a versioned set of APIs that must be available on .NET implementations that comply with that version of the standard. The
.NET Standard is targeted at library developers. It aims to guarantee the functionality that is available to a library that targets a version of the .NET
Standard on each .NET implementation. .NET Core 1.x supports the .NET Standard version 1.6; .NET Core 2.0 supports the latest version, .NET
Standard 2.0. For more information, see .NET Standard.
.NET Standard 2.0 includes over 20,000 more APIs than were available in the .NET Standard 1.6. Much of this expanded surface area results from
incorporating APIs that are common to the .NET Framework and Xamarin into .NET Standard.
.NET Standard 2.0 class libraries can also reference .NET Framework class libraries, provided that they call APIs that are present in the .NET Standard
2.0. No recompilation of the .NET Framework libraries is required.
For a list of the APIs that have been added to the .NET Standard since its last version, the .NET Standard 1.6, see .NET Standard 2.0 vs. 1.6.
Expanded surface area
The total number of APIs available on .NET Core 2.0 has more than doubled in comparison with .NET Core 1.1.
And with the Windows Compatibility Pack porting from .NET Framework has also become much simpler.
Support for .NET Framework libraries
.NET Core code can reference existing .NET Framework libraries, including existing NuGet packages. Note that the libraries must use APIs that are
found in .NET Standard.

Visual Studio integration
Visual Studio 2017 version 15.3 and in some cases Visual Studio for Mac offer a number of significant enhancements for .NET Core developers.
Retargeting .NET Core apps and .NET Standard libraries
If the .NET Core 2.0 SDK is installed, you can retarget .NET Core 1.x projects to .NET Core 2.0 and .NET Standard 1.x libraries to .NET Standard 2.0.
To retarget your project in Visual Studio, you open the Application tab of the project's properties dialog and change the Target framework value to
.NET Core 2.0 or .NET Standard 2.0. You can also change it by right-clicking on the project and selecting the Edit *.csproj file option. For more
information, see the Tooling section earlier in this topic.
Live Unit Testing support for .NET Core
Whenever you modify your code, Live Unit Testing automatically runs any affected unit tests in the background and displays the results and code
coverage live in the Visual Studio environment. .NET Core 2.0 now supports Live Unit Testing. Previously, Live Unit Testing was available only for .NET
Framework applications.
For more information, see Live Unit Testing with Visual Studio 2017 and the Live Unit Testing FAQ.
Better support for multiple target frameworks
If you're building a project for multiple target frameworks, you can now select the target platform from the top-level menu. In the following figure, a
project named SCD1 targets 64-bit macOS X 10.11 ( osx.10.11-x64 ) and 64-bit Windows 10/Windows Server 2016 ( win10-x64 ). You can select the
target framework before selecting the project button, in this case to run a debug build.

Side-by-side support for .NET Core SDKs
You can now install the .NET Core SDK independently of Visual Studio. This makes it possible for a single version of Visual Studio to build projects that
target different versions of .NET Core. Previously, Visual Studio and the .NET Core SDK were tightly coupled; a particular version of the SDK
accompanied a particular version of Visual Studio.

Documentation improvements
.NET Application Architecture
.NET Application Architecture gives you access to a set of e-books that provide guidance, best practices, and sample applications when using .NET to
build:
Microservices and Docker containers
Web applications with ASP.NET
Mobile applications with Xamarin
Applications that are deployed to the Cloud with Azure

See also
What's new in ASP.NET Core 2.0

.NET Core Tutorials
5/4/2018 • 2 minutes to read • Edit Online

The following tutorials are available for learning about .NET Core.

Building applications with Visual Studio 2017
Building a C# Hello World application
Debugging your C# Hello World application
Publishing your C# Hello World application
Building a C# class library
Building a class library with Visual Basic
Testing a class library
Consuming a class library
Building a complete C# .NET Core solution on Windows
Azure Cosmos DB: Getting started with the SQL API and .NET Core

Building applications with Visual Studio Code
Getting Started with C# and Visual Studio Code
Getting started with .NET Core on macOS

Building applications with Visual Studio for Mac
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

Building applications with the .NET Core CLI tools
Getting started with .NET Core on Windows/Linux/macOS using the .NET Core CLI tools
Organizing and testing projects with the .NET Core CLI tools
Get started with F#

Other
Unit Testing in .NET Core using dotnet test
Unit testing with MSTest and .NET Core
Developing Libraries with Cross Platform Tools
How to Manage Package Dependency Versions for .NET Core 1.0
Hosting .NET Core from native code
Create a custom template for dotnet new
For tutorials about developing ASP.NET Core web applications, see the ASP.NET Core documentation.

Building a complete .NET Core solution on Windows, using Visual Studio
2017
5/4/2018 • 2 minutes to read • Edit Online

Visual Studio 2017 provides a full-featured development environment for developing .NET Core applications. The procedures in this document describe
the steps necessary to build a typical .NET Core solution that includes reusable libraries, testing, and using third-party libraries.

Prerequisites
Follow the instructions on our prerequisites page to update your environment.

A solution using only .NET Core projects
Writing the library
1. In Visual Studio, choose File, New, Project. In the New Project dialog, expand the Visual C# node and choose the .NET Standard node, and
then choose Class Library (.NET Standard).
2. Name the project "Library" and the solution "Golden". Leave Create directory for solution checked. Click OK.
3. In Solution Explorer, open the context menu for the Dependencies node and choose Manage NuGet Packages.
4. Choose "nuget.org" as the Package source, and choose the Browse tab. Browse for Newtonsoft.Json. Click Install, and accept the license
agreement. The package should now appear under Dependencies/NuGet and be automatically restored.
5. Rename the

Class1.cs

file to

Thing.cs

. Accept the rename of the class. Add a method:

public int Get(int number) => Newtonsoft.Json.JsonConvert.DeserializeObject($"{number}");

6. On the Build menu, choose Build Solution.
The solution should build without error.
Writing the test project
1. In Solution Explorer, open the context menu for the Solution node and choose Add, New Project. In the New Project dialog, under Visual C#
/ .NET Core, choose Unit Test Project (.NET Core). Name it "TestLibrary" and click OK.
2. In the TestLibrary project, open the context menu for the Dependencies node and choose Add Reference. Click Projects, then check the
Library project and click OK. This adds a reference to your library from the test project.
3. Rename the
TestMethod1

file to LibraryTests.cs and accept the class rename. Add
method with the following code:
UnitTest1.cs

using Library;

to the top of the file, and replace the

[TestMethod]
public void ThingGetsObjectValFromNumber()
{
Assert.AreEqual(42, new Thing().Get(42));
}

You should now be able to build the solution.
4. On the Test menu, choose Windows, Test Explorer in order to get the test explorer window into your workspace. After a few seconds, the
ThingGetsObjectValFromNumber test should appear in the test explorer. Choose Run All.
The test should pass.
Writing the console app
1. In Solution Explorer, open the context menu for the solution, and add a new Console App (.NET Core) project. Name it "App".
2. In the App project, open the context menu for the Dependencies node and choose Add, Reference.
3. In the Reference Manager dialog, check Library under the Projects, Solution node, and then click OK
4. Open the context menu for the App node and choose Set as StartUp Project. This ensures that hitting F5 or CTRL+F5 will start the console
app.
5. Open the

Program.cs

file, add a

using Library;

directive to the top of the file, and then add
to the Main method.

Console.WriteLine($"The answer is {new Thing().Get(42)}.");

6. Set a breakpoint after the line that you just added.
7. Press F5 to run the application..
The application should build without error, and should hit the breakpoint. You should also be able to check that the application output "The

answer is 42.".

Getting started with .NET Core on macOS
5/4/2018 • 6 minutes to read • Edit Online

This document provides the steps and workflow to create a .NET Core solution for macOS. Learn how to create projects, unit tests, use the debugging
tools, and incorporate third-party libraries via NuGet.
NOTE
This article uses Visual Studio Code on macOS.

Prerequisites
Install the .NET Core SDK. The .NET Core SDK includes the latest release of the .NET Core framework and runtime.
Install Visual Studio Code. During the course of this article, you also install Visual Studio Code extensions that improve the .NET Core development
experience.
Install the Visual Studio Code C# extension by opening Visual Studio Code and pressing F1 to open the Visual Studio Code palette. Type ext install to
see the list of extensions. Select the C# extension. Restart Visual Studio Code to activate the extension. For more information, see the Visual Studio
Code C# Extension documentation.

Getting started
In this tutorial, you create three projects: a library project, tests for that library project, and a console application that makes use of the library. You can
view or download the source for this topic at the dotnet/samples repository on GitHub. For download instructions, see Samples and Tutorials.
Start Visual Studio Code. Press Ctrl+` (the backquote or backtick character) or select View > Integrated Terminal from the menu to open an
embedded terminal in Visual Studio Code. You can still open an external shell with the Explorer Open in Command Prompt command (Open in
Terminal on Mac or Linux) if you prefer to work outside of Visual Studio Code.
Begin by creating a solution file, which serves as a container for one or more .NET Core projects. In the terminal, create a golden folder and open the
folder. This folder is the root of your solution. Run the dotnet new command to create a new solution, golden.sln:
dotnet new sln

From the golden folder, execute the following command to create a library project, which produces two files,library.csproj and Class1.cs, in the library
folder:
dotnet new classlib -o library

Execute the

dotnet sln

command to add the newly created library.csproj project to the solution:

dotnet sln add library/library.csproj

The library.csproj file contains the following information:


netstandard1.4



Our library methods serialize and deserialize objects in JSON format. To support JSON serialization and deserialization, add a reference to the
Newtonsoft.Json NuGet package. The dotnet add command adds new items to a project. To add a reference to a NuGet package, use the
dotnet add package command and specify the name of the package:
dotnet add library package Newtonsoft.Json

This adds

Newtonsoft.Json

and its dependencies to the library project. Alternatively, manually edit the library.csproj file and add the following node:





Execute dotnet restore , (see note) which restores dependencies and creates an obj folder inside library with three files in it, including a
project.assets.json file:
dotnet restore

In the library folder, rename the file Class1.cs to Thing.cs. Replace the code with the following:
using static Newtonsoft.Json.JsonConvert;
namespace Library
{
public class Thing
{
public int Get(int left, int right) =>
DeserializeObject($"{left + right}");
}
}

The Thing class contains one public method, Get , which returns the sum of two numbers but does so by converting the sum into a string and then
deserializing it into an integer. This makes use of a number of modern C# features, such as using static directives, expression-bodied members, and
string interpolation.
Build the library with the

dotnet build

command. This produces a library.dll file under golden/library/bin/Debug/netstandard1.4:

dotnet build

Create the test project
Build a test project for the library. From the golden folder, create a new test project:
dotnet new xunit -o test-library

Add the test project to the solution:
dotnet sln add test-library/test-library.csproj

Add a project reference the library you created in the previous section so that the compiler can find and use the library project. Use the
dotnet add reference command:
dotnet add test-library/test-library.csproj reference library/library.csproj

Alternatively, manually edit the test-library.csproj file and add the following node:




Now that the dependencies have been properly configured, create the tests for your library. Open UnitTest1.cs and replace its contents with the
following code:
using Library;
using Xunit;
namespace TestApp
{
public class LibraryTests
{
[Fact]
public void TestThing() {
Assert.NotEqual(42, new Thing().Get(19, 23));
}
}
}

Note that you assert the value 42 is not equal to 19+23 (or 42) when you first create the unit test ( Assert.NotEqual ), which will fail. An important step
in building unit tests is to create the test to fail once first to confirm its logic.
From the golden folder, execute the following commands:

dotnet restore
dotnet test test-library/test-library.csproj

These commands will recursively find all projects to restore dependencies, build them, and activate the xUnit test runner to run the tests. The single test
fails, as you expect.
Edit the UnitTest1.cs file and change the assertion from
run the test, which passes this time:

Assert.NotEqual

to

Assert.Equal

. Execute the following command from the golden folder to re-

dotnet test test-library/test-library.csproj

Create the console app
The console app you create over the following steps takes a dependency on the library project you created earlier and calls its library method when it
runs. Using this pattern of development, you see how to create reusable libraries for multiple projects.
Create a new console application from the golden folder:
dotnet new console -o app

Add the console app project to the solution:
dotnet sln add app/app.csproj

Create the dependency on the library by running the

dotnet add reference

command:

dotnet add app/app.csproj reference library/library.csproj

Run dotnet restore (see note) to restore the dependencies of the three projects in the solution. Open Program.cs and replace the contents of the
method with the following line:

Main

WriteLine($"The answer is {new Thing().Get(19, 23)}");

Add two

using

directives to the top of the Program.cs file:

using static System.Console;
using Library;

Execute the following dotnet run command to run the executable, where the
The app produces the string "The answer is 42".

-p

option to

dotnet run

specifies the project for the main application.

dotnet run -p app/app.csproj

Debug the application
Set a breakpoint at the WriteLine statement in the Main method. Do this by either pressing the F9 key when the cursor is over the WriteLine line or
by clicking the mouse in the left margin on the line where you want to set the breakpoint. A red circle will appear in the margin next to the line of code.
When the breakpoint is reached, code execution will stop before the breakpoint line is executed.
Open the debugger tab by selecting the Debug icon in the Visual Studio Code toolbar, selecting View > Debug from the menu bar, or using the
keyboard shortcut CTRL+SHIFT+D:

Press the Play button to start the application under the debugger. The app begins execution and runs to the breakpoint, where it stops. Step into the

Get

method and make sure that you have passed in the correct arguments. Confirm that the answer is 42.

NOTE
Starting with .NET Core 2.0, you don't have to run dotnet restore because it's run implicitly by all commands that require a restore to occur, such as dotnet new ,
dotnet build and dotnet run . It's still a valid command in certain scenarios where doing an explicit restore makes sense, such as continuous integration builds in
Visual Studio Team Services or in build systems that need to explicitly control the time at which the restore occurs.

Getting started with .NET Core on macOS using Visual Studio for Mac
6/22/2018 • 2 minutes to read • Edit Online

Visual Studio for Mac provides a full-featured Integrated Development Environment (IDE ) for developing .NET Core applications. This topic walks you
through building a simple console application using Visual Studio for Mac and .NET Core.
NOTE
Your feedback is highly valued. There are a two ways you can provide feedback to the development team on Visual Studio for Mac:
In Visual Studio for Mac, select Help > Report a Problem from the menu or Report a Problem from the Welcome screen, which will open a window for filing a
bug report. You can track your feedback in the Developer Community portal.
To make a suggestion, select Help > Provide a Suggestion from the menu or Provide a Suggestion from the Welcome screen, which will take you to the Visual
Studio for Mac UserVoice webpage.

Prerequisites
See the Prerequisites for .NET Core on Mac topic.

Getting started
If you've already installed the prerequisites and Visual Studio for Mac, skip this section and proceed to Creating a project. Follow these steps to install
the prerequisites and Visual Studio for Mac:
Download the Visual Studio for Mac installer. Run the installer. Read and accept the license agreement. During the install, you're provided the
opportunity to install Xamarin, a cross-platform mobile app development technology. Installing Xamarin and its related components is optional for .NET
Core development. For a walk-through of the Visual Studio for Mac install process, see Introducing Visual Studio for Mac. When the install is complete,
start the Visual Studio for Mac IDE.

Creating a project
1. Select New Project on the Welcome screen.

2. In the New Project dialog, select App under the .NET Core node. Select the Console Application template followed by Next.

3. Type "HelloWorld" for the Project Name. Select Create.

4. Wait while the project's dependencies are restored. The project has a single C# file, Program.cs, containing a
The Console.WriteLine statement will output "Hello World!" to the console when the app is run.

Program

class with a

Main

method.

Run the application
Run the app in Debug mode using F5 or in Release mode using CTRL+F5.

Next step
The Building a complete .NET Core solution on macOS using Visual Studio for Mac topic shows you how to build a complete .NET Core solution that
includes a reusable library and unit testing.

Building a complete .NET Core solution on macOS using Visual Studio
for Mac
7/17/2018 • 9 minutes to read • Edit Online

Visual Studio for Mac provides a full-featured Integrated Development Environment (IDE ) for developing .NET Core applications. This topic walks you
through building a .NET Core solution that includes a reusable library and unit testing.
This tutorial shows you how to create an application that accepts a search word and a string of text from the user, counts the number of times the search
word appears in the string using a method in a class library, and returns the result to the user. The solution also includes unit testing for the class library
as an introduction to unit testing concepts. If you prefer to proceed through the tutorial with a complete sample, download the sample solution. For
download instructions, see Samples and Tutorials.
NOTE
Your feedback is highly valued. There are two ways you can provide feedback to the development team on Visual Studio for Mac:
In Visual Studio for Mac, select Help > Report a Problem from the menu or Report a Problem from the Welcome screen, which opens a window for filing a bug
report. You can track your feedback in the Developer Community portal.
To make a suggestion, select Help > Provide a Suggestion from the menu or Provide a Suggestion from the Welcome screen, which takes you to the Visual
Studio for Mac UserVoice webpage.

Prerequisites
OpenSSL (if running .NET Core 1.1): See the Prerequisites for .NET Core on Mac topic.
.NET Core SDK 1.1 or later
Visual Studio 2017 for Mac
For more information on prerequisites, see the Prerequisites for .NET Core on Mac. For the full system requirements of Visual Studio 2017 for Mac, see
Visual Studio 2017 for Mac Product Family System Requirements.

Building a library
1. On the Welcome screen, select New Project. In the New Project dialog under the Multiplatform node, select the .NET Standard Library
template. Select Next.

2. Name the project "TextUtils" (a short name for "Text Utilities") and the solution "WordCounter". Leave Create a project directory within the
solution directory checked. Select Create.

3. In the Solution sidebar, expand the TextUtils node to reveal the class file provided by the template, Class1.cs. Right-click the file, select
Rename from the context menu, and rename the file to WordCount.cs. Open the file and replace the contents with the following code:
using System;
using System.Linq;
namespace TextUtils
{
public static class WordCount
{
public static int GetWordCount(string searchWord, string inputString)
{
// Null check these variables and determine if they have values.
if (string.IsNullOrEmpty(searchWord) || string.IsNullOrEmpty(inputString))
{
return 0;
}
//Convert the string into an array of words
var source = inputString.Split(new char[] { '.', '?', '!', ' ', ';', ':', ',' },
StringSplitOptions.RemoveEmptyEntries);
// Create the query. Use ToLowerInvariant to match uppercase/lowercase strings.
var matchQuery = from word in source
where word.ToLowerInvariant() == searchWord.ToLowerInvariant()
select word;
// Count the matches, which executes the query. Return the result.
return matchQuery.Count();
}
}
}

4. Save the file by using any of three different methods: use the keyboard shortcut ⌘+s, select File > Save from the menu, or right-click on the
file's tab and select Save from the contextual menu. The following image shows the IDE window:

5. Select Errors in the margin at the bottom of the IDE window to open the Errors panel. Select the Build Output button.

6. Select Build > Build All from the menu.
The solution builds. The build output panel shows that the build is successful.

Creating a test project
Unit tests provide automated software testing during your development and publishing. The testing framework that you use in this tutorial is xUnit
(version 2.2.0 or later), which is installed automatically when the xUnit test project is added to the solution in the following steps:
1. In the Solution sidebar, right-click the

WordCounter

solution and select Add > Add New Project.

2. In the New Project dialog, select Tests from the .NET Core node. Select the xUnit Test Project followed by Next.

3. Name the new project "TestLibrary" and select Create.

4. In order for the test library to work with the WordCount class, add a reference to the
Dependencies under TestLibrary. Select Edit References from the context menu.

TextUtils

5. In the Edit References dialog, select the TextUtils project on the Projects tab. Select OK.

project. In the Solution sidebar, right-click

6. In the TestLibrary project, rename the UnitTest1.cs file to TextUtilsTests.cs.
7. Open the file and replace the code with the following:
using Xunit;
using TextUtils;
using System.Diagnostics;
namespace TestLibrary
{
public class TextUtils_GetWordCountShould
{
[Fact]
public void IgnoreCasing()
{
var wordCount = WordCount.GetWordCount("Jack", "Jack jack");
Assert.NotEqual(2, wordCount);
}
}
}

The following image shows the IDE with the unit test code in place. Pay attention to the

Assert.NotEqual

statement.

It's important to make a new test fail once to confirm its testing logic is correct. The method passes in the name "Jack" (uppercase) and a string
with "Jack" and "jack" (uppercase and lowercase). If the GetWordCount method is working properly, it returns a count of two instances of the
search word. In order to fail this test on purpose, you first implement the test asserting that two instances of the search word "Jack" aren't
returned by the GetWordCount method. Continue to the next step to fail the test on purpose.
8. Open the Unit Tests panel on the right side of the screen.

9. Click the Dock icon to keep the panel open.

10. Click the Run All button.
The test fails, which is the correct result. The test method asserts that two instances of the inputString , "Jack," aren't returned from the string
"Jack jack" provided to the GetWordCount method. Since word casing was factored out in the GetWordCount method, two instances are returned.
The assertion that 2 is not equal to 2 fails. This is the correct outcome, and the logic of our test is good.

11. Modify the IgnoreCasing test method by changing Assert.NotEqual to Assert.Equal . Save the file by using the keyboard shortcut ⌘+s, File >
Save from the menu, or right-clicking on the file's tab and selecting Save from the context menu.
You expect that the searchWord "Jack" returns two instances with inputString "Jack jack" passed into GetWordCount . Run the test again by
clicking the Run Tests button in the Unit Tests panel or the Rerun Tests button in the Test Results panel at the bottom of the screen. The test
passes. There are two instances of "Jack" in the string "Jack jack" (ignoring casing), and the test assertion is true .

12. Testing individual return values with a Fact is only the beginning of what you can do with unit testing. Another powerful technique allows you
to test several values at once using a Theory . Add the following method to your TextUtils_GetWordCountShould class. You have two methods in
the class after you add this method:
[Theory]
[InlineData(0, "Ting", "Does not appear in the string.")]
[InlineData(1, "Ting", "Ting appears once.")]
[InlineData(2, "Ting", "Ting appears twice with Ting.")]
public void CountInstancesCorrectly(int count,
string searchWord,
string inputString)
{
Assert.NotEqual(count, WordCount.GetWordCount(searchWord,
inputString));
}

The CountInstancesCorrectly checks that the GetWordCount method counts correctly. The InlineData provides a count, a search word, and an
input string to check. The test method runs once for each line of data. Note once again that you're asserting a failure first by using
Assert.NotEqual , even when you know that the counts in the data are correct and that the values match the counts returned by the GetWordCount
method. Performing the step of failing the test on purpose might seem like a waste of time at first, but checking the logic of the test by failing it
first is an important check on the logic of your tests. When you come across a test method that passes when you expect it to fail, you've found a
bug in the logic of the test. It's worth the effort to take this step every time you create a test method.
13. Save the file and run the tests again. The casing test passes but the three count tests fail. This is exactly what you expect to happen.

14. Modify the

CountInstancesCorrectly

test method by changing

Assert.NotEqual

to

Assert.Equal

. Save the file. Run the tests again. All tests pass.

Adding a console app
1. In the Solution sidebar, right-click the WordCounter solution. Add a new Console Application project by selecting the template from the .NET
Core > App templates. Select Next. Name the project WordCounterApp. Select Create to create the project in the solution.
2. In the Solutions sidebar, right-click the Dependencies node of the new WordCounterApp project. In the Edit References dialog, check
TextUtils and select OK.
3. Open the Program.cs file. Replace the code with the following:

using System;
using TextUtils;
namespace WordCounterApp
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Enter a search word:");
var searchWord = Console.ReadLine();
Console.WriteLine("Provide a string to search:");
var inputString = Console.ReadLine();
var wordCount = WordCount.GetWordCount(searchWord, inputString);
var pluralChar = "s";
if (wordCount == 1)
{
pluralChar = string.Empty;
}
Console.WriteLine($"The search word {searchWord} appears " +
$"{wordCount} time{pluralChar}.");
}
}
}

4. To run the app in a console window instead of the IDE, right-click the WordCounterApp project, select Options, and open the Default node under
Configurations. Check the box for Run on external console. Leave the Pause console output option checked. This setting causes the app to
spawn in a console window so that you can type input for the Console.ReadLine statements. If you leave the app to run in the IDE, you can only
see the output of Console.WriteLine statements. Console.ReadLine statements do not work in the IDE's Application Output panel.

5. Because the current version of Visual Studio for Mac cannot run the tests when the solution is run, you run the console app directly. Right-click
on the WordCounterApp project and select Run item from the context menu. If you attempt to run the app with the Play button, the test runner
and app fail to run. For more information on the status of the work on this issue, see xunit/xamarinstudio.xunit (#60). When you run the app,
provide values for the search word and input string at the prompts in the console window. The app indicates the number of times the search
word appears in the string.

6. The last feature to explore is debugging with Visual Studio for Mac. Set a breakpoint on the Console.WriteLine statement: Select in the left
margin of line 23, and you see a red circle appear next to the line of code. Alternatively, select anywhere on the line of code and select Run >
Toggle Breakpoint from the menu.

7. Right-click the WordCounterApp project. Select Start Debugging item from the context menu. When the app runs, enter the search word "cat"
and "The dog chased the cat, but the cat escaped." for the string to search. When the Console.WriteLine statement is reached, program execution
halts before the statement is executed. In the Locals tab, you can see the searchWord , inputString , wordCount , and pluralChar values.

8. In the Immediate pane, type "wordCount = 999;" and press Enter. This assigns a nonsense value of 999 to the
you can replace variable values while debugging.

wordCount

variable showing that

9. In the toolbar, click the continue arrow. Look at the output in the console window. It reports the incorrect value of 999 that you set when you were
debugging the app.

See also
Visual Studio 2017 for Mac Release Notes

Getting started with .NET Core on Windows/Linux/macOS using the
command line
5/4/2018 • 5 minutes to read • Edit Online

This topic will show you how to start developing cross-platforms apps in your machine using the .NET Core CLI tools.
If you're unfamiliar with the .NET Core CLI toolset, read the .NET Core SDK overview.

Prerequisites
.NET Core SDK 1.0.
A text editor or code editor of your choice.

Hello, Console App!
You can view or download the sample code from the dotnet/samples GitHub repository. For download instructions, see Samples and Tutorials.
Open a command prompt and create a folder named Hello. Navigate to the folder you created and type the following:
$ dotnet new console
$ dotnet restore
$ dotnet run

Let's do a quick walkthrough:
1.

$ dotnet new console
dotnet new creates an up-to-date Hello.csproj project file with the dependencies necessary to build a console app. It also creates a
a basic file containing the entry point for the application.
Hello.csproj

Program.cs

,

:



Exe
netcoreapp1.0



The project file specifies everything that's needed to restore dependencies and build the program.
The OutputType tag specifies that we're building an executable, in other words a console application.
The TargetFramework tag specifies what .NET implementation we're targeting. In an advanced scenario, you can specify multiple target
frameworks and build to all those in a single operation. In this tutorial, we'll stick to building only for .NET Core 1.0.
Program.cs :
using System;
namespace Hello
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Hello World!");
}
}
}

The program starts by using System , which means "bring everything in the
includes basic constructs such as string , or numeric types.

System

namespace into scope for this file". The

System

namespace

We then define a namespace called Hello . You can change this to anything you want. A class named Program is defined within that namespace,
with a Main method that takes an array of strings as its argument. This array contains the list of arguments passed in when the compiled
program is called. As it is, this array is not used: all the program is doing is to write "Hello World!" to the console. Later, we'll make changes to the
code that will make use of this argument.

NOTE
Starting with .NET Core 2.0, you don't have to run dotnet restore because it's run implicitly by all commands that require a restore to occur, such as
dotnet new , dotnet build and dotnet run . It's still a valid command in certain scenarios where doing an explicit restore makes sense, such as continuous
integration builds in Visual Studio Team Services or in build systems that need to explicitly control the time at which the restore occurs.

2.

$ dotnet restore
dotnet restore calls into NuGet (.NET package manager ) to restore the tree of dependencies. NuGet analyzes the Hello.csproj file, downloads
the dependencies stated in the file (or grabs them from a cache on your machine), and writes the obj/project.assets.json file. The project.assets.json
file is necessary to be able to compile and run.

The project.assets.json file is a persisted and complete set of the graph of NuGet dependencies and other information describing an app. This file
is read by other tools, such as dotnet build and dotnet run , enabling them to process the source code with a correct set of NuGet
dependencies and binding resolutions.
3.

$ dotnet run
dotnet run

calls

dotnet build

to ensure that the build targets have been built, and then calls

dotnet 

to run the target

application.
$ dotnet run
Hello World!

Alternatively, you can also execute dotnet build to compile the code without running the build console applications. This results in a compiled
application as a DLL file that can be run with dotnet bin\Debug\netcoreapp1.0\Hello.dll on Windows (use / for non-Windows systems). You
may also specify arguments to the application as you'll see later on the topic.
$ dotnet bin\Debug\netcoreapp1.0\Hello.dll
Hello World!

As an advanced scenario, it's possible to build the application as a self-contained set of platform-specific files that can be deployed and run to a
machine that doesn't necessarily have .NET Core installed. See .NET Core Application Deployment for details.
Augmenting the program
Let's change the program a bit. Fibonacci numbers are fun, so let's add that in addition to use the argument to greet the person running the app.
1. Replace the contents of your Program.cs file with the following code:

using System;
namespace Hello
{
class Program
{
static void Main(string[] args)
{
if (args.Length > 0)
{
Console.WriteLine($"Hello {args[0]}!");
}
else
{
Console.WriteLine("Hello!");
}
Console.WriteLine("Fibonacci Numbers 1-15:");
for (int i = 0; i < 15; i++)
{
Console.WriteLine($"{i + 1}: {FibonacciNumber(i)}");
}
}
static int FibonacciNumber(int n)
{
int a = 0;
int b = 1;
int tmp;
for (int i = 0; i < n; i++)
{
tmp = a;
a = b;
b += tmp;
}
return a;
}
}
}

2. Execute

dotnet build

to compile the changes.

3. Run the program passing a parameter to the app:
$ dotnet run -- John
Hello John!
Fibonacci Numbers 1-15:
1: 0
2: 1
3: 1
4: 2
5: 3
6: 5
7: 8
8: 13
9: 21
10: 34
11: 55
12: 89
13: 144
14: 233
15: 377

And that's it! You can augment

Program.cs

any way you like.

Working with multiple files
Single files are fine for simple one-off programs, but if you're building a more complex app, you're probably going to have multiple source files on your
project Let's build off of the previous Fibonacci example by caching some Fibonacci values and add some recursive features.
1. Add a new file inside the Hello directory named FibonacciGenerator.cs with the following code:

using System;
using System.Collections.Generic;
namespace Hello
{
public class FibonacciGenerator
{
private Dictionary _cache = new Dictionary();
private int Fib(int n) => n < 2 ? n : FibValue(n - 1) + FibValue(n - 2);
private int FibValue(int n)
{
if (!_cache.ContainsKey(n))
{
_cache.Add(n, Fib(n));
}
return _cache[n];
}
public IEnumerable Generate(int n)
{
for (int i = 0; i < n; i++)
{
yield return FibValue(i);
}
}
}
}

2. Change the

Main

method in your Program.cs file to instantiate the new class and call its method as in the following example:

using System;
namespace Hello
{
class Program
{
static void Main(string[] args)
{
var generator = new FibonacciGenerator();
foreach (var digit in generator.Generate(15))
{
Console.WriteLine(digit);
}
}
}
}

3. Execute

dotnet build

to compile the changes.

4. Run your app by executing

dotnet run

. The following shows the program output:

0
1
1
2
3
5
8
13
21
34
55
89
144
233
377

And that's it! Now, you can start using the basic concepts learned here to create your own programs.
Note that the commands and steps shown in this tutorial to run your application are used during development time only. Once you're ready to deploy
your app, you'll want to take a look at the different deployment strategies for .NET Core apps and the dotnet publish command.

See also
Organizing and testing projects with the .NET Core CLI tools

Organizing and testing projects with the .NET Core command line
7/17/2018 • 6 minutes to read • Edit Online

This tutorial follows Getting started with .NET Core on Windows/Linux/macOS using the command line, taking you beyond the creation of a simple
console app to develop advanced and well-organized applications. After showing you how to use folders to organize your code, this tutorial shows you
how to extend a console application with the xUnit testing framework.

Using folders to organize code
If you want to introduce new types into a console app, you can do so by adding files containing the types to the app. For example if you add files
containing AccountInformation and MonthlyReportRecords types to your project, the project file structure is flat and easy to navigate:
/MyProject
|__AccountInformation.cs
|__MonthlyReportRecords.cs
|__MyProject.csproj
|__Program.cs

However, this only works well when the size of your project is relatively small. Can you imagine what will happen if you add 20 types to the project? The
project definitely wouldn't be easy to navigate and maintain with that many files littering the project's root directory.
To organize the project, create a new folder and name it Models to hold the type files. Place the type files into the Models folder:
/MyProject
|__/Models
|__AccountInformation.cs
|__MonthlyReportRecords.cs
|__MyProject.csproj
|__Program.cs

Projects that logically group files into folders are easy to navigate and maintain. In the next section, you create a more complex sample with folders and
unit testing.

Organizing and testing using the NewTypes Pets Sample
Building the sample
For the following steps, you can either follow along using the NewTypes Pets Sample or create your own files and folders. The types are logically
organized into a folder structure that permits the addition of more types later, and tests are also logically placed in folders permitting the addition of
more tests later.
The sample contains two types, Dog and Cat , and has them implement a common interface, IPet . For the NewTypes project, your goal is to organize
the pet-related types into a Pets folder. If another set of types is added later, WildAnimals for example, they're placed in the NewTypes folder alongside
the Pets folder. The WildAnimals folder may contain types for animals that aren't pets, such as Squirrel and Rabbit types. In this way as types are
added, the project remains well organized.
Create the following folder structure with file content indicated:
/NewTypes
|__/src
|__/NewTypes
|__/Pets
|__Dog.cs
|__Cat.cs
|__IPet.cs
|__Program.cs
|__NewTypes.csproj

IPet.cs:
using System;
namespace Pets
{
public interface IPet
{
string TalkToOwner();
}
}

Dog.cs:

using System;
namespace Pets
{
public class Dog : IPet
{
public string TalkToOwner() => "Woof!";
}
}

Cat.cs:
using System;
namespace Pets
{
public class Cat : IPet
{
public string TalkToOwner() => "Meow!";
}
}

Program.cs:
using System;
using Pets;
using System.Collections.Generic;
namespace ConsoleApplication
{
public class Program
{
public static void Main(string[] args)
{
List pets = new List
{
new Dog(),
new Cat()
};
foreach (var pet in pets)
{
Console.WriteLine(pet.TalkToOwner());
}
}
}
}

NewTypes.csproj:


Exe
netcoreapp1.1



Execute the following commands:
dotnet run

Obtain the following output:
Woof!
Meow!

Optional exercise: You can add a new pet type, such as a Bird , by extending this project. Make the bird's
owner. Run the app again. The output will include Tweet!

TalkToOwner

method give a

Tweet!

to the

Testing the sample
The NewTypes project is in place, and you've organized it by keeping the pets-related types in a folder. Next, create your test project and start writing
tests with the xUnit test framework. Unit testing allows you to automatically check the bevahior of your pet types to confirm that they're operating
properly.
Create a test folder with a NewTypesTests folder within it. At a command prompt from the NewTypesTests folder, execute

dotnet new xunit

. This

produces two files: NewTypesTests.csproj and UnitTest1.cs.
The test project cannot currently test the types in
dotnet add reference command:

NewTypes

and requires a project reference to the

NewTypes

project. To add a project reference, use the

dotnet add reference ../../src/NewTypes/NewTypes.csproj

You also have the option of manually adding the project reference by adding an



node to the NewTypesTests.csproj file:





NewTypesTests.csproj:


netcoreapp1.1











The NewTypesTests.csproj file contains the following:
Package reference to Microsoft.NET.Test.Sdk , the .NET testing infrastructure
Package reference to xunit , the xUnit testing framework
Package reference to xunit.runner.visualstudio , the test runner
Project reference to NewTypes , the code to test
Change the name of UnitTest1.cs to PetTests.cs and replace the code in the file with the following:
using System;
using Xunit;
using Pets;
public class PetTests
{
[Fact]
public void DogTalkToOwnerReturnsWoof()
{
string expected = "Woof!";
string actual = new Dog().TalkToOwner();
Assert.NotEqual(expected, actual);
}
[Fact]
public void CatTalkToOwnerReturnsMeow()
{
string expected = "Meow!";
string actual = new Cat().TalkToOwner();
Assert.NotEqual(expected, actual);
}
}

Optional exercise: If you added a Bird type earlier that yields a Tweet! to the owner, add a test method to the PetTests.cs file,
BirdTalkToOwnerReturnsTweet , to check that the TalkToOwner method works correctly for the Bird type.
NOTE
Although you expect that the expected and actual values are equal, an initial assertion with the Assert.NotEqual check specifies that these values are not
equal. Always initially create a test to fail in order to check the logic of the test. After you confirm that the test fails, adjust the assertion to allow the test to pass.

The following shows the complete project structure:

/NewTypes
|__/src
|__/NewTypes
|__/Pets
|__Dog.cs
|__Cat.cs
|__IPet.cs
|__Program.cs
|__NewTypes.csproj
|__/test
|__NewTypesTests
|__PetTests.cs
|__NewTypesTests.csproj

Start in the test/NewTypesTests directory. Restore the test project with the
This command starts the test runner specified in the project file.

dotnet restore

command. Run the tests with the

dotnet test

command.

NOTE
Starting with .NET Core 2.0, you don't have to run dotnet restore because it's run implicitly by all commands that require a restore to occur, such as dotnet new ,
dotnet build and dotnet run . It's still a valid command in certain scenarios where doing an explicit restore makes sense, such as continuous integration builds in
Visual Studio Team Services or in build systems that need to explicitly control the time at which the restore occurs.

As expected, testing fails, and the console displays the following output:
Test run for C:\NewTypesMsBuild\test\NewTypesTests\bin\Debug\netcoreapp1.1\NewTypesTests.dll(.NETCoreApp,Version=v1.1)
Microsoft (R) Test Execution Command Line Tool Version 15.0.0.0
Copyright (c) Microsoft Corporation. All rights reserved.
Starting test execution, please wait...
[xUnit.net 00:00:00.7271827] Discovering: NewTypesTests
[xUnit.net 00:00:00.8258687] Discovered: NewTypesTests
[xUnit.net 00:00:00.8663545] Starting:
NewTypesTests
[xUnit.net 00:00:01.0109236]
PetTests.CatTalkToOwnerReturnsMeow [FAIL]
[xUnit.net 00:00:01.0119107]
Assert.NotEqual() Failure
[xUnit.net 00:00:01.0120278]
Expected: Not "Meow!"
[xUnit.net 00:00:01.0120968]
Actual: "Meow!"
[xUnit.net 00:00:01.0130500]
Stack Trace:
[xUnit.net 00:00:01.0141240]
C:\NewTypesMsBuild\test\NewTypesTests\PetTests.cs(22,0): at PetTests.CatTalkToOwnerReturnsMeow()
[xUnit.net 00:00:01.0272364]
PetTests.DogTalkToOwnerReturnsWoof [FAIL]
[xUnit.net 00:00:01.0273649]
Assert.NotEqual() Failure
[xUnit.net 00:00:01.0274166]
Expected: Not "Woof!"
[xUnit.net 00:00:01.0274690]
Actual: "Woof!"
[xUnit.net 00:00:01.0275264]
Stack Trace:
[xUnit.net 00:00:01.0275960]
C:\NewTypesMsBuild\test\NewTypesTests\PetTests.cs(13,0): at PetTests.DogTalkToOwnerReturnsWoof()
[xUnit.net 00:00:01.0294509] Finished:
NewTypesTests
Failed PetTests.CatTalkToOwnerReturnsMeow
Error Message:
Assert.NotEqual() Failure
Expected: Not "Meow!"
Actual: "Meow!"
Stack Trace:
at PetTests.CatTalkToOwnerReturnsMeow() in C:\NewTypesMsBuild\test\NewTypesTests\PetTests.cs:line 22
Failed PetTests.DogTalkToOwnerReturnsWoof
Error Message:
Assert.NotEqual() Failure
Expected: Not "Woof!"
Actual: "Woof!"
Stack Trace:
at PetTests.DogTalkToOwnerReturnsWoof() in C:\NewTypesMsBuild\test\NewTypesTests\PetTests.cs:line 13
Total tests: 2. Passed: 0. Failed: 2. Skipped: 0.
Test Run Failed.
Test execution time: 2.1371 Seconds

Change the assertions of your tests from

Assert.NotEqual

to

Assert.Equal

:

using System;
using Xunit;
using Pets;
public class PetTests
{
[Fact]
public void DogTalkToOwnerReturnsWoof()
{
string expected = "Woof!";
string actual = new Dog().TalkToOwner();
Assert.Equal(expected, actual);
}
[Fact]
public void CatTalkToOwnerReturnsMeow()
{
string expected = "Meow!";
string actual = new Cat().TalkToOwner();
Assert.Equal(expected, actual);
}
}

Re-run the tests with the

dotnet test

command and obtain the following output:

Microsoft (R) Test Execution Command Line Tool Version 15.0.0.0
Copyright (c) Microsoft Corporation. All rights reserved.
Starting test execution, please wait...
[xUnit.net 00:00:01.3882374] Discovering:
[xUnit.net 00:00:01.4767970] Discovered:
[xUnit.net 00:00:01.5157667] Starting:
[xUnit.net 00:00:01.6408870] Finished:

NewTypesTests
NewTypesTests
NewTypesTests
NewTypesTests

Total tests: 2. Passed: 2. Failed: 0. Skipped: 0.
Test Run Successful.
Test execution time: 1.6634 Seconds

Testing passes. The pet types' methods return the correct values when talking to the owner.
You've learned techniques for organizing and testing projects using xUnit. Go forward with these techniques applying them in your own projects. Happy
coding!

Developing Libraries with Cross Platform Tools
5/4/2018 • 11 minutes to read • Edit Online

This article covers how to write libraries for .NET using cross-platform CLI tools. The CLI provides an efficient and low-level experience that works
across any supported OS. You can still build libraries with Visual Studio, and if that is your preferred experience refer to the Visual Studio guide.

Prerequisites
You need the .NET Core SDK and CLI installed on your machine.
For the sections of this document dealing with .NET Framework versions, you need the .NET Framework installed on a Windows machine.
Additionally, if you wish to support older .NET Framework targets, you need to install targeting/developer packs for older framework versions from the
.NET target platforms page. Refer to this table:
.NET FRAMEWORK VERSION

WHAT TO DOWNLOAD

4.6.1

.NET Framework 4.6.1 Targeting Pack

4.6

.NET Framework 4.6 Targeting Pack

4.5.2

.NET Framework 4.5.2 Developer Pack

4.5.1

.NET Framework 4.5.1 Developer Pack

4.5

Windows Software Development Kit for Windows 8

4.0

Windows SDK for Windows 7 and .NET Framework 4

2.0, 3.0, and 3.5

.NET Framework 3.5 SP1 Runtime (or Windows 8+ version)

How to target the .NET Standard
If you're not quite familiar with the .NET Standard, refer to the .NET Standard to learn more.
In that article, there is a table which maps .NET Standard versions to various implementations:
.NET
STANDARD

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

.NET
Framework 1

4.5

4.5

4.5.1

4.6

4.6.1

4.6.1

4.6.1

4.6.1

Mono

4.6

4.6

4.6

4.6

4.6

4.6

4.6

5.4

Xamarin.iOS

10.0

10.0

10.0

10.0

10.0

10.0

10.0

10.14

Xamarin.Mac

3.0

3.0

3.0

3.0

3.0

3.0

3.0

3.8

Xamarin.Andro
id

7.0

7.0

7.0

7.0

7.0

7.0

7.0

8.0

Universal
Windows
Platform

10.0

10.0

10.0

10.0

10.0

10.0.16299

10.0.16299

10.0.16299

Windows

8.0

8.0

8.1

Windows
Phone

8.1

8.1

8.1

Windows
Phone
Silverlight

8.0

1 The versions listed for .NET Framework apply to .NET Core SDK 2.0 and later versions of the tooling. Older versions used a different mapping for .NET Standard 1.5 and higher.

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.
For an interactive table, see .NET Standard versions.
Here's what this table means for the purposes of creating a library:
The version of the .NET Standard you pick will be a tradeoff between access to the newest APIs and the ability to target more .NET implementations
and .NET Standard versions. You control the range of targetable platforms and versions by picking a version of netstandardX.X (Where X.X is a
version number) and adding it to your project file ( .csproj or .fsproj ).
You have three primary options when targeting the .NET Standard, depending on your needs.
1. You can use the default version of the .NET Standard supplied by templates - netstandard1.4 - which gives you access to most APIs on .NET
Standard while still being compatible with UWP, .NET Framework 4.6.1, and the forthcoming .NET Standard 2.0.


netstandard1.4



2. You can use a lower or higher version of the .NET Standard by modifying the value in the

TargetFramework

node of your project file.

.NET Standard versions are backward compatible. That means that netstandard1.0 libraries run on netstandard1.1 platforms and higher.
However, there is no forward compatibility - lower .NET Standard platforms cannot reference higher ones. This means that netstandard1.0
libraries cannot reference libraries targeting netstandard1.1 or higher. Select the Standard version that has the right mix of APIs and platform
support for your needs. We recommend netstandard1.4 for now.
3. If you want to target the .NET Framework versions 4.0 or below, or you wish to use an API available in the .NET Framework but not in the .NET
Standard (for example, System.Drawing ), read the following sections and learn how to multitarget.

How to target the .NET Framework
NOTE
These instructions assume you have the .NET Framework installed on your machine. Refer to the Prerequisites to get dependencies installed.

Keep in mind that some of the .NET Framework versions used here are no longer in support. Refer to the .NET Framework Support Lifecycle Policy
FAQ about unsupported versions.
If you want to reach the maximum number of developers and projects, use the .NET Framework 4.0 as your baseline target. To target the .NET
Framework, you will need to begin by using the correct Target Framework Moniker (TFM ) that corresponds to the .NET Framework version you wish to
support.
.NET
.NET
.NET
.NET
.NET
.NET
.NET
.NET
.NET
.NET
.NET

Framework
Framework
Framework
Framework
Framework
Framework
Framework
Framework
Framework
Framework
Framework

2.0
3.0
3.5
4.0
4.5
4.5.1
4.5.2
4.6
4.6.1
4.6.2
4.7

-->
-->
-->
-->
-->
-->
-->
-->
-->
-->
-->

net20
net30
net35
net40
net45
net451
net452
net46
net461
net462
net47

You then insert this TFM into the
Framework 4.0:

TargetFramework

section of your project file. For example, here's how you would write a library which targets the .NET



net40



And that's it! Although this compiled only for the .NET Framework 4, you can use the library on newer versions of the .NET Framework.

How to Multitarget

NOTE
The following instructions assume you have the .NET Framework installed on your machine. Refer to the Prerequisites section to learn which dependencies you need to
install and where to download them from.

You may need to target older versions of the .NET Framework when your project supports both the .NET Framework and .NET Core. In this scenario, if
you want to use newer APIs and language constructs for the newer targets, use #if directives in your code. You also might need to add different
packages and dependencies for each platform you're targeting to include the different APIs needed for each case.
For example, let's say you have a library that performs networking operations over HTTP. For .NET Standard and the .NET Framework versions 4.5 or
higher, you can use the HttpClient class from the System.Net.Http namespace. However, earlier versions of the .NET Framework don't have the
HttpClient class, so you could use the WebClient class from the System.Net namespace for those instead.
Your project file could look like this:


netstandard1.4;net40;net45












You'll notice three major changes here:
1. The TargetFramework node has been replaced by TargetFrameworks , and three TFMs are expressed inside.
2. There is an  node for the net40 target pulling in one .NET Framework reference.
3. There is an  node for the net45 target pulling in two .NET Framework references.
The build system is aware of the following preprocessor symbols used in
TARGET FRAMEWORKS

.NET Framework

#if

directives:
SYMBOLS
NET20

.NET Standard

,
,

NET35

,

Here is an example making use of conditional compilation per-target:

,

NET45

,

NET451

,

NET472

NETSTANDARD1_0

,
,

NETSTANDARD1_1

NETSTANDARD1_4

.NET Core

NET40

NET471

NET47

NETCOREAPP1_0

,

NETSTANDARD1_5

NETCOREAPP1_1

,

,
,

,

NET452

,

NET46

NETSTANDARD1_2
NETSTANDARD1_6

NETCOREAPP2_0

,

,
,

,

NET461

,

NETSTANDARD1_3
NETSTANDARD2_0

NETCOREAPP2_1

NET462

,

,

using System;
using System.Text.RegularExpressions;
#if NET40
// This only compiles for the .NET Framework 4 targets
using System.Net;
#else
// This compiles for all other targets
using System.Net.Http;
using System.Threading.Tasks;
#endif
namespace MultitargetLib
{
public class Library
{
#if NET40
private readonly WebClient _client = new WebClient();
private readonly object _locker = new object();
#else
private readonly HttpClient _client = new HttpClient();
#endif
#if NET40
// .NET Framework 4.0 does not have async/await
public string GetDotNetCount()
{
string url = "http://www.dotnetfoundation.org/";
var uri = new Uri(url);
string result = "";
// Lock here to provide thread-safety.
lock(_locker)
{
result = _client.DownloadString(uri);
}
int dotNetCount = Regex.Matches(result, ".NET").Count;
return $"Dotnet Foundation mentions .NET {dotNetCount} times!";
}
#else
// .NET 4.5+ can use async/await!
public async Task GetDotNetCountAsync()
{
string url = "http://www.dotnetfoundation.org/";
// HttpClient is thread-safe, so no need to explicitly lock here
var result = await _client.GetStringAsync(url);
int dotNetCount = Regex.Matches(result, ".NET").Count;
return $"dotnetfoundation.org mentions .NET {dotNetCount} times in its HTML!";
}
#endif
}
}

If you build this project with

dotnet build

, you'll notice three directories under the

bin/

folder:

net40/
net45/
netstandard1.4/

Each of these contain the

.dll

files for each target.

How to test libraries on .NET Core
It's important to be able to test across platforms. You can use either xUnit or MSTest out of the box. Both are perfectly suitable for unit testing your
library on .NET Core. How you set up your solution with test projects will depend on the structure of your solution. The following example assumes that
the test and source directories live in the same top-level directory.
NOTE
This uses some .NET Core CLI commands. See dotnet new and dotnet sln for more information.

1. Set up your solution. You can do so with the following commands:

mkdir SolutionWithSrcAndTest
cd SolutionWithSrcAndTest
dotnet new sln
dotnet new classlib -o MyProject
dotnet new xunit -o MyProject.Test
dotnet sln add MyProject/MyProject.csproj
dotnet sln add MyProject.Test/MyProject.Test.csproj

This will create projects and link them together in a solution. Your directory for

SolutionWithSrcAndTest

should look like this:

/SolutionWithSrcAndTest
|__SolutionWithSrcAndTest.sln
|__MyProject/
|__MyProject.Test/

2. Navigate to the test project's directory and add a reference to

MyProject.Test

from

MyProject

.

cd MyProject.Test
dotnet add reference ../MyProject/MyProject.csproj

3. Restore packages and build projects:
dotnet restore
dotnet build

NOTE
Starting with .NET Core 2.0, you don't have to run dotnet restore because it's run implicitly by all commands that require a restore to occur, such as
dotnet new , dotnet build and dotnet run . It's still a valid command in certain scenarios where doing an explicit restore makes sense, such as continuous
integration builds in Visual Studio Team Services or in build systems that need to explicitly control the time at which the restore occurs.

4. Verify that xUnit runs by executing the

dotnet test

command. If you chose to use MSTest, then the MSTest console runner should run instead.

And that's it! You can now test your library across all platforms using command line tools. To continue testing now that you have everything set up,
testing your library is very simple:
1. Make changes to your library.
2. Run tests from the command line, in your test directory, with
Your code will be automatically rebuilt when you invoke

dotnet test

dotnet test

command.

command.

How to use multiple projects
A common need for larger libraries is to place functionality in different projects.
Imagine you wished to build a library which could be consumed in idiomatic C# and F#. That would mean that consumers of your library consume
them in ways which are natural to C# or F#. For example, in C# you might consume the library like this:
using AwesomeLibrary.CSharp;
public Task DoThings(Data data)
{
var convertResult = await AwesomeLibrary.ConvertAsync(data);
var result = AwesomeLibrary.Process(convertResult);
// do something with result
}

In F#, it might look like this:
open AwesomeLibrary.FSharp
let doWork data = async {
let! result = AwesomeLibrary.AsyncConvert data // Uses an F# async function rather than C# async method
// do something with result
}

Consumption scenarios like this mean that the APIs being accessed have to have a different structure for C# and F#. A common approach to
accomplishing this is to factor all of the logic of a library into a core project, with C# and F# projects defining the API layers that call into that core
project. The rest of the section will use the following names:
AwesomeLibrary.Core - A core project which contains all logic for the library
AwesomeLibrary.CSharp - A project with public APIs intended for consumption in C#

AwesomeLibrary.FSharp - A project with public APIs intended for consumption in F#
You can run the following commands in your terminal to produce the same structure as this guide:
mkdir AwesomeLibrary && cd AwesomeLibrary
dotnet new sln
mkdir AwesomeLibrary.Core && cd AwesomeLibrary.Core && dotnet new classlib
cd ..
mkdir AwesomeLibrary.CSharp && cd AwesomeLibrary.CSharp && dotnet new classlib
cd ..
mkdir AwesomeLibrary.FSharp && cd AwesomeLibrary.FSharp && dotnet new classlib -lang F#
cd ..
dotnet sln add AwesomeLibrary.Core/AwesomeLibrary.Core.csproj
dotnet sln add AwesomeLibrary.CSharp/AwesomeLibrary.CSharp.csproj
dotnet sln add AwesomeLibrary.FSharp/AwesomeLibrary.FSharp.fsproj

This will add the three projects above and a solution file which links them together. Creating the solution file and linking projects will allow you to
restore and build projects from a top-level.
Project-to-project referencing
The best way to reference a project is to use the .NET Core CLI to add a project reference. From the AwesomeLibrary.CSharp and
AwesomeLibrary.FSharp project directories, you can run the following command:
$ dotnet add reference ../AwesomeLibrary.Core/AwesomeLibrary.Core.csproj

The project files for both AwesomeLibrary.CSharp and AwesomeLibrary.FSharp will now reference AwesomeLibrary.Core as a
target. You can verify this by inspecting the project files and seeing the following in them:

ProjectReference





You can add this section to each project file manually if you prefer not to use the .NET Core CLI.
Structuring a solution
Another important aspect of multi-project solutions is establishing a good overall project structure. You can organize code however you like, and as
long as you link each project to your solution file with dotnet sln add , you will be able to run dotnet restore and dotnet build at the solution level.

Getting started with ASP.NET Core
5/4/2018 • 2 minutes to read • Edit Online

For tutorials about developing ASP.NET Core web applications, we suggest you head over to ASP.NET Core documentation.

How to Manage Package Dependency Versions for .NET Core 1.0
5/4/2018 • 2 minutes to read • Edit Online

This article covers what you need to know about package versions for your .NET Core libraries and apps.

Glossary
Fix - Fixing dependencies means you are using the same "family" of packages released on NuGet for .NET Core 1.0.
Metapackage - A NuGet package that represents a set of NuGet packages.
Trimming - The act of removing the packages you do not depend on from a metapackage. This is something relevant for NuGet package authors. See
Reducing Package Dependencies with project.json for more information.

Fix your dependencies to .NET Core 1.0
To reliably restore packages and write reliable code, it's important that you fix your dependencies to the versions of packages shipping alongside .NET
Core 1.0. This means every package should have a single version with no additional qualifiers.
Examples of packages fixed to 1.0
"System.Collections":"4.0.11"
"NETStandard.Library":"1.6.0"
"Microsoft.NETCore.App":"1.0.0"

Examples of packages that are NOT fixed to 1.0
"Microsoft.NETCore.App":"1.0.0-rc4-00454-00"
"System.Net.Http":"4.1.0-*"
"System.Text.RegularExpressions":"4.0.10-rc3-24021-00"

Why does this matter?
We guarantee that if you fix your dependencies to what ships alongside .NET Core 1.0, those packages will all work together. There is no such guarantee
if you use packages which aren't fixed in this way.
Scenarios
Although there is a big list of all packages and their versions released with .NET Core 1.0, you may not have to look through it if your code falls under
certain scenarios.
Are you depending only on
If so, you should fix your

NETStandard.Library

NETStandard.Library

Are you depending only on

?

package to version

Microsoft.NETCore.App

If so, you should fix your
1.0.

Microsoft.NETCore.App

Are you trimming your

NETStandard.Library

1.6

?

package to version
or

. Because this is a curated metapackage, its package closure is also fixed to 1.0.

1.0.0

Microsoft.NETCore.App

. Because this is a curated metapackage, its package closure is also fixed to

metapackage dependencies?

If so, you should ensure that the metapackage you start with is fixed to 1.0. The individual packages you depend on after trimming are also fixed to 1.0.
Are you depending on packages outside the

NETStandard.Library

or

Microsoft.NETCore.App

metapackages?

If so, you need to fix your other dependencies to 1.0. See the correct package versions and build numbers at the end of this article.
A note on using a splat string (*) when versioning
You may have adopted a versioning pattern which uses a splat (*) string like this:

"System.Collections":"4.0.11-*"

.

You should not do this. Using the splat string could result in restoring packages from different builds, some of which may be further along than .NET
Core 1.0. This could then result in some packages being incompatible.

Packages and Version Numbers organized by Metapackage
List of all .NET Standard packages and their versions for 1.0.
List of all runtime packages and their versions for 1.0.
List of all .NET Core application packages and their versions for 1.0.

Hosting .NET Core
5/4/2018 • 14 minutes to read • Edit Online

Like all managed code, .NET Core applications are executed by a host. The host is responsible for starting the runtime (including components like the
JIT and garbage collector), creating AppDomains, and invoking managed entry points.
Hosting the .NET Core runtime is an advanced scenario and, in most cases, .NET Core developers don't need to worry about hosting because .NET Core
build processes provide a default host to run .NET Core applications. In some specialized circumstances, though, it can be useful to explicitly host the
.NET Core runtime, either as a means of invoking managed code in a native process or in order to gain more control over how the runtime works.
This article gives an overview of the steps necessary to start the .NET Core runtime from native code, create an initial application domain (AppDomain),
and execute managed code in it.

Prerequisites
Because hosts are native applications, this tutorial will cover constructing a C++ application to host .NET Core. You will need a C++ development
environment (such as that provided by Visual Studio).
You will also want a simple .NET Core application to test the host with, so you should install the .NET Core SDK and build a small .NET Core test app
(such as a 'Hello World' app). The 'Hello World' app created by the new .NET Core console project template is sufficient.
This tutorial and its associated sample build a Windows host; see the notes at the end of this article about hosting on Unix.

Creating the host
A sample host demonstrating the steps outlined in this article is available in the dotnet/samples GitHub repository. Comments in the sample's host.cpp
file clearly associate the numbered steps from this tutorial with where they're performed in the sample. For download instructions, see Samples and
Tutorials.
Keep in mind that the sample host is meant to be used for learning purposes, so it is light on error checking and is designed to emphasize readability
over efficiency. More real-world host samples are available in the dotnet/coreclr repository. The CoreRun host, in particular, is a good general-purpose
host to study after reading through the simpler sample.
A note about mscoree.h
The primary .NET Core hosting interface ( ICLRRuntimeHost2 ) is defined in MSCOREE.IDL. A header version of this file (mscoree.h), which your host will
need to reference, is produced via MIDL when the .NET Core runtime is built. If you do not want to build the .NET Core runtime, mscoree.h is also
available as a pre-built header in the dotnet/coreclr repository. Instructions on building the .NET Core runtime can be found in its GitHub repository.
Step 1 - Identify the managed entry point
After referencing necessary headers (mscoree.h and stdio.h, for example), one of the first things a .NET Core host must do is locate the managed entry
point it will be using. In our sample host, this is done by just taking the first command line argument to our host as the path to a managed binary whose
main method will be executed.
// The managed application to run should be the first command-line parameter.
// Subsequent command line parameters will be passed to the managed app later in this host.
wchar_t targetApp[MAX_PATH];
GetFullPathNameW(argv[1], MAX_PATH, targetApp, NULL);

Step 2 - Find and load CoreCLR.dll
The .NET Core runtime APIs are in CoreCLR.dll (on Windows). To get our hosting interface ( ICLRRuntimeHost2 ), it's necessary to find and load
CoreCLR.dll. It is up to the host to define a convention for how it will locate CoreCLR.dll. Some hosts expect the file to be present in a well-known
machine-wide location (such as %programfiles%\dotnet\shared\Microsoft.NETCore.App\1.1.0). Others expect that CoreCLR.dll will be loaded from a
location next to either the host itself or the app to be hosted. Still others might consult an environment variable to find the library.
On Linux or Mac, the core runtime library is libcoreclr.so or libcoreclr.dylib, respectively.
Our sample host probes a few common locations for CoreCLR.dll. Once found, it must be loaded via

LoadLibrary

(or

dlopen

on Linux/Mac).

HMODULE ret = LoadLibraryExW(coreDllPath, NULL, 0);

Step 3 - Get an ICLRRuntimeHost2 Instance
The ICLRRuntimeHost2 hosting interface is retrieved by calling
function.

GetProcAddress

(or

dlsym

on Linux/Mac) on

GetCLRRuntimeHost

, and then invoking that

ICLRRuntimeHost2* runtimeHost;
FnGetCLRRuntimeHost pfnGetCLRRuntimeHost =
(FnGetCLRRuntimeHost)::GetProcAddress(coreCLRModule, "GetCLRRuntimeHost");
if (!pfnGetCLRRuntimeHost)
{
printf("ERROR - GetCLRRuntimeHost not found");
return -1;
}
// Get the hosting interface
HRESULT hr = pfnGetCLRRuntimeHost(IID_ICLRRuntimeHost2, (IUnknown**)&runtimeHost);

Step 4 - Setting startup flags and starting the runtime
With an ICLRRuntimeHost2 in-hand, we can now specify runtime-wide startup flags and start the runtime. Startup flags will determine which garbage
collector (GC ) to use (concurrent or server), whether we will use a single AppDomain or multiple AppDomains, and what loader optimization policy to
use (for domain-neutral loading of assemblies).
hr = runtimeHost->SetStartupFlags(
// These startup flags control runtime-wide behaviors.
// A complete list of STARTUP_FLAGS can be found in mscoree.h,
// but some of the more common ones are listed below.
static_cast(
// STARTUP_FLAGS::STARTUP_SERVER_GC |
// Use server GC
// STARTUP_FLAGS::STARTUP_LOADER_OPTIMIZATION_MULTI_DOMAIN | // Maximize domain-neutral loading
// STARTUP_FLAGS::STARTUP_LOADER_OPTIMIZATION_MULTI_DOMAIN_HOST | // Domain-neutral loading for strongly-named assemblies
STARTUP_FLAGS::STARTUP_CONCURRENT_GC |
// Use concurrent GC
STARTUP_FLAGS::STARTUP_SINGLE_APPDOMAIN |
// All code executes in the default AppDomain
// (required to use the runtimeHost->ExecuteAssembly helper function)
STARTUP_FLAGS::STARTUP_LOADER_OPTIMIZATION_SINGLE_DOMAIN // Prevents domain-neutral loading
)
);

The runtime is started with a call to the

Start

function.

hr = runtimeHost->Start();

Step 5 - Preparing AppDomain settings
Once the runtime is started, we will want to set up an AppDomain. There are a number of options that must be specified when creating a .NET
AppDomain, however, so it's necessary to prepare those first.
AppDomain flags specify AppDomain behaviors related to security and interop. Older Silverlight hosts used these settings to sandbox user code, but
most modern .NET Core hosts run user code as full trust and enable interop.
int appDomainFlags =
// APPDOMAIN_FORCE_TRIVIAL_WAIT_OPERATIONS | // Do not pump messages during wait
// APPDOMAIN_SECURITY_SANDBOXED |
// Causes assemblies not from the TPA list to be loaded as partially trusted
APPDOMAIN_ENABLE_PLATFORM_SPECIFIC_APPS | // Enable platform-specific assemblies to run
APPDOMAIN_ENABLE_PINVOKE_AND_CLASSIC_COMINTEROP | // Allow PInvoking from non-TPA assemblies
APPDOMAIN_DISABLE_TRANSPARENCY_ENFORCEMENT; // Entirely disables transparency checks

After deciding which AppDomain flags to use, AppDomain properties must be defined. The properties are key/value pairs of strings. Many of the
properties relate to how the AppDomain will load assemblies.
Common AppDomain properties include:
TRUSTED_PLATFORM_ASSEMBLIES This is a list of assembly paths (delimited by ';' on Windows and ':' on Unix) which the AppDomain should prioritize
loading and give full trust to (even in partially-trusted domains). This list is meant to contain 'Framework' assemblies and other trusted modules,
similar to the GAC in .NET Framework scenarios. Some hosts will put any library next to coreclr.dll on this list, others have hard-coded manifests
listing trusted assemblies for their purposes.
APP_PATHS This is a list of paths to probe in for an assembly if it can't be found in the trusted platform assemblies ( TPA ) list. These paths are meant to
be the locations where users' assemblies can be found. In a sandboxed AppDomain, assemblies loaded from these paths will only be granted partial
trust. Common APP_PATH paths include the path the target app was loaded from or other locations where user assets are known to live.
APP_NI_PATHS This list is very similar to APP_PATHS except that it's meant to be paths that will be probed for native images.
NATIVE_DLL_SEARCH_DIRECTORIES This property is a list of paths the loader should probe when looking for native DLLs called via p/invoke.
PLATFORM_RESOURCE_ROOTS This list includes paths to probe in for resource satellite assemblies (in culture-specific sub-directories).
AppDomainCompatSwitch This string specifies which compatibility quirks should be used for assemblies without an explicit Target Framework Moniker
(an assembly-level attribute indicating which Framework an assembly is meant to run against). Typically, this should be set to
"UseLatestBehaviorWhenTFMNotSpecified" but some hosts may prefer to get older Silverlight or Windows Phone compatibility quirks, instead.

In our simple sample host, these properties are set up as follows:
// TRUSTED_PLATFORM_ASSEMBLIES

// TRUSTED_PLATFORM_ASSEMBLIES
// "Trusted Platform Assemblies" are prioritized by the loader and always loaded with full trust.
// A common pattern is to include any assemblies next to CoreCLR.dll as platform assemblies.
// More sophisticated hosts may also include their own Framework extensions (such as AppDomain managers)
// in this list.
int tpaSize = 100 * MAX_PATH; // Starting size for our TPA (Trusted Platform Assemblies) list
wchar_t* trustedPlatformAssemblies = new wchar_t[tpaSize];
trustedPlatformAssemblies[0] = L'\0';
// Extensions to probe for when finding TPA list files
wchar_t *tpaExtensions[] = {
L"*.dll",
L"*.exe",
L"*.winmd"
};
// Probe next to CoreCLR.dll for any files matching the extensions from tpaExtensions and
// add them to the TPA list. In a real host, this would likely be extracted into a separate function
// and perhaps also run on other directories of interest.
for (int i = 0; i < _countof(tpaExtensions); i++)
{
// Construct the file name search pattern
wchar_t searchPath[MAX_PATH];
wcscpy_s(searchPath, MAX_PATH, coreRoot);
wcscat_s(searchPath, MAX_PATH, L"\\");
wcscat_s(searchPath, MAX_PATH, tpaExtensions[i]);
// Find files matching the search pattern
WIN32_FIND_DATAW findData;
HANDLE fileHandle = FindFirstFileW(searchPath, &findData);
if (fileHandle != INVALID_HANDLE_VALUE)
{
do
{
// Construct the full path of the trusted assembly
wchar_t pathToAdd[MAX_PATH];
wcscpy_s(pathToAdd, MAX_PATH, coreRoot);
wcscat_s(pathToAdd, MAX_PATH, L"\\");
wcscat_s(pathToAdd, MAX_PATH, findData.cFileName);
// Check to see if TPA list needs expanded
if (wcslen(pathToAdd) + (3) + wcslen(trustedPlatformAssemblies) >= tpaSize)
{
// Expand, if needed
tpaSize *= 2;
wchar_t* newTPAList = new wchar_t[tpaSize];
wcscpy_s(newTPAList, tpaSize, trustedPlatformAssemblies);
trustedPlatformAssemblies = newTPAList;
}
// Add the assembly to the list and delimited with a semi-colon
wcscat_s(trustedPlatformAssemblies, tpaSize, pathToAdd);
wcscat_s(trustedPlatformAssemblies, tpaSize, L";");
//
//
//
//
//
//
//

Note that the CLR does not guarantee which assembly will be loaded if an assembly
is in the TPA list multiple times (perhaps from different paths or perhaps with different NI/NI.dll
extensions. Therefore, a real host should probably add items to the list in priority order and only
add a file if it's not already present on the list.
For this simple sample, though, and because we're only loading TPA assemblies from a single path,
we can ignore that complication.

}
while (FindNextFileW(fileHandle, &findData));
FindClose(fileHandle);
}
}

// APP_PATHS
// App paths are directories to probe in for assemblies which are not one of the well-known Framework assemblies
// included in the TPA list.
//
// For this simple sample, we just include the directory the target application is in.
// More complex hosts may want to also check the current working directory or other
// locations known to contain application assets.
wchar_t appPaths[MAX_PATH * 50];
// Just use the targetApp provided by the user and remove the file name
wcscpy_s(appPaths, targetAppPath);

// APP_NI_PATHS
// App (NI) paths are the paths that will be probed for native images not found on the TPA list.
// It will typically be similar to the app paths.
// For this sample, we probe next to the app and in a hypothetical directory of the same name with 'NI' suffixed to the end.
wchar_t appNiPaths[MAX_PATH * 50];
wcscpy_s(appNiPaths, targetAppPath);
wcscat_s(appNiPaths, MAX_PATH * 50, L";");
wcscat_s(appNiPaths, MAX_PATH * 50, targetAppPath);
wcscat_s(appNiPaths, MAX_PATH * 50, L"NI");

wcscat_s(appNiPaths, MAX_PATH * 50, L"NI");

// NATIVE_DLL_SEARCH_DIRECTORIES
// Native dll search directories are paths that the runtime will probe for native DLLs called via PInvoke
wchar_t nativeDllSearchDirectories[MAX_PATH * 50];
wcscpy_s(nativeDllSearchDirectories, appPaths);
wcscat_s(nativeDllSearchDirectories, MAX_PATH * 50, L";");
wcscat_s(nativeDllSearchDirectories, MAX_PATH * 50, coreRoot);

// PLATFORM_RESOURCE_ROOTS
// Platform resource roots are paths to probe in for resource assemblies (in culture-specific sub-directories)
wchar_t platformResourceRoots[MAX_PATH * 50];
wcscpy_s(platformResourceRoots, appPaths);

// AppDomainCompatSwitch
// Specifies compatibility behavior for the app domain. This indicates which compatibility
// quirks to apply if an assembly doesn't have an explicit Target Framework Moniker. If a TFM is
// present on an assembly, the runtime will always attempt to use quirks appropriate to the version
// of the TFM.
//
// Typically the latest behavior is desired, but some hosts may want to default to older Silverlight
// or Windows Phone behaviors for compatibility reasons.
wchar_t* appDomainCompatSwitch = L"UseLatestBehaviorWhenTFMNotSpecified";

Step 6 - Create the AppDomain
Once all AppDomain flags and properties are prepared, ICLRRuntimeHost2::CreateAppDomainWithManager can be used to set up the AppDomain. This
function optionally takes a fully qualified assembly name and type name to use as the domain's AppDomain manager. An AppDomain manager can
allow a host to control some aspects of AppDomain behavior and may provide entry points for launching managed code if the host doesn't intend to
invoke user code directly.
DWORD domainId;
// Setup key/value pairs for AppDomain properties
const wchar_t* propertyKeys[] = {
L"TRUSTED_PLATFORM_ASSEMBLIES",
L"APP_PATHS",
L"APP_NI_PATHS",
L"NATIVE_DLL_SEARCH_DIRECTORIES",
L"PLATFORM_RESOURCE_ROOTS",
L"AppDomainCompatSwitch"
};
// Property values which were constructed in step 5
const wchar_t* propertyValues[] = {
trustedPlatformAssemblies,
appPaths,
appNiPaths,
nativeDllSearchDirectories,
platformResourceRoots,
appDomainCompatSwitch
};
// Create the AppDomain
hr = runtimeHost->CreateAppDomainWithManager(
L"Sample Host AppDomain", // Friendly AD name
appDomainFlags,
NULL,
// Optional AppDomain manager assembly name
NULL,
// Optional AppDomain manager type (including namespace)
sizeof(propertyKeys)/sizeof(wchar_t*),
propertyKeys,
propertyValues,
&domainId);

Step 7 - Run managed code!
With an AppDomain up and running, the host can now start executing managed code. The easiest way to do this is to use
ICLRRuntimeHost2::ExecuteAssembly to invoke a managed assembly's entry point method. Note that this function only works in single-domain scenarios.
DWORD exitCode = -1;
hr = runtimeHost->ExecuteAssembly(domainId, targetApp, argc - 1, (LPCWSTR*)(argc > 1 ? &argv[1] : NULL), &exitCode);

Another option, if ExecuteAssembly doesn't meet your host's needs, is to use CreateDelegate to create a function pointer to a static managed method.
This requires the host to know the signature of the method it is calling into (in order to create the function pointer type) but allows hosts the flexibility to
invoke code other than an assembly's entry point.

void *pfnDelegate = NULL;
hr = runtimeHost->CreateDelegate(
domainId,
L"HW, Version=1.0.0.0, Culture=neutral", // Target managed assembly
L"ConsoleApplication.Program",
// Target managed type
L"Main",
// Target entry point (static method)
(INT_PTR*)&pfnDelegate);
((MainMethodFp*)pfnDelegate)(NULL);

Step 8 - Clean up
Finally, the host should clean up after itself by unloading AppDomains, stopping the runtime, and releasing the

ICLRRuntimeHost2

reference.

runtimeHost->UnloadAppDomain(domainId, true /* Wait until unload complete */);
runtimeHost->Stop();
runtimeHost->Release();

About Hosting .NET Core on Unix
.NET Core is a cross-platform product, running on Windows, Linux, and Mac operating systems. As native applications, though, hosts for different
platforms will have some differences between them. The process described above of using ICLRRuntimeHost2 to start the runtime, create an
AppDomain, and execute managed code, should work on any supported operating system. However, the interfaces defined in mscoree.h can be
cumbersome to work with on Unix platforms since mscoree makes many Win32 assumptions.
To make hosting on Unix platforms easier, a set of more platform-neutral hosting API wrappers are available in coreclrhost.h.
An example of using coreclrhost.h (instead of mscoree.h directly) can be seen in the UnixCoreRun host. The steps to use the APIs from coreclrhost.h to
host the runtime are similar to the steps when using mscoree.h:
1. Identify the managed code to execute (from command line parameters, for example).
2. Load the CoreCLR library.
a. dlopen("./libcoreclr.so", RTLD_NOW | RTLD_LOCAL);
3. Get function pointers to CoreCLR's coreclr_initialize , coreclr_create_delegate , coreclr_execute_assembly , and

coreclr_shutdown

functions using

dlsym

a. coreclr_initialize_ptr coreclr_initialize = (coreclr_initialize_ptr)dlsym(coreclrLib, "coreclr_initialize");
4. Set up AppDomain properties (such as the TPA list). This is the same as step 5 from the mscoree workflow, above.
5. Use coreclr_initialize to start the runtime and create an AppDomain. This will also create a hostHandle pointer that will be used in future hosting
calls.
a. Note that this function performs the roles of both steps 4 and 6 from the previous workflow.
6. Use either coreclr_execute_assembly or coreclr_create_delegate to execute managed code. These functions are analogous to mscoree's
ExecuteAssembly and CreateDelegate functions from step 7 of the previous workflow.
7. Use coreclr_shutdown to unload the AppDomain and shut down the runtime.

Conclusion
Once your host is built, it can be tested by running it from the command line and passing any arguments (like the managed app to run) the host expects.
When specifying the .NET Core app for the host to run, be sure to use the .dll that is produced by dotnet build . Executables produced by
dotnet publish for self-contained applications are actually the default .NET Core host (so that the app can be launched directly from the command line
in mainline scenarios); user code is compiled into a dll of the same name.
If things don't work initially, double-check that coreclr.dll is available in the location expected by the host, that all necessary Framework libraries are in
the TPA list, and that CoreCLR's bitness (32- or 64-bit) matches how the host was built.
Hosting the .NET Core runtime is an advanced scenario that many developers won't require, but for those who need to launch managed code from a
native process, or who need more control over the .NET Core runtime's behavior, it can be very useful. Because .NET Core is able to run side-by-side
with itself, it's even possible to create hosts which initialize and start multiple versions of the .NET Core runtime and execute apps on all of them in the
same process.

Create a custom template for dotnet new
5/4/2018 • 7 minutes to read • Edit Online

This tutorial shows you how to:
Create a basic template from an existing project or a new console app project.
Pack the template for distribution at nuget.org or from a local nupkg file.
Install the template from nuget.org, a local nupkg file, or the local file system.
Uninstall the template.
If you prefer to proceed through the tutorial with a complete sample, download the sample project template. The sample template is configured for
NuGet distribution.
If you wish to use the downloaded sample with file system distribution, do the following:
Move the contents of the content folder of the sample up one level into the GarciaSoftware.ConsoleTemplate.CSharp folder.
Delete the empty content folder.
Delete the nuspec file.

Prerequisites
Install the .NET Core 2.0 SDK or later versions.
Read the reference topic Custom templates for dotnet new.

Create a template from a project
Use an existing project that you've confirmed compiles and runs, or create a new console app project in a folder on your hard drive. This tutorial
assumes that the name of the project folder is GarciaSoftware.ConsoleTemplate.CSharp stored at Documents\Templates in the user's profile. The
tutorial project template name is in the format .