Tutorial Document
Tutorial Document
Welcome
.NET Guide
Get Started with .NET
Tour of .NET
.NET Microservices: Architecture for Containerized .NET Applications
.NET Architectural Components
.NET Standard
Target Frameworks
.NET Glossary
Choosing between .NET Core and .NET Framework for server apps
What is "managed code"?
Automatic Memory Management
Common Language Runtime (CLR)
Language Independence
Language Independence and Language-Independent Components
Framework Libraries
Class Library Overview
Base Types
.NET Class libraries
Portability Analyzer
Handling and throwing exceptions
.NET Assembly File Format
Garbage Collection
Generic types
Delegates and lambdas
LINQ
Common Type System & Common Language Specification
Asynchronous programming
Asynchronous programming in depth
Asynchronous Programming Patterns
Native interoperability
Collections and Data Structures
Numerics in .NET
Dates, times, and time zones
Events
Managed Execution Process
Metadata and Self-Describing Components
Building Console Applications
Parallel Processing and Concurrency
Application Essentials
File and Stream I/O
Globalization and Localization
Attributes
Framework Design Guidelines
XML Documents and Data
Threading
Parallel Programming
Security
Serialization
Developing for Multiple Platforms
.NET Core Guide
Get started
Get started with C# and Visual Studio Code
Build a C# Hello World app with .NET Core in Visual Studio 2017
Build a Visual Basic Hello World app with .NET Core in Visual Studio 2017
Build a class library with C# and .NET Core in Visual Studio 2017
Build a class library with Visual Basic and .NET Core in Visual Studio 2017
What's new in .NET Core
Windows Prerequisites
macOS Prerequisites
Linux Prerequisites
Tutorials
Building a complete .NET Core solution on Windows, using Visual Studio 2017
Get Started with C# and Visual Studio Code
Getting started with .NET Core on macOS
Getting started with .NET Core on macOS using Visual Studio for Mac
Building a complete .NET Core solution on macOS using Visual Studio for Mac
Getting started with .NET Core using the CLI tools
Developing Libraries with Cross Platform Tools
Developing ASP.NET Core applications
How to Manage Package Dependency Versions for .NET Core 1.0
Hosting .NET Core from native code
Create a custom template for dotnet new
Packages, Metapackages and Frameworks
Changes in CLI overview
Dependency management
Additions to the csproj format
Migration
Migration to csproj format
Mapping between project.json and csproj
Migrating from DNX
Application Deployment
Deploy apps with CLI tools
Deploy apps with Visual Studio
Creating a NuGet Package with Cross Platform Tools
Runtime package store
Docker
Building Docker Images for .NET Core Applications
Visual Studio Tools for Docker
Unit Testing
Unit testing with dotnet test and xUnit
Unit testing with dotnet test and MSTest
Running selective unit tests
Versioning
.NET Core Support
Runtime IDentifier catalog
.NET Core SDK Overview
.NET Core CLI Tools
Telemetry
Extensibility Model
Continuous Integration
Custom templates
dotnet
dotnet build
dotnet clean
dotnet help
dotnet install-script
dotnet migrate
dotnet msbuild
dotnet new
dotnet nuget delete
dotnet nuget locals
dotnet nuget push
dotnet pack
dotnet publish
dotnet restore
dotnet run
dotnet sln
dotnet store
dotnet test
dotnet vstest
Project modification commands
global.json
Porting from .NET Framework
Organizing projects for .NET Core
Analyzing third-party dependencies
Porting libraries
Build .NET Core from source
.NET Core distribution packaging
VS 2015/project.json docs
.NET Framework Guide
What's New
Get Started
Installation guide
Migration Guide
.NET Framework on Docker Guide
Running Console Apps in Containers
Development Guide
Application Domains and Assemblies
Resources in Desktop Apps
Accessibility
Data and Modeling
Client Applications
Service-Oriented Applications with WCF
Windows Workflow Foundation
Windows Service Applications
64-bit Applications
Web Applications with ASP.NET
Network Programming in the .NET Framework
Configuring Apps
Compiling Apps with .NET Native
Windows Identity Foundation
Debugging, Tracing, and Profiling
Deployment
Performance
Dynamic Programming
Managed Extensibility Framework (MEF)
Add-ins and Extensibility
Interoperating with Unmanaged Code
Unmanaged API Reference
XAML Services
Tools
Additional Class Libraries and APIs
C# Guide
Get Started
Tutorials
Tour of C#
What's new in C#
What's new in C# 7.1
What's new in C# 7
What's new in C# 6
Relationships between language and framework
C# Concepts
C# Type system
Namespaces
Basic Types
Classes
Structs
Tuples
Deconstructing tuples and other types
Interfaces
Methods
Properties
Indexers
Discards
Generics
Iterators
Delegates & events
Language Integrated Query (LINQ)
Asynchronous programming
Pattern Matching
Expression Trees
Native interoperability
Documenting your code
Versioning
C# Programming Guide
Language Reference
Walkthroughs
F# Guide
Tour of F#
Get Started
Get Started with Visual Studio
Get Started with Visual Studio for Mac
Get Started with Visual Studio Code and Ionide
Get Started with with the .NET Core CLI
Tutorials
F# Interactive
Type Providers
Introduction to Functional Programming
Functions as First-Class Values
Asynchronous and Concurrent Programming
Visual F# Development Environment Features
Configuring Projects
Targeting Older Versions of .NET
Using F# on Azure
Get started with Azure Blob storage using F#
Get started with Azure File storage using F#
Get started with Azure Queue storage using F#
Get started with Azure Table storage using F#
Package Management for F# Azure Dependencies
F# Language Reference
Keyword Reference
Symbol and Operator Reference
Functions
Values
Literals
F# Types
Type Inference
Primitive Types
Unit Type
Strings
Tuples
F# Collection Types
Lists
Options
Results
Sequences
Arrays
Generics
Records
Discriminated Unions
Enumerations
Reference Cells
Type Abbreviations
Classes
Structures
Inheritance
Interfaces
Abstract Classes
Members
Type Extensions
Parameters and Arguments
Operator Overloading
Flexible Types
Delegates
Object Expressions
Copy and Update Record Expressions
Casting and Conversions
Access Control
Conditional Expressions: if...then...else
Match Expressions
Pattern Matching
Active Patterns
Loops: for...to Expression
Loops: for...in Expression
Loops: while...do Expression
Assertions
Exception Handling
Attributes
Resource Management: the use Keyword
Namespaces
Modules
Import Declarations: The open Keyword
Signatures
Units of Measure
XML Documentation
Lazy Computations
Computation Expressions
Asynchronous Workflows
Query Expressions
Code Quotations
Fixed keyword
Compiler Directives
Compiler Options
Source Line, File, and Path Identifiers
Caller Information
Verbose Syntax
Code Formatting Guidelines
Visual Basic Guide
Get Started
What's New for Visual Basic
Visual Basic Breaking Changes in Visual Studio
Additional Resources for Visual Basic Programmers
Developing Applications
Programming in Visual Basic
Development with My
Accessing Data
Creating and Using Components
Printing and Reporting
Windows Forms Application Basics
Power Packs Controls
DataRepeater Control
Line and Shape Controls
Customizing Projects and Extending My with Visual Basic
Programming Concepts
Assemblies and the Global Assembly Cache
Asynchronous Programming with Async and Await
Attributes
Expression Trees
Iterators
Language-Integrated Query (LINQ)
Object-Oriented Programming
Reflection
Serialization
Threading
Program Structure and Code Conventions
Structure of a Program
Main Procedure
References and the Imports Statement
Namespaces
Naming Conventions
Coding Conventions
Conditional Compilation
How to: Break and Combine Statements in Code
How to: Collapse and Hide Sections of Code
How to: Label Statements
Special Characters in Code
Comments in Code
Keywords as Element Names in Code
Me, My, MyBase, and MyClass
Limitations
Language Features
Arrays
Collection Initializers
Constants and Enumerations
Control Flow
Data Types
Declared Elements
Delegates
Early and Late Binding
Error Types
Events
Interfaces
LINQ
Objects and Classes
Operators and Expressions
Procedures
Statements
Strings
Variables
XML
COM Interop
Introduction to COM Interop
How to: Reference COM Objects
How to: Work with ActiveX Controls
Walkthrough: Calling Windows APIs
How to: Call Windows APIs
How to: Call a Windows Function that Takes Unsigned Types
Walkthrough: Creating COM Objects
Troubleshooting Interoperability
COM Interoperability in .NET Framework Applications
Walkthrough: Implementing Inheritance with COM Objects
Language Reference
Typographic and Code Conventions
Visual Basic Runtime Library Members
Keywords
Attributes
Constants and Enumerations
Data Type Summary
Directives
Functions
Modifiers
Modules
Nothing
Objects
Operators
Properties
Queries
Statements
XML Comment Tags
XML Axis Properties
XML Literals
Error Messages
Reference
Command-Line Compiler
.NET Framework Reference Information
Language Specification
Sample Applications
Walkthroughs
Samples and Tutorials
Welcome to .NET
8/16/2017 • 1 min to read • Edit Online
See Getting Started with .NET Core to learn how to create .NET Core apps.
Build many types of apps with .NET, such as cloud, IoT, and games using free cross-platform tools. Your apps can
run on Android, iOS, Linux, macOS, and Windows. Deploy apps to servers or desktops and publish to app stores for
deployment on mobile devices. .NET is accessible to students and hobbyists, and all are welcome to participate in a
lively international developer community and make direct contributions to many of the .NET technologies.
News
.NET Core 2.0 Released!
Announcing .NET Core 2.0
Announcing .NET Standard 2.0
Announcing ASP.NET Core 2.0
Announcing Entity Framework Core 2.0
New for Visual Basic: .NET Standard Class Libraries and the dotnet CLI!
Visual Studio 2017 Version 15.3 Released
Introducing .NET Standard
Visual Studio for Mac: now generally available
Announcing Visual Studio 2017 General Availability
What's new for .NET Core and Visual Studio 2017 (video)
Announcing the .NET Framework 4.7
New Features in C# 7.0
Announcing F# 4.1 and the Visual F# Tools for Visual Studio 2017
Open Source Xamarin, Ready for you!
The week in .NET
Build 2017 on Channel 9 - Video on Microsoft's latest technologies and news!
Documentation
This documentation covers the breadth of .NET across platforms and languages. You can get started with .NET and
its languages in any of the following sections:
.NET Guide
.NET Core Guide
.NET Framework Guide
C# Guide
F# Guide
Visual Basic Guide
Additionally, you can browse the .NET API reference.
Open source
ihis documentation is completely open source. You can contribute in any way you like, from creating issues to
writing documentation. Additionally, much of .NET itself is open source:
.NET Core Home
.NET Libraries
.NET Core Runtime
Roslyn (C# and Visual Basic) Compiler Platform and IDE Tools
F# Compiler and IDE Tools
You can join other people who are already active in the .NET community to find out what's new or ask for help.
.NET Guide
7/29/2017 • 1 min to read • Edit Online
The .NET Guide provides a large amount of information about .NET. Depending on your familiarity with .NET, you
may wish to explore different sections of this guide and other sections of the .NET documentation.
New to .NET
If you're new to .NET, check out the Get Started article.
If you prefer to have a guided tour through major features of .NET, check out the Tour of .NET.
You can also read about .NET Architectural Components to get an overview of the various "pieces" of .NET and how
they fit together.
API Reference
Check out the .NET API Reference to see the breadth of APIs avaialable.
Get Started
8/14/2017 • 1 min to read • Edit Online
There are a number of ways to get started with .NET. Because .NET is a massive platform, there are multiple articles
in this documentation which show how you can get started with .NET, each from a different perspective.
.NET is a general purpose development platform. It has several key features, such as support for multiple
programming languages, asynchronous and concurrent programming models, and native interoperability, which
enable a wide range of scenarios across multiple platforms.
This article offers a guided tour through some of the key features of the .NET. See the .NET Architectural
Components topic to learn about the architectural pieces of .NET and what they're used for.
Programming languages
.NET supports multiple programming languages. The .NET implementations implement the Common Language
Infrastructure (CLI), which among other things specifies a language-independent runtime and language
interoperability. This means that you choose any .NET language to build apps and services on .NET.
Microsoft actively develops and supports three .NET languages: C#, F#, and Visual Basic (VB).
C# is simple, powerful, type-safe, and object-oriented, while retaining the expressiveness and elegance of C-
style languages. Anyone familiar with C and similar languages finds few problems in adapting to C#. Check
out the C# Guide to learn more about C#.
F# is a cross-platform, functional-first programming language that also supports traditional object-oriented
and imperative programming. Check out the F# Guide to learn more about F#.
Visual Basic is an easy language to learn that you use to build a variety of apps that run on .NET. Among the
.NET languages, the syntax of VB is the closest to ordinary human language, often making it easier for
people new to software development.
There's no analogous keyword to de-allocate memory, as de-allocation happens automatically when the garbage
collector reclaims the memory through its scheduled run.
The garbage collector is one of the services that help ensure memory safety. A program is memory safe if it
accesses only allocated memory. For instance, the runtime ensures that an app doesn't access unallocated memory
beyond the bounds of an array.
In the following example, the runtime throws an InvalidIndexException exception to enforce memory safety:
using System.IO;
Once the using block completes, the .NET runtime automatically calls the stream object's Dispose() method,
which releases the file handle. The runtime also does this if an exception causes control to leave the block.
For more details, see the following topics:
For C#, see the using Statement (C# Reference) topic.
For F#, see Resource Management: The use Keyword.
For VB, see the Using Statement (Visual Basic) topic.
Type safety
An object is an instance of a specific type. The only operations allowed for a given object are those of its type. A
Dog type may have Jump and WagTail methods but not a SumTotal method. A program only calls the methods
belonging to a given type. All other calls result in either a compile-time error or a run-time exception (in case of
using dynamic features or object ).
.NET languages are object-oriented with hierarchies of base and derived classes. The .NET runtime only allows
object casts and calls that align with the object hierarchy. Remember that every type defined in any .NET language
derives from the base Object type.
Type safety is also used to help enforce encapsulation by guaranteeing the fidelity of the accessor keywords.
Accessor keywords are artifacts which control access to members of a given type by other code. These are usually
used for various kinds of data within a type that are used to manage its behavior.
private Dog _nextDogToBeAdopted = AnimalShelter.AdoptDog()
C#, VB, and F# support local type inference. Type inference means that the compiler deduces the type of the
expression on the left-hand side from the expression on the right-hand side. This doesn't mean that the type safety
is broken or avoided. The resulting type does have a strong type with everything that implies. From the previous
example, dog and cat are rewritten to introduce type inference, and the remainder of the example is unchanged:
F# has even further type inference capabilities than the method-local type inference found in C# and VB. To learn
more, see Type Inference.
Generics
Generics allow the programmer to introduce a type parameter when designing their classes that allows the client
code (the users of the type) to specify the exact type to use in place of the type parameter.
Generics were added to help programmers implement generic data structures. Before their arrival in order for a
type such as the List type to be generic, it would have to work with elements that were of type object . This had
various performance and semantic problems, along with possible subtle runtime errors. The most notorious of the
latter is when a data structure contains, for instance, both integers and strings, and an InvalidCastException is
thrown on working with the list's members.
The following sample shows a basic program running using an instance of List<T> types:
using System;
using System.Collections.Generic;
namespace GenericsSampleShort
{
public static void Main(string[] args)
{
// List<string> is the client way of specifying the actual type for the type parameter T
List<string> listOfStrings = new List<string> { "First", "Second", "Third" };
For more information, see the Generic types (Generics) overview topic.
Async programming
Async programming is a first-class concept within .NET with async support in the runtime, framework libraries, and
.NET language constructs. Internally, they're based on objects (such as Task ), which take advantage of the
operating system to perform I/O-bound jobs as efficiently as possible.
To learn more about async programming in .NET, start with the Async overview topic.
Native interoperability
Every operating system includes an application programming interface (API) that provides system services. .NET
provides several ways to call those APIs.
The main way to do native interoperability is via "platform invoke" or P/Invoke for short, which is supported across
Linux and Windows platforms. A Windows-only way of doing native interoperability is known as "COM interop,"
which is used to work with COM components in managed code. It's built on top of the P/Invoke infrastructure, but
it works in subtly different ways.
Most of Mono's (and thus Xamarin's) interoperability support for Java and Objective-C are built similarly, that is,
they use the same principles.
Read more about it native interoperability in the Native interoperability topic.
Unsafe code
Depending on language support, the CLR lets you access native memory and do pointer arithmetic via unsafe
code. These operations are needed for certain algorithms and system interoperability. Although powerful, use of
unsafe code is discouraged unless it's necessary to interop with system APIs or implement the most efficient
algorithm. Unsafe code may not execute the same way in different environments and also loses the benefits of a
garbage collector and type safety. It's recommended to confine and centralize unsafe code as much as possible and
test that code thoroughly.
The following example is a modified version of the ToString() method from the StringBuilder class. It illustrates
how using unsafe code can efficiently implement an algorithm by moving around chunks of memory directly:
Next steps
If you're interested in a tour of C# features, check out Tour of C#.
If you're interested in a tour of F# features, see Tour of F#.
If you want to get started with writing code of your own, visit Getting Started.
To learn about important components of .NET, check out .NET Architectural Components.
7/29/2017 • 5 min to read • Edit Online
Editors:
Mike Pope
Steve Hoag
Introduction
Enterprises are increasingly realizing cost savings, solving deployment problems, and improving DevOps and
production operations by using containers. Microsoft has been releasing container innovations for Windows and
Linux by creating products like Azure Container Service and Azure Service Fabric, and by partnering with industry
leaders like Docker, Mesosphere, and Kubernetes. These products deliver container solutions that help companies
build and deploy applications at cloud speed and scale, whatever their choice of platform or tools.
Docker is becoming the de facto standard in the container industry, supported by the most significant vendors in
the Windows and Linux ecosystems. (Microsoft is one of the main cloud vendors supporting Docker.) In the future,
Docker will probably be ubiquitous in any datacenter in the cloud or on-premises.
In addition, the microservices architecture is emerging as an important approach for distributed mission-critical
applications. In a microservice-based architecture, the application is built on a collection of services that can be
developed, tested, deployed, and versioned independently.
NEXT
.NET architectural components
8/24/2017 • 4 min to read • Edit Online
A .NET app is developed for and runs in one or more implementations of .NET. Implementations of .NET include
the .NET Framework, .NET Core, and Mono. There is an API specification common to all implementations of .NET
that's called the .NET Standard. This article gives a brief introduction to each of these concepts.
.NET Standard
The .NET Standard is a set of APIs that are implemented by the Base Class Library of a .NET implementation. More
formally, it's a specification of .NET APIs that make up a uniform set of contracts that you compile your code
against. These contracts are implemented in each .NET implementation. This enables portability across different
.NET implementations, effectively allowing your code to run everywhere.
The .NET Standard is also a target framework. If your code targets a version of the .NET Standard, it can run on any
.NET implementation which supports that version of the .NET Standard.
To learn more about the .NET Standard and how to target it, see the .NET Standard topic.
.NET implementations
Each implementation of .NET includes the following components:
One or more runtimes. Examples: CLR for .NET Framework, CoreCLR and CoreRT for .NET Core.
A class library that implements the .NET Standard and may implement additional APIs. Examples: .NET
Framework Base Class Library, .NET Core Base Class Library.
Optionally, one or more application frameworks. Examples: ASP.NET, Windows Forms, and Windows
Presentation Foundation (WPF) are included in the .NET Framework.
Optionally, development tools. Some development tools are shared among multiple implementations.
There are four primary .NET implementations that Microsoft actively develops and maintains: .NET Core, .NET
Framework, Mono, and UWP.
.NET Core
.NET Core is a cross-platform implementation of .NET and designed to handle server and cloud workloads at scale.
It runs on Windows, macOS and Linux. It implements the .NET Standard, so code that targets the .NET Standard
can run on .NET Core. ASP.NET Core runs on .NET Core.
To learn more about .NET Core, see the .NET Core Guide and Choosing between .NET Core and .NET Framework
for server apps.
.NET Framework
The.NET Framework is the original .NET implementation that has existed since 2002. It's the same .NET Framework
that existing .NET developers have always used. Versions 4.5 and later implement the .NET Standard, so code that
targets the .NET Standard can run on those versions of the .NET Framework. It contains additional Windows-
specific APIs, such as APIs for Windows desktop development with Windows Forms and WPF. The .NET
Framework is optimized for building Windows desktop applications.
To learn more about the .NET Framework, see the .NET Framework Guide.
Mono
Mono is a .NET implementation that is mainly used when a small runtime is required. It is the runtime that powers
Xamarin applications on Android, Mac, iOS, tvOS and watchOS and is focused primarily on a small footprint.
It supports all of the currently published .NET Standard versions.
Historically, Mono implemented the larger API of the .NET Framework and emulated some of the most popular
capabilities on Unix. It is sometimes used to run .NET applications that rely on those capabilities on Unix.
Mono is typically used with a just-in-time compiler, but it also features a full static compiler (ahead-of-time
compilation) that is used on platforms like iOS.
To learn more about Mono, see the Mono documentation.
Universal Windows Platform (UWP)
UWP is an implementation of .NET that is used for building modern, touch-enabled Windows applications and
software for the Internet of Things (IoT). It's designed to unify the different types of devices that you may want to
target, including PCs, tablets, phablets, phones, and even the Xbox. UWP provides many services, such as a
centralized app store, an execution environment (AppContainer), and a set of Windows APIs to use instead of
Win32 (WinRT). Apps can be written in C++, C#, VB.NET, and JavaScript. When using C# and VB.NET, the .NET APIs
are provided by .NET Core.
To learn more about UWP, see Intro to the Universal Windows Platform.
.NET runtimes
A runtime is the execution environment for a managed program. The OS is part of the runtime environment but is
not part of the .NET runtime. Here are some examples of .NET runtimes:
Common Language Runtime (CLR) for the .NET Framework
Core Common Language Runtime (CoreCLR) for .NET Core
.NET Native for Universal Windows Platform
The Mono runtime for Xamarin.iOS, Xamarin.Android, Xamarin.Mac, and the Mono desktop framework
See also
Choosing between .NET Core and .NET Framework for server apps
.NET Standard
.NET Core Guide
.NET Framework Guide
C# Guide
F# Guide
VB.NET Guide
.NET Standard
8/15/2017 • 7 min to read • Edit Online
The .NET Standard is a formal specification of .NET APIs that are intended to be available on all .NET
implementations. The motivation behind the .NET Standard is establishing greater uniformity in the .NET
ecosystem. ECMA 335 continues to establish uniformity for .NET implementation behavior, but there is no
similar spec for the .NET Base Class Libraries (BCL) for .NET library implementations.
The .NET Standard enables the following key scenarios:
Defines uniform set of BCL APIs for all .NET implementations to implement, independent of workload.
Enables developers to produce portable libraries that are usable across .NET implementations, using this
same set of APIs.
Reduces or even eliminates conditional compilation of shared source due to .NET APIs, only for OS APIs.
The various .NET implementations target specific versions of .NET Standard. Each .NET implementation version
advertises the highest .NET Standard version it supports, a statement that means it also supports previous
versions. For example, the .NET Framework 4.6 implements .NET Standard 1.3, which means that it exposes all
APIs defined in .NET Standard versions 1.0 through 1.3. Similarly, the .NET Framework 4.6.1 implements .NET
Standard 1.4, while .NET Core 1.0 implements .NET Standard 1.6.
.NET
STANDAR
D 1.0 1.1 1.2 1.3 1.4 1.5 1.6 2.0
.NET Core 1.0 1.0 1.0 1.0 1.0 1.0 1.0 2.0
Windows 8.0
Phone
Silverlight
The columns represent .NET Standard versions. Each header cell is a link to a document that shows which
APIs got added in that version of .NET Standard.
The rows represent the different .NET implementations.
The version number in each cell indicates the minimum version of the implementation you'll need in order to
target that .NET Standard version.
To find the highest version of .NET Standard that you can target, do the following:
1. Find the row that indicate the .NET implementation you want to run on.
2. Find the column in that row that indicates your version starting from right to left.
3. The column header indicates the .NET Standard version that your target supports (and any lower .NET
Standard versions will also support it).
4. Repeat this process for each platform you want to target. If you have more than one target platform, you
should pick the smaller version among them. For example, if you want to run on .NET Framework 4.5 and
.NET Core 1.0, the highest .NET Standard version you can use is .NET Standard 1.1.
Which .NET Standard version to target
When choosing a .NET Standard version, you should consider this trade-off:
The higher the version, the more APIs are available to you.
The lower the version, the more platforms implement it.
In general, we recommend you to target the lowest version of .NET Standard possible. So, after you find the
highest .NET Standard version you can target, follow these steps:
1. Target the next lower version of .NET Standard and build your project.
2. If your project builds successfully, repeat step 1. Otherwise, retarget to the next higher version and that's the
version you should use.
.NET Standard versioning rules
There are two primary versioning rules:
Additive: .NET Standard versions are logically concentric circles: higher versions incorporate all APIs from
previous versions. There are no breaking changes between versions.
Immutable. Once shipped, .NET Standard versions are frozen. New APIs will first become available in specific
.NET implementations, such as .NET Core. If the .NET Standard review board believes the new APIs should be
made available everywhere, they'll be added in a new .NET Standard version.
Specification
The .NET Standard specification is a standardized set of APIs. The specification is maintained by .NET
implementors, specifically Microsoft (includes .NET Framework, .NET Core and Mono) and Unity. A public
feedback process is used as part of establishing new .NET Standard versions through GitHub.
Official artifacts
The official specification is a set of .cs files that define the APIs that are part of the standard. The ref directory in
the dotnet/standard repository defines the .NET Standard APIs.
The NETStandard.Library metapackage (source) describes the set of libraries that define (in part) one or more
.NET Standard versions.
A given component, like System.Runtime, describes:
Part of .NET Standard (just its scope).
Multiple versions of .NET Standard, for that scope.
Derivative artifacts are provided to enable more convenient reading and to enable certain developer scenarios
(for example, using a compiler).
API list in markdown
Reference assemblies, distributed as NuGet packages and referenced by the NETStandard.Library
metapackage.
Package representation
The primary distribution vehicle for the .NET Standard reference assemblies is NuGet packages.
Implementations will be delivered in a variety of ways, appropriate for each .NET implementation.
NuGet packages target one or more frameworks. The .NET Standard packages target the ".NET Standard"
framework. You can target the .NET Standard Framework using the netstandard compact TFM (for example,
netstandard1.4 ). Libraries that are intended to run on multiple runtimes should target this framework.
The NETStandard.Library metapackage references the complete set of NuGet packages that define .NET
Standard. The most common way to target netstandard is by referencing this metapackage. It describes and
provides access to the ~40 .NET libraries and associated APIs that define .NET Standard. You can reference
additional packages that target netstandard to get access to additional APIs.
Versioning
The specification is not singular, but an incrementally growing and linearly versioned set of APIs. The first
version of the standard establishes a baseline set of APIs. Subsequent versions add APIs and inherit APIs defined
by previous versions. There is no established provision for removing APIs from the standard.
.NET Standard is not specific to any one .NET implementation, nor does it match the versioning scheme of any of
those runtimes.
APIs added to any of the implementations (such as, .NET Framework, .NET Core and Mono) can be considered as
candidates to add to the specification, particularly if they are thought to be fundamental in nature. New versions
of .NET Standard are created based on .NET implementation releases, enabling you to target new APIs from a
.NET Standard PCL. The versioning mechanics are described in more detail in .NET Core Versioning.
.NET Standard versioning is important for usage. Given a .NET Standard version, you can use libraries that target
that same or lower version. The following approach describes the workflow for using .NET Standard PCLs,
specific to .NET Standard targeting.
Select a .NET Standard version to use for your PCL.
Use libraries that depend on the same .NET Standard version or lower.
If you find a library that depends on a higher .NET Standard version, you either need to adopt that same
version or decide not to use that library.
PCL compatibility
.NET Standard is compatible with a subset of PCL profiles. .NET Standard 1.0, 1.1 and 1.2 each overlap with a set
of PCL profiles. This overlap was created for two reasons:
Enable .NET Standard-based PCLs to reference profile-based PCLs.
Enable profile-based PCLs to be packaged as .NET Standard-based PCLs.
Profile-based PCL compatibility is provided by the Microsoft.NETCore.Portable.Compatibility NuGet package.
This dependency is required when referencing NuGet packages that contain profile-based PCLs.
Profile-based PCLs packaged as netstandard are easier to consume than typically packaged profile-based PCLs.
netstandard packaging is compatible with existing users.
You can see the set of PCL profiles that are compatible with the .NET Standard:
See also
.NET Standard Versions
Target frameworks
8/26/2017 • 4 min to read • Edit Online
When you target a framework in an app or library, you're specifying the set of APIs that you'd like to make
available to the app or library. You specify the target framework in your project file using Target Framework
Monikers (TFMs).
An app or library can target a version of .NET Standard. .NET Standard versions represent standardized sets of
APIs across all .NET implementations. For example, a library can target .NET Standard 1.6 and gain access to
APIs that function across .NET Core and .NET Framework using the same codebase.
An app or library can also target a specific .NET implementation to gain access to implementation-specific APIs.
For example, an app that targets Xamarin.iOS (for example, Xamarin.iOS10 ) gets access to Xamarin-provided
iOS API wrappers for iOS 10, or an app that targets the Universal Windows Platform (UWP, uap10.0 ) has
access to APIs that compile for devices that run Windows 10.
For some target frameworks (for example, the .NET Framework), the APIs are defined by the assemblies that the
framework installs on a system and may include application framework APIs (for example, ASP.NET).
For package-based target frameworks (for example, .NET Standard and .NET Core), the APIs are defined by the
packages included in the app or library. A metapackage is a NuGet package that has no content of its own but
is a list of dependencies (other packages). A NuGet package-based target framework implicitly specifies a
metapackage that references all the packages that together make up the framework.
Silverlight sl4
sl5
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp2.0</TargetFramework>
</PropertyGroup>
</Project>
When you specify multiple target frameworks, you may conditionally reference assemblies for each target
framework. In your code, you can conditionally compile against those assemblies by using preprocessor
symbols with if-then-else logic.
The following library project file targets APIs of .NET Standard ( netstandard1.4 ) and APIs of the .NET
Framework ( net40 and net45 ). Use the plural TargetFrameworks element with multiple target frameworks.
Note how the Condition attributes include implementation-specific packages when the library is compiled for
the two .NET Framework TFMs:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>netstandard1.4;net40;net45</TargetFrameworks>
</PropertyGroup>
<!-- Conditionally obtain references for the .NET Framework 4.0 target -->
<ItemGroup Condition=" '$(TargetFramework)' == 'net40' ">
<Reference Include="System.Net" />
</ItemGroup>
<!-- Conditionally obtain references for the .NET Framework 4.5 target -->
<ItemGroup Condition=" '$(TargetFramework)' == 'net45' ">
<Reference Include="System.Net.Http" />
<Reference Include="System.Threading.Tasks" />
</ItemGroup>
</Project>
Within your library or app, you write conditional code to compile for each target framework:
The build system is aware of preprocessor symbols representing the target frameworks shown in the
Supported target framework versions table. When using a symbol that represents a .NET Standard or .NET Core
TFM, replace the dot with an underscore and change lowercase letters to uppercase (for example, the symbol
for netstandard1.4 is NETSTANDARD1_4 ).
The complete list of preprocessor symbols for .NET Core target frameworks is:
TARGET FRAMEWORKS SYMBOLS
aspnet50 netcoreapp
aspnetcore50
dnxcore50
dnx
dnx45
dnx451
dnx452
dotnet netstandard
dotnet50
dotnet51
dotnet52
dotnet53
dotnet54
dotnet55
dotnet56
netcore50 uap10.0
win netcore45
win8 netcore45
win81 netcore451
win10 uap10.0
winrt netcore45
See also
Packages, Metapackages and Frameworks
Developing Libraries with Cross Platform Tools
.NET Standard
.NET Core Versioning
dotnet/standard GitHub repository
NuGet Tools GitHub Repository
Framework Profiles in .NET
.NET Glossary
8/14/2017 • 10 min to read • Edit Online
The primary goal of this glossary is to clarify meanings of selected terms and acronyms that appear frequently in
the .NET documentation without definitions.
AOT
Ahead-of-time compiler.
Similar to JIT, this compiler also translates IL to machine code. In contrast to JIT compilation, AOT compilation
happens before the application is executed and is usually performed on a different machine. Because AOT tool
chains don't compile at runtime, they don't have to minimize time spent compiling. That means they can spend
more time optimizing. Since the context of AOT is the entire application, the AOT compiler also performs cross-
module linking and whole-program analysis, which means that all references are followed and a single executable
is produced.
ASP.NET
The original ASP.NET implementation that ships with the .NET Framework.
Sometimes ASP.NET is an umbrella term that refers to both ASP.NET implementations including ASP.NET Core. The
meaning that the term carries in any given instance is determined by context.
See ASP.NET.
ASP.NET Core
A cross-platform, high-performance, open source implementation of ASP.NET built on .NET Core.
See ASP.NET Core.
assembly
A .dll file that contains a collection of APIs that can be called by apps or other assemblies.
A .NET assembly is a collection of types. An assembly includes interfaces, classes, structures, enumerations, and
delegates. Assemblies in a project's bin folder are sometimes referred to as binaries. See also library.
CLR
Common Language Runtime.
The exact meaning depends on the context, but this usually refers to the runtime of the .NET Framework. The CLR
handles memory allocation and management. The CLR is also a virtual machine that not only executes apps but
also generates and compiles code on-the-fly using a JIT compiler. The current Microsoft CLR implementation is
Windows only.
CoreCLR
.NET Core Common Language Runtime.
This CLR is built from the same code base as the CLR. Originally, CoreCLR was the runtime of Silverlight and was
designed to run on multiple platforms, specifically Windows and OS X. CoreCLR is now part of .NET Core and
represents a simplified version of the CLR. It's still a cross platform runtime, now including support for many Linux
distributions. CoreCLR is also a virtual machine with JIT and code execution capabilities.
CoreFX
.NET Core Base Class Library (BCL)
A set of libraries that comprise the System.* (and to a limited extent Microsoft.*) namespaces. The BCL is a general
purpose, lower-level framework that higher-level application frameworks, such as ASP.NET Core, build on. The
source code of the .NET Core BCL is contained in the CoreFX repository. However, the majority of the .NET Core
APIs are also available in the .NET Framework, so you can think of CoreFX as a fork of the .NET Framework BCL.
CoreRT
.NET Core runtime.
In contrast to the CLR/CoreCLR, CoreRT is not a virtual machine, which means it doesn't include the facilities to
generate and run code on-the-fly because it doesn't include a JIT. It does, however, include the GC and the ability
for runtime type identification (RTTI) and reflection. However, its type system is designed so that metadata for
reflection isn't required. This enables having an AOT tool chain that can link away superfluous metadata and (more
importantly) identify code that the app doesn't use. CoreRT is in development.
See Intro to .NET Native and CoreRT
ecosystem
All of the runtime software, development tools, and community resources that are used to build and run
applications for a given technology.
The term ".NET ecosystem" differs from similar terms such as ".NET stack" in its inclusion of third-party apps and
libraries. Here's an example in a sentence:
"The motivation behind the .NET Standard is to establish greater uniformity in the .NET ecosystem."
framework
In general, a comprehensive collection of APIs that facilitates development and deployment of applications that are
based on a particular technology. In this general sense, ASP.NET Core and Windows Forms are examples of
application frameworks. See also library.
The word "framework" has a more specific technical meaning in the following terms:
.NET Framework
target framework
TFM (target framework moniker)
In the existing documentation, "framework" sometimes refers to an implementation of .NET. For example, an article
may call .NET Core a framework. We plan to eliminate this confusing usage from the documentation.
GC
Garbage collector.
The garbage collector is an implementation of automatic memory management. The GC frees memory occupied by
objects that are no longer in use.
See Garbage Collection.
IL
Intermediate language.
Higher-level .NET languages, such as C#, compile down to a hardware-agnostic instruction set, which is called
Intermediate Language (IL). IL is sometimes referred to as MSIL (Microsoft IL) or CIL (Common IL).
JIT
Just-in-time compiler.
Similar to AOT, this compiler translates IL to machine code that the processor understands. Unlike AOT, JIT
compilation happens on demand and is performed on the same machine that the code needs to run on. Since JIT
compilation occurs during execution of the application, compile time is part of the run time. Thus, JIT compilers
have to balance time spent optimizing code against the savings that the resulting code can produce. But a JIT knows
the actual hardware and can free developers from having to ship different implementations.
implementation of .NET
An implementation of .NET includes the following:
One or more runtimes. Examples: CLR, CoreCLR, CoreRT.
A class library that implements a version of the .NET Standard and may include additional APIs. Examples: .NET
Framework Base Class Library, .NET Core Base Class Library.
Optionally, one or more application frameworks. Examples: ASP.NET, Windows Forms, and WPF are included in
the .NET Framework.
Optionally, development tools. Some development tools are shared among multiple implementations.
Examples of .NET implementations:
.NET Framework
.NET Core
Universal Windows Platform (UWP)
library
A collection of APIs that can be called by apps or other libraries. A .NET library is composed of one or more
assemblies.
The words library and framework are often used synonymously.
metapackage
A NuGet package that has no library of its own but is only a list of dependencies. The included packages can
optionally establish the API for a target framework.
See Packages, Metapackages and Frameworks
Mono
An open source alternative to the .NET Framework.
Mono started around the same time the .NET Framework was first released. Since the .NET Framework wasn't open
source, Mono was forced to start from scratch and is thus a complete re-implementation of the .NET Framework
with no shared code.
When .NET Core was released under the MIT license, Microsoft also released large chunks of the .NET Framework
under the MIT license as well. This enabled the Mono community to use the same code the .NET Framework uses in
order to close gaps and avoid behavioral differences.
Mono is primarily used to run .NET applications on Linux and macOS. There are ports of Mono to other platforms;
see Mono's Supported Platforms. Mono has implementations (though not necessarily complete) of WinForms,
ASP.NET, and System.Drawing .
.NET
The umbrella term for .NET Standard and all .NET implementations and workloads. Always capitalized, never ".Net".
See the .NET Guide
.NET Core
A cross-platform, high-performance, open source implementation of .NET. Includes the Core Common Language
Runtime (CoreCLR), the Core AOT Runtime (CoreRT, in development), the Core Base Class Library, and the Core
SDK.
See .NET Core.
.NET Framework
An implementation of .NET that runs only on Windows. Includes the Common Language Runtime (CLR), the Base
Class Library, and application framework libraries such as ASP.NET, Windows Forms, and WPF.
See .NET Framework Guide.
.NET Native
A compiler tool chain that produces native code ahead-of-time (AOT), as opposed to just-in-time (JIT).
Compilation happens on the developer's machine similar to the way a C++ compiler and linker works. It removes
unused code and spends more time optimizing it. It extracts code from libraries and merges them into the
executable. The result is a single module that represents the entire app.
UWP was the first application framework supported by .NET Native. Now, we support building native console apps
for Windows, macOS, and Linux.
See Intro to .NET Native and CoreRT
.NET Standard
A formal specification of .NET APIs that are available in each .NET implementation.
The .NET Standard specification is sometimes called a library in the documentation. Because a library includes API
implementations, not only specifications (interfaces), it's misleading to call .NET Standard a "library." We plan to
eliminate that usage from the documentation, except in reference to the name of the .NET Standard metapackage (
NETStandard.Library ).
NGEN
Native (image) generation.
You can think of this technology as a persistent JIT compiler. It usually compiles code on the machine where the
code is executed, but compilation typically occurs at install time.
package
A NuGet package — or just a package — is a .zip file with one or more assemblies of the same name along with
additional metadata such as the author name.
The .zip file has a .nupkg extension and may contain assets, such as .dll files and .xml files, for use with multiple
frameworks and versions. When installed in an app or library, the appropriate assets are selected based on the
target framework specified by the app or library. The assets that define the interface are in the ref folder, and the
assets that define the implementation are in the lib folder.
platform
An operating system and the hardware it runs on, such as Windows, macOS, Linux, iOS, and Android.
Here are examples of usage in sentences:
".NET Core is a cross-platform implementation of .NET."
"PCL profiles represent Microsoft platforms, while the .NET Standard is agnostic to platform."
The .NET documentation frequently uses ".NET platform" to mean either an implementation of .NET or the .NET
stack including all implementations. Both of these usages tend to get confused with the primary (OS/hardware)
meaning, so we plan to eliminate these usages from the documentation.
runtime
The execution environment for a managed program.
The OS is part of the runtime environment but is not part of the .NET runtime. Here are some examples of .NET
runtimes:
Common Language Runtime (CLR)
Core Common Language Runtime (CoreCLR)
.NET Native (for UWP)
Mono runtime
The .NET documentation sometimes uses "runtime" to mean an implementation of .NET. For example, in the
following sentences "runtime" should be replaced with "implementation":
"The various .NET runtimes implement specific versions of .NET Standard."
"Libraries that are intended to run on multiple runtimes should target this framework." (referring to .NET
Standard)
"The various .NET runtimes implement specific versions of .NET Standard. … Each .NET runtime version
advertises the highest .NET Standard version it supports …"
We plan to eliminate this inconsistent usage.
stack
A set of programming technologies that are used together to build and run applications.
"The .NET stack" refers to the .NET Standard and all .NET implementations. The phrase "a .NET stack" may refer to
one implementation of .NET.
target framework
The collection of APIs that a .NET app or library relies on.
An app or library can target a version of .NET Standard (for example, .NET Standard 2.0), which is specification for a
standardized set of APIs across all .NET implementations. An app or library can also target a version of a specific
.NET implementation, in which case it gets access to implementation-specific APIs. For example, an app that targets
Xamarin.iOS gets access to Xamarin-provided iOS API wrappers.
For some target frameworks (for example, the .NET Framework) the available APIs are defined by the assemblies
that a .NET implementation installs on a system, which may include application framework APIs (for example,
ASP.NET, WinForms). For package-based target frameworks (such as .NET Standard and .NET Core), the framework
APIs are defined by the packages installed in the app or library. In that case, the target framework implicitly
specifies a metapackage that references all the packages that together make up the framework.
See Target Frameworks.
TFM
Target framework moniker.
A standardized token format for specifying the target framework of a .NET app or library. Target frameworks are
typically referenced by a short name, such as net462 . Long-form TFMs (such as .NETFramework,Version=4.6.2)
exist but are not generally used to specify a target framework.
See Target Frameworks.
UWP
Universal Windows Platform.
An implementation of .NET that is used for building modern, touch-enabled Windows applications and software for
the Internet of Things (IoT). It's designed to unify the different types of devices that you may want to target,
including PCs, tablets, phablets, phones, and even the Xbox. UWP provides many services, such as a centralized app
store, an execution environment (AppContainer), and a set of Windows APIs to use instead of Win32 (WinRT). Apps
can be written in C++, C#, VB.NET, and JavaScript. When using C# and VB.NET, the .NET APIs are provided by .NET
Core.
See also
.NET Guide
.NET Framework Guide
.NET Core
ASP.NET Overview
ASP.NET Core Overview
Choosing between .NET Core and .NET Framework
for server apps
8/17/2017 • 6 min to read • Edit Online
There are two supported implementations for building server-side applications with .NET: .NET Framework and
.NET Core. Both share many of the same components and you can share code across the two. However, there are
fundamental differences between the two and your choice depends on what you want to accomplish. This article
provides guidance on when to use each.
Use .NET Core for your server application when:
You have cross-platform needs.
You are targeting microservices.
You are using Docker containers.
You need high-performance and scalable systems.
You need side-by-side .NET versions per application.
Use .NET Framework for your server application when:
Your app currently uses .NET Framework (recommendation is to extend instead of migrating).
Your app uses third-party .NET libraries or NuGet packages not available for .NET Core.
Your app uses .NET technologies that aren't available for .NET Core.
Your app uses a platform that doesn’t support .NET Core.
See also
Choose between ASP.NET and ASP.NET Core
.NET Core Guide
Porting from .NET Framework to .NET Core
.NET Framework on Docker Guide
.NET Components Overview
.NET Microservices. Architecture for Containerized .NET Applications
What is "managed code"?
8/5/2017 • 2 min to read • Edit Online
When working with .NET Framework, you will often encounter the term "managed code". This document will
explain what this term means and additional information around it.
To put it very simply, managed code is just that: code whose execution is managed by a runtime. In this case, the
runtime in question is called the Common Language Runtime or CLR, regardless of the implementation (Mono
or .NET Framework or .NET Core). CLR is in charge of taking the managed code, compiling it into machine code and
then executing it. On top of that, runtime provides several important services such as automatic memory
management, security boundaries, type safety etc.
Contrast this to the way you would run a C/C++ program, also called "unmanaged code". In the unmanaged world,
the programmer is in charge of pretty much everything. The actual program is, essentially, a binary that the
operating system (OS) loads into memory and starts. Everything else, from memory management to security
considerations are a burden of the programmer.
Managed code is written in one of the high-level languages that can be run on top of .NET, such as C#, Visual Basic,
F# and others. When you compile code written in those languages with their respective compiler, you don’t get
machine code. You get Intermediate Language code which the runtime then compiles and executes. C++ is the
one exception to this rule, as it can also produce native, unmanaged binaries that run on Windows.
More resources
.NET Framework Conceptual Overview
Unsafe Code and Pointers
Interoperability (C# Programming guide)
Automatic Memory Management
7/29/2017 • 7 min to read • Edit Online
Automatic memory management is one of the services that the Common Language Runtime provides during
Managed Execution. The Common Language Runtime's garbage collector manages the allocation and release of
memory for an application. For developers, this means that you do not have to write code to perform memory
management tasks when you develop managed applications. Automatic memory management can eliminate
common problems, such as forgetting to free an object and causing a memory leak, or attempting to access
memory for an object that has already been freed. This section describes how the garbage collector allocates and
releases memory.
Allocating Memory
When you initialize a new process, the runtime reserves a contiguous region of address space for the process. This
reserved address space is called the managed heap. The managed heap maintains a pointer to the address where
the next object in the heap will be allocated. Initially, this pointer is set to the managed heap's base address. All
reference types are allocated on the managed heap. When an application creates the first reference type, memory is
allocated for the type at the base address of the managed heap. When the application creates the next object, the
garbage collector allocates memory for it in the address space immediately following the first object. As long as
address space is available, the garbage collector continues to allocate space for new objects in this manner.
Allocating memory from the managed heap is faster than unmanaged memory allocation. Because the runtime
allocates memory for an object by adding a value to a pointer, it is almost as fast as allocating memory from the
stack. In addition, because new objects that are allocated consecutively are stored contiguously in the managed
heap, an application can access the objects very quickly.
Releasing Memory
The garbage collector's optimizing engine determines the best time to perform a collection based on the
allocations being made. When the garbage collector performs a collection, it releases the memory for objects that
are no longer being used by the application. It determines which objects are no longer being used by examining the
application's roots. Every application has a set of roots. Each root either refers to an object on the managed heap or
is set to null. An application's roots include static fields, local variables and parameters on a thread's stack, and CPU
registers. The garbage collector has access to the list of active roots that the just-in-time (JIT) compiler and the
runtime maintain. Using this list, it examines an application's roots, and in the process creates a graph that contains
all the objects that are reachable from the roots.
Objects that are not in the graph are unreachable from the application's roots. The garbage collector considers
unreachable objects garbage and will release the memory allocated for them. During a collection, the garbage
collector examines the managed heap, looking for the blocks of address space occupied by unreachable objects. As
it discovers each unreachable object, it uses a memory-copying function to compact the reachable objects in
memory, freeing up the blocks of address spaces allocated to unreachable objects. Once the memory for the
reachable objects has been compacted, the garbage collector makes the necessary pointer corrections so that the
application's roots point to the objects in their new locations. It also positions the managed heap's pointer after the
last reachable object. Note that memory is compacted only if a collection discovers a significant number of
unreachable objects. If all the objects in the managed heap survive a collection, then there is no need for memory
compaction.
To improve performance, the runtime allocates memory for large objects in a separate heap. The garbage collector
automatically releases the memory for large objects. However, to avoid moving large objects in memory, this
memory is not compacted.
See Also
GC
Garbage Collection
Managed Execution Process
Common Language Runtime (CLR)
7/29/2017 • 4 min to read • Edit Online
The .NET Framework provides a run-time environment called the common language runtime, which runs the code
and provides services that make the development process easier.
Compilers and tools expose the common language runtime's functionality and enable you to write code that
benefits from this managed execution environment. Code that you develop with a language compiler that targets
the runtime is called managed code; it benefits from features such as cross-language integration, cross-language
exception handling, enhanced security, versioning and deployment support, a simplified model for component
interaction, and debugging and profiling services.
NOTE
Compilers and tools are able to produce output that the common language runtime can consume because the type system,
the format of metadata, and the runtime environment (the virtual execution system) are all defined by a public standard, the
ECMA Common Language Infrastructure specification. For more information, see ECMA C# and Common Language
Infrastructure Specifications.
To enable the runtime to provide services to managed code, language compilers must emit metadata that describes
the types, members, and references in your code. Metadata is stored with the code; every loadable common
language runtime portable executable (PE) file contains metadata. The runtime uses metadata to locate and load
classes, lay out instances in memory, resolve method invocations, generate native code, enforce security, and set
run-time context boundaries.
The runtime automatically handles object layout and manages references to objects, releasing them when they are
no longer being used. Objects whose lifetimes are managed in this way are called managed data. Garbage
collection eliminates memory leaks as well as some other common programming errors. If your code is managed,
you can use managed data, unmanaged data, or both managed and unmanaged data in your .NET Framework
application. Because language compilers supply their own types, such as primitive types, you might not always
know (or need to know) whether your data is being managed.
The common language runtime makes it easy to design components and applications whose objects interact across
languages. Objects written in different languages can communicate with each other, and their behaviors can be
tightly integrated. For example, you can define a class and then use a different language to derive a class from your
original class or call a method on the original class. You can also pass an instance of a class to a method of a class
written in a different language. This cross-language integration is possible because language compilers and tools
that target the runtime use a common type system defined by the runtime, and they follow the runtime's rules for
defining new types, as well as for creating, using, persisting, and binding to types.
As part of their metadata, all managed components carry information about the components and resources they
were built against. The runtime uses this information to ensure that your component or application has the
specified versions of everything it needs, which makes your code less likely to break because of some unmet
dependency. Registration information and state data are no longer stored in the registry where they can be difficult
to establish and maintain. Instead, information about the types you define (and their dependencies) is stored with
the code as metadata, making the tasks of component replication and removal much less complicated.
Language compilers and tools expose the runtime's functionality in ways that are intended to be useful and
intuitive to developers. This means that some features of the runtime might be more noticeable in one
environment than in another. How you experience the runtime depends on which language compilers or tools you
use. For example, if you are a Visual Basic developer, you might notice that with the common language runtime, the
Visual Basic language has more object-oriented features than before. The runtime provides the following benefits:
Performance improvements.
The ability to easily use components developed in other languages.
Extensible types provided by a class library.
Language features such as inheritance, interfaces, and overloading for object-oriented programming.
Support for explicit free threading that allows creation of multithreaded, scalable applications.
Support for structured exception handling.
Support for custom attributes.
Garbage collection.
Use of delegates instead of function pointers for increased type safety and security. For more information
about delegates, see Common Type System.
1.0 1.0
1.1 1.1
2.0 2.0
3.0 2.0
3.5 2.0
4 4
4.7 4
Related Topics
TITLE DESCRIPTION
Managed Execution Process Describes the steps required to take advantage of the
common language runtime.
Automatic Memory Management Describes how the garbage collector allocates and releases
memory.
TITLE DESCRIPTION
NIB: Overview of the .NET Framework Describes key .NET Framework concepts such as the common
type system, cross-language interoperability, managed
execution, application domains, and assemblies.
Common Type System Describes how types are declared, used, and managed in the
runtime in support of cross-language integration.
See Also
Versions and Dependencies
Language independence and language-independent
components
8/5/2017 • 68 min to read • Edit Online
.NET is language independent. This means that, as a developer, you can develop in one of the many languages that
target .NET implementations, such as C#, F#, and Visual Basic. You can access the types and members of class
libraries developed for .NET implementations without having to know the language in which they were originally
written and without having to follow any of the original language's conventions. If you are a component developer,
your component can be accessed by any .NET app regardless of its language.
NOTE
This first part of this article discusses creating language-independent components - that is, components that can be
consumed by apps that are written in any language. You can also create a single component or app from source code written
in multiple languages; see Cross-Language Interoperability in the second part of this article.
To fully interact with other objects written in any language, objects must expose to callers only those features that
are common to all languages. This common set of features is defined by the Common Language Specification
(CLS), which is a set of rules that apply to generated assemblies. The Common Language Specification is defined in
Partition I, Clauses 7 through 11 of the ECMA-335 Standard: Common Language Infrastructure.
If your component conforms to the Common Language Specification, it is guaranteed to be CLS-compliant and can
be accessed from code in assemblies written in any programming language that supports the CLS. You can
determine whether your component conforms to the Common Language Specification at compile time by applying
the CLSCompliantAttribute attribute to your source code. For more information, see The CLSCompliantAttribute
attribute.
In this article:
CLS compliance rules
Types and type member signatures
Naming conventions
Type conversion
Arrays
Interfaces
Enumerations
Type members in general
Member accessibility
Generic types and members
Constructors
Properties
Events
Overloads
Exceptions
Attributes
CLSCompliantAttribute attribute
Cross-Language Interoperability
NOTE
The Common Language Specification discusses each rule for CLS compliance as it applies to consumers (developers who are
programmatically accessing a component that is CLS-compliant), frameworks (developers who are using a language compiler
to create CLS-compliant libraries), and extenders (developers who are creating a tool such as a language compiler or a code
parser that creates CLS-compliant components). This article focuses on the rules as they apply to frameworks. Note, though,
that some of the rules that apply to extenders may also apply to assemblies that are created using Reflection.Emit.
To design a component that is language independent, you only need to apply the rules for CLS compliance to your
component's public interface. Your private implementation does not have to conform to the specification.
IMPORTANT
The rules for CLS compliance apply only to a component's public interface, not to its private implementation.
For example, unsigned integers other than Byte are not CLS-compliant. Because the Person class in the following
example exposes an Age property of type UInt16, the following code displays a compiler warning.
using System;
[assembly: CLSCompliant(true)]
You can make the Person class CLS-compliant by changing the type of Age property from UInt16 to Int16, which
is a CLS-compliant, 16-bit signed integer. You do not have to change the type of the private personAge field.
using System;
[assembly: CLSCompliant(true)]
<Assembly: CLSCompliant(True)>
Types Types and type member Boxed value types are not 3
signatures CLS-compliant.
[assembly: CLSCompliant(true)]
[CLSCompliant(false)]
public class Counter
{
UInt32 ctr;
public Counter()
{
ctr = 0;
}
<CLSCompliant(False)> _
Public Class Counter
Dim ctr As UInt32
All types that appear in member signatures, including a method's return type or a property type, must be CLS-
compliant. In addition, for generic types:
All types that compose an instantiated generic type must be CLS-compliant.
All types used as constraints on generic parameters must be CLS-compliant.
The .NET common type system includes a number of built-in types that are supported directly by the common
language runtime and are specially encoded in an assembly's metadata. Of these intrinsic types, the types listed in
the following table are CLS-compliant.
The intrinsic types listed in the following table are not CLS-Compliant.
The .NET Framework Class Library or any other class library may include other types that aren't CLS-compliant; for
example:
Boxed value types. The following C# example creates a class that has a public property of type int * named
Value . Because an int * is a boxed value type, the compiler flags it as non-CLS-compliant.
using System;
[assembly:CLSCompliant(true)]
Typed references, which are special constructs that contain a reference to an object and a reference to a type.
If a type is not CLS-compliant, you should apply the CLSCompliantAttribute attribute with an isCompliant
parameter with a value of false to it. For more information, see the CLSCompliantAttribute attribute section.
The following example illustrates the problem of CLS compliance in a method signature and in generic type
instantiation. It defines an InvoiceItem class with a property of type UInt32, a property of type Nullable(Of UInt32),
and a constructor with parameters of type UInt32 and Nullable(Of UInt32) . You get four compiler warnings when
you try to compile this example.
using System;
[assembly: CLSCompliant(true)]
To eliminate the compiler warnings, replace the non-CLS-compliant types in the InvoiceItem public interface with
compliant types:
using System;
[assembly: CLSCompliant(true)]
qty = quantity;
}
In addition to the specific types listed, some categories of types are not CLS compliant. These include unmanaged
pointer types and function pointer types. The following example generates a compiler warning because it uses a
pointer to an integer to create an array of integers.
using System;
[assembly: CLSCompliant(true)]
[assembly: CLSCompliant(true)]
For CLS-compliant abstract classes (that is, classes marked as abstract in C#), all members of the class must also
be CLS-compliant.
Naming conventions
Because some programming languages are case-insensitive, identifiers (such as the names of namespaces, types,
and members) must differ by more than case. Two identifiers are considered equivalent if their lowercase
mappings are the same. The following C# example defines two public classes, Person and person . Because they
differ only by case, the C# compiler flags them as not CLS-compliant.
using System;
[assembly: CLSCompliant(true)]
}
// Compilation produces a compiler warning like the following:
// Naming1.cs(11,14): warning CS3005: Identifier 'person' differing
// only in case is not CLS-compliant
// Naming1.cs(6,14): (Location of symbol related to previous warning)
Programming language identifiers, such as the names of namespaces, types, and members, must conform to the
Unicode Standard 3.0, Technical Report 15, Annex 7. This means that:
The first character of an identifier can be any Unicode uppercase letter, lowercase letter, title case letter,
modifier letter, other letter, or letter number. For information on Unicode character categories, see the
System.Globalization.UnicodeCategory enumeration.
Subsequent characters can be from any of the categories as the first character, and can also include non-
spacing marks, spacing combining marks, decimal numbers, connector punctuations, and formatting codes.
Before you compare identifiers, you should filter out formatting codes and convert the identifiers to Unicode
Normalization Form C, because a single character can be represented by multiple UTF-16-encoded code units.
Character sequences that produce the same code units in Unicode Normalization Form C are not CLS-compliant.
The following example defines a property named Å , which consists of the character ANGSTROM SIGN (U+212B),
and a second property named Å which consists of the character LATIN CAPITAL LETTER A WITH RING ABOVE
(U+00C5). The C# compiler flags the source code as non-CLS-compliant.
public double Å
{
get { return a1; }
set { a1 = value; }
}
public double Å
{
get { return a2; }
set { a2 = value; }
}
}
// Compilation produces a compiler warning like the following:
// Naming2a.cs(16,18): warning CS3005: Identifier 'Size.Å' differing only in case is not
// CLS-compliant
// Naming2a.cs(10,18): (Location of symbol related to previous warning)
// Naming2a.cs(18,8): warning CS3005: Identifier 'Size.Å.get' differing only in case is not
// CLS-compliant
// Naming2a.cs(12,8): (Location of symbol related to previous warning)
// Naming2a.cs(19,8): warning CS3005: Identifier 'Size.Å.set' differing only in case is not
// CLS-compliant
// Naming2a.cs(13,8): (Location of symbol related to previous warning)
<Assembly: CLSCompliant(True)>
Public Class Size
Private a1 As Double
Private a2 As Double
Member names within a particular scope (such as the namespaces within an assembly, the types within a
namespace, or the members within a type) must be unique except for names that are resolved through
overloading. This requirement is more stringent than that of the common type system, which allows multiple
members within a scope to have identical names as long as they are different kinds of members (for example, one
is a method and one is a field). In particular, for type members:
Fields and nested types are distinguished by name alone.
Methods, properties, and events that have the same name must differ by more than just return type.
The following example illustrates the requirement that member names must be unique within their scope. It defines
a class named Converter that includes four members named Conversion . Three are methods, and one is a
property. The method that includes an Int64 parameter is uniquely named, but the two methods with an Int32
parameter are not, because return value is not considered a part of a member's signature. The Conversion property
also violates this requirement, because properties cannot have the same name as overloaded methods.
using System;
[assembly: CLSCompliant(true)]
Individual languages include unique keywords, so languages that target the common language runtime must also
provide some mechanism for referencing identifiers (such as type names) that coincide with keywords. For
example, case is a keyword in both C# and Visual Basic. However, the following Visual Basic example is able to
disambiguate a class named case from the case keyword by using opening and closing braces. Otherwise, the
example would produce the error message, "Keyword is not valid as an identifier," and fail to compile.
The following C# example is able to instantiate the case class by using the @ symbol to disambiguate the
identifier from the language keyword. Without it, the C# compiler would display two error messages, "Type
expected" and "Invalid expression term 'case'."
using System;
Type conversion
The Common Language Specification defines two conversion operators:
op_Implicit, which is used for widening conversions that do not result in loss of data or precision. For
example, the Decimal structure includes an overloaded op_Implicit operator to convert values of integral
types and Char values to Decimal values.
op_Explicit , which is used for narrowing conversions that can result in loss of magnitude (a value is
converted to a value that has a smaller range) or precision. For example, the Decimal structure includes an
overloaded op_Explicit operator to convert Double and Single values to Decimal and to convert Decimal
values to integral values, Double , Single , and Char .
However, not all languages support operator overloading or the definition of custom operators. If you choose to
implement these conversion operators, you should also provide an alternate way to perform the conversion. We
recommend that you provide From Xxx and To Xxx methods.
The following example defines CLS-compliant implicit and explicit conversions. It creates a UDouble class that
represents an signed double-precision, floating-point number. It provides for implicit conversions from UDouble to
Double and for explicit conversions from UDouble to Single , Double to UDouble , and Single to UDouble . It also
defines a ToDouble method as an alternative to the implicit conversion operator and the ToSingle , FromDouble ,
and FromSingle methods as alternatives to the explicit conversion operators.
using System;
number = value;
}
number = value;
}
Arrays
CLS-compliant arrays conform to the following rules:
All dimensions of an array must have a lower bound of zero. The following example creates a non-CLS-
compliant array with a lower bound of one. Note that, despite the presence of the CLSCompliantAttribute
attribute, the compiler does not detect that the array returned by the Numbers.GetTenPrimes method is not
CLS-compliant.
[assembly: CLSCompliant(true)]
return arr;
}
}
<Assembly: CLSCompliant(True)>
All array elements must consist of CLS-compliant types. The following example defines two methods that
return non-CLS-compliant arrays. The first returns an array of UInt32 values. The second returns an Object
array that includes Int32 and UInt32 values. Although the compiler identifies the first array as non-
compliant because of its UInt32 type, it fails to recognize that the second array includes non-CLS-compliant
elements.
using System;
[assembly: CLSCompliant(true)]
<Assembly: CLSCompliant(True)>
Overload resolution for methods that have array parameters is based on the fact that they are arrays and on
their element type. For this reason, the following definition of an overloaded GetSquares method is CLS-
compliant.
using System;
using System.Numerics;
[assembly: CLSCompliant(true)]
}
return numbersOut;
}
return numbersOut;
}
}
Imports System.Numerics
<Assembly: CLSCompliant(True)>
Interfaces
CLS-compliant interfaces can define properties, events, and virtual methods (methods with no implementation). A
CLS-compliant interface cannot have any of the following:
Static methods or static fields. The C# compiler generatse compiler errors if you define a static member in an
interface.
Fields. The C# acompiler generates compiler errors if you define a field in an interface.
Methods that are not CLS-compliant. For example, the following interface definition includes a method,
INumber.GetUnsigned , that is marked as non-CLS-compliant. This example generates a compiler warning.
using System;
[assembly:CLSCompliant(true)]
<Assembly: CLSCompliant(True)>
Because of this rule, CLS-compliant types are not required to implement non-CLS-compliant members. If a
CLS-compliant framework does expose a class that implements a non-CLS compliant interface, it should also
provide concrete implementations of all non-CLS-compliant members.
CLS-compliant language compilers must also allow a class to provide separate implementations of members that
have the same name and signature in multiple interfaces. C# supports explicit interface implementations to provide
different implementations of identically named methods. The following example illustrates this scenario by defining
a Temperature class that implements the ICelsius and IFahrenheit interfaces as explicit interface
implementations.
using System;
[assembly: CLSCompliant(true)]
decimal IFahrenheit.GetTemperature()
{
return _value * 9 / 5 + 32;
}
decimal ICelsius.GetTemperature()
{
return _value;
}
}
public class Example
{
public static void Main()
{
Temperature temp = new Temperature(100.0m);
ICelsius cTemp = temp;
IFahrenheit fTemp = temp;
Console.WriteLine("Temperature in Celsius: {0} degrees",
cTemp.GetTemperature());
Console.WriteLine("Temperature in Fahrenheit: {0} degrees",
fTemp.GetTemperature());
}
}
// The example displays the following output:
// Temperature in Celsius: 100.0 degrees
// Temperature in Fahrenheit: 212.0 degrees
Assembly: CLSCompliant(True)>
Module Example
Public Sub Main()
Dim temp As New Temperature(100.0d)
Console.WriteLine("Temperature in Celsius: {0} degrees",
temp.GetCelsius())
Console.WriteLine("Temperature in Fahrenheit: {0} degrees",
temp.GetFahrenheit())
End Sub
End Module
' The example displays the following output:
' Temperature in Celsius: 100.0 degrees
' Temperature in Fahrenheit: 212.0 degrees
Enumerations
CLS-compliant enumerations must follow these rules:
The underlying type of the enumeration must be an intrinsic CLS-compliant integer (Byte, Int16, Int32, or
Int64). For example, the following code tries to define an enumeration whose underlying type is UInt32 and
generates a compiler warning.
using System;
[assembly: CLSCompliant(true)]
<Assembly: CLSCompliant(True)>
An enumeration type must have a single instance field named Value__ that is marked with the
FieldAttributes.RTSpecialName attribute. This enables you to reference the field value implicitly.
An enumeration includes literal static fields whose types match the type of the enumeration itself. For
example, if you define a State enumeration with values of State.On and State.Off , State.On and
State.Off are both literal static fields whose type is State .
[assembly: CLSCompliant(true)]
Types in the signature of a member must be accessible whenever that member is accessible. For example, this
means that a public member cannot include a parameter whose type is private, protected, or internal. The following
example illustrates the compiler error that results when a StringWrapper class constructor exposes an internal
StringOperationType enumeration value that determines how a string value should be wrapped.
using System;
using System.Text;
Imports System.Text
<Assembly:CLSCompliant(True)>
using System;
[assembly:CLSCompliant(true)]
Generic type names are encoded in the form name'n, where name is the type name, ` is a character literal, and n is
the number of parameters declared on the type, or, for nested generic types, the number of newly introduced type
parameters. This encoding of generic type names is primarily of interest to developers who use reflection to access
CLS-complaint generic types in a library.
If constraints are applied to a generic type, any types used as constraints must also be CLS-compliant. The following
example defines a class named BaseClass that is not CLS-compliant and a generic class named BaseCollection
whose type parameter must derive from BaseClass . But because BaseClass is not CLS-compliant, the compiler
emits a warning.
using System;
[assembly:CLSCompliant(true)]
Assembly: CLSCompliant(True)>
If a generic type is derived from a generic base type, it must redeclare any constraints so that it can guarantee that
constraints on the base type are also satisfied. The following example defines a Number<T> that can represent any
numeric type. It also defines a FloatingPoint<T> class that represents a floating point value. However, the source
code fails to compile, because it does not apply the constraint on Number<T> (that T must be a value type) to
FloatingPoint<T> .
using System;
[assembly:CLSCompliant(true)]
The example compiles successfully if the constraint is added to the FloatingPoint<T> class.
using System;
[assembly:CLSCompliant(true)]
The Common Language Specification imposes a conservative per-instantiation model for nested types and
protected members. Open generic types cannot expose fields or members with signatures that contain a specific
instantiation of a nested, protected generic type. Non-generic types that extend a specific instantiation of a generic
base class or interface cannot expose fields or members with signatures that contain a different instantiation of a
nested, protected generic type.
The following example defines a generic type, C1<T> , and a protected class, C1<T>.N . C1<T> has two methods, M1
and M2 . However, M1 is not CLS-compliant because it tries to return a C1<int>.N object from C1<T> . A second
class, C2 , is derived from C1<long> . It has two methods, M3 and M4 . M3 is not CLS-compliant because it tries to
return a C1<int>.N object from a subclass of C1<long> . Note that language compilers can be even more restrictive.
In this example, Visual Basic displays an error when it tries to compile M4 .
using System;
[assembly:CLSCompliant(true)]
Protected Sub M1(n As C1(Of Integer).N) ' Not CLS-compliant - C1<int>.N not
' accessible from within C1(Of T) in all
End Sub ' languages
Protected Sub M2(n As C1(Of T).N) ' CLS-compliant – C1(Of T).N accessible
End Sub ' inside C1(Of T)
End Class
Constructors
Constructors in CLS-compliant classes and structures must follow these rules:
A constructor of a derived class must call the instance constructor of its base class before it accesses
inherited instance data. This requirement is due to the fact that base class constructors are not inherited by
their derived classes. This rule does not apply to structures, which do not support direct inheritance.
Typically, compilers enforce this rule independently of CLS compliance, as the following example shows. It
creates a Doctor class that is derived from a Person class, but the Doctor class fails to call the Person
class constructor to initialize inherited instance fields.
using System;
[assembly: CLSCompliant(true)]
fName = firstName;
lName = lastName;
_id = id;
}
public string Id
{
get { return _id; }
}
fName = firstName
lName = lastName
_id = id
End Sub
An object constructor cannot be called except to create an object. In addition, an object cannot be initialized
twice. For example, this means that Object.MemberwiseClone must not call constructors.
Properties
Properties in CLS-compliant types must follow these rules:
A property must have a setter, a getter, or both. In an assembly, these are implemented as special methods,
which means that they will appear as separate methods (the getter is named get _propertyname and the
setter is set*\_*propertyname*) marked as SpecialName` in the assembly's metadata. The C# compiler
enforces this rule automatically without the need to apply the CLSCompliantAttribute attribute.
A property's type is the return type of the property getter and the last argument of the setter. These types
must be CLS compliant, and arguments cannot be assigned to the property by reference (that is, they cannot
be managed pointers).
If a property has both a getter and a setter, they must both be virtual, both static, or both instance. The C#
compiler automatically enforces this rule through property definition syntax.
Events
An event is defined by its name and its type. The event type is a delegate that is used to indicate the event. For
example, the DbConnection.StateChange event is of type StateChangeEventHandler . In addition to the event itself,
three methods with names based on the event name provide the event's implementation and are marked as
SpecialName in the assembly's metadata:
A method for adding an event handler, named add _EventName. For example, the event subscription
method for the DbConnection.StateChange event is named add_StateChange .
A method for removing an event handler, named remove _EventName. For example, the removal method for
the DbConnection.StateChange event is named remove_StateChange .
A method for indicating that the event has occurred, named raise _EventName.
NOTE
Most of the Common Language Specification's rules regarding events are implemented by language compilers and are
transparent to component developers.
The methods for adding, removing, and raising the event must have the same accessibility. They must also all be
static, instance, or virtual. The methods for adding and removing an event have one parameter whose type is the
event delegate type. The add and remove methods must both be present or both be absent.
The following example defines a CLS-compliant class named Temperature that raises a TemperatureChanged event if
the change in temperature between two readings equals or exceeds a threshold value. The Temperature class
explicitly defines a raise_TemperatureChanged method so that it can selectively execute event handlers.
using System;
using System.Collections;
using System.Collections.Generic;
[assembly: CLSCompliant(true)]
public Example()
{
temp = new Temperature(65, 3);
temp.TemperatureChanged += this.TemperatureNotification;
RecordTemperatures();
Example ex = new Example(temp);
ex.RecordTemperatures();
}
public Example(Temperature t)
{
temp = t;
RecordTemperatures();
}
Imports System.Collections
Imports System.Collections.Generic
<Assembly: CLSCompliant(True)>
End Sub
Overloads
The Common Language Specification imposes the following requirements on overloaded members:
Members can be overloaded based on the number of parameters and the type of any parameter. Calling
convention, return type, custom modifiers applied to the method or its parameter, and whether parameters
are passed by value or by reference are not considered when differentiating between overloads. For an
example, see the code for the requirement that names must be unique within a scope in the Naming
conventions section.
Only properties and methods can be overloaded. Fields and events cannot be overloaded.
Generic methods can be overloaded based on the number of their generic parameters.
NOTE
The op_Explicit and op_Implicit operators are exceptions to the rule that return value is not considered part of a
method signature for overload resolution. These two operators can be overloaded based on both their parameters and their
return value.
Exceptions
Exception objects must derive from System.Exception or from another type derived from System.Exception . The
following example illustrates the compiler error that results when a custom class named ErrorClass is used for
exception handling.
using System;
[assembly: CLSCompliant(true)]
<Assembly: CLSCompliant(True)>
To correct this error, the ErrorClass class must inherit from System.Exception . In addition, the Message property
must be overridden. The following example corrects these errors to define an ErrorClass class that is CLS-
compliant.
using System;
[assembly: CLSCompliant(true)]
Imports System.Runtime.CompilerServices
<Assembly: CLSCompliant(True)>
Attributes
In.NET Framework assemblies, custom attributes provide an extensible mechanism for storing custom attributes
and retrieving metadata about programming objects, such as assemblies, types, members, and method parameters.
Custom attributes must derive from System.Attribute or from a type derived from System.Attribute .
The following example violates this rule. It defines a NumericAttribute class that does not derive from
System.Attribute . Note that a compiler error results only when the non-CLS-compliant attribute is applied, not
when the class is defined.
using System;
[assembly: CLSCompliant(true)]
[AttributeUsageAttribute(AttributeTargets.Class | AttributeTargets.Struct)]
public class NumericAttribute
{
private bool _isNumeric;
<Assembly: CLSCompliant(True)>
<AttributeUsageAttribute(AttributeTargets.Class Or AttributeTargets.Struct)> _
Public Class NumericAttribute
Private _isNumeric As Boolean
The following example defines a DescriptionAttribute class that derives from Attribute. The class constructor has a
parameter of type Descriptor , so the class is not CLS-compliant. Note that the C# compiler emits a warning but
compiles successfully.
using System;
[assembly:CLSCompliantAttribute(true)]
[AttributeUsage(AttributeTargets.All)]
public class DescriptionAttribute : Attribute
{
private Descriptor desc;
public DescriptionAttribute(Descriptor d)
{
desc = d;
}
<AttributeUsage(AttributeTargets.All)> _
Public Class DescriptionAttribute : Inherits Attribute
Private desc As Descriptor
WARNING
In some cases, language compilers enforce CLS-compliant rules regardless of whether the CLSCompliantAttribute attribute
is used. For example, defining a *static member in an interface violates a CLS rule. However, if you define a *static
member in an interface, the C# compiler displays an error message and fails to compile the app.
The CLSCompliantAttribute attribute is marked with an AttributeUsageAttribute attribute that has a value of
AttributeTargets.All . This value allows you to apply the CLSCompliantAttribute attribute to any program element,
including assemblies, modules, types (classes, structures, enumerations, interfaces, and delegates), type members
(constructors, methods, properties, fields, and events), parameters, generic parameters, and return values. However,
in practice, you should apply the attribute only to assemblies, types, and type members. Otherwise, compilers
ignore the attribute and continue to generate compiler warnings whenever they encounter a non-compliant
parameter, generic parameter, or return value in your library's public interface.
The value of the CLSCompliantAttribute attribute is inherited by contained program elements. For example, if an
assembly is marked as CLS-compliant, its types are also CLS-compliant. If a type is marked as CLS-compliant, its
nested types and members are also CLS-compliant.
You can explicitly override the inherited compliance by applying the CLSCompliantAttribute attribute to a contained
program element. For example, you can use the CLSCompliantAttribute attribute with an isCompliant value of
false to define a non-compliant type in a compliant assembly, and you can use the attribute with an isComplian
value of true to define a compliant type in a non-compliant assembly. You can also define non-compliant
members in a compliant type. However, a non-compliant type cannot have compliant members, so you cannot use
the attribute with an isCompliant value of true to override inheritance from a non-compliant type.
When you are developing components, you should always use the CLSCompliantAttribute attribute to indicate
whether your assembly, its types, and its members are CLS-compliant.
To create CLS-compliant components:
1. Use the CLSCompliantAttribute to mark you assembly as CLS-compliant.
2. Mark any publicly exposed types in the assembly that are not CLS-compliant as non-compliant.
3. Mark any publicly exposed members in CLS-compliant types as non-compliant.
4. Provide a CLS-compliant alternative for non-CLS-compliant members.
If you've successfully marked all your non-compliant types and members, your compiler should not emit any non-
compliance warnings. However, you should indicate which members are not CLS-compliant and list their CLS-
compliant alternatives in your product documentation.
The following example uses the CLSCompliantAttribute attribute to define a CLS-compliant assembly and a type,
CharacterUtilities , that has two non-CLS-compliant members. Because both members are tagged with the
CLSCompliant(false) attribute, the compiler produces no warnings. The class also provides a CLS-compliant
alternative for both methods. Ordinarily, we would just add two overloads to the ToUTF16 method to provide CLS-
compliant alternatives. However, because methods cannot be overloaded based on return value, the names of the
CLS-compliant methods are different from the names of the non-compliant methods.
using System;
using System.Text;
[assembly:CLSCompliant(true)]
if (chars.Length == 2) {
if (! Char.IsSurrogatePair(chars[0], chars[1]))
throw new ArgumentException("The array must contain a low and a high surrogate.");
else
return Char.ConvertToUtf32(chars[0], chars[1]);
}
else {
return Char.ConvertToUtf32(chars.ToString(), 0);
}
}
}
Imports System.Text
<Assembly:CLSCompliant(True)>
If you are developing an app rather than a library (that is, if you aren't exposing types or members that can be
consumed by other app developers), the CLS compliance of the program elements that your app consumes are of
interest only if your language does not support them. In that case, your language compiler will generate an error
when you try to use a non-CLS-compliant element.
Cross-Language Interoperability
Language independence has a number of possible meanings. One meaning involves seamlessly consuming types
written in one language from an app written in another language. A second meaning, which is the focus of this
article, involves combining code written in multiple languages into a single .NET Framework assembly.
The following example illustrates cross-language interoperability by creating a class library named Utilities.dll that
includes two classes, NumericLib and StringLib . The NumericLib class is written in C#, and the StringLib class is
written in Visual Basic. Here's the source code for StringUtil.vb , which includes a single member, ToTitleCase , in
its StringLib class.
Imports System.Collections.Generic
Imports System.Runtime.CompilerServices
Sub New()
Dim words() As String = { "a", "an", "and", "of", "the" }
exclusions = New List(Of String)
exclusions.AddRange(words)
End Sub
<Extension()> _
Public Function ToTitleCase(title As String) As String
Dim words() As String = title.Split()
Dim result As String = String.Empty
Here's the source code for NumberUtil.cs, which defines a NumericLib class that has two members, IsEven and
NearZero .
using System;
To package the two classes in a single assembly, you must compile them into modules. To compile the Visual Basic
source code file into a module, use this command:
To compile the C# source code file into a module, use this command:
You then use the Link tool (Link.exe) to compile the two modules into an assembly:
The following example then calls the NumericLib.NearZero and StringLib.ToTitleCase methods. Note that both the
Visual Basic code and the C# code are able to access the methods in both classes.
using System;
To compile with C#, change the name of the compiler from vbc to csc, and change the file extension from .vb to .cs:
The .NET Framework is language independent. This means that, as a developer, you can develop in one of the
many languages that target the .NET Framework, such as C#, C++/CLI, Eiffel, F#, IronPython, IronRuby,
PowerBuilder, Visual Basic, Visual COBOL, and Windows PowerShell. You can access the types and members of
class libraries developed for the .NET Framework without having to know the language in which they were
originally written and without having to follow any of the original language's conventions. If you are a component
developer, your component can be accessed by any .NET Framework app regardless of its language.
NOTE
This first part of this article discusses creating language-independent components—that is, components that can be
consumed by apps that are written in any language. You can also create a single component or app from source code
written in multiple languages; see Cross-Language Interoperability in the second part of this article.
To fully interact with other objects written in any language, objects must expose to callers only those features that
are common to all languages. This common set of features is defined by the Common Language Specification
(CLS), which is a set of rules that apply to generated assemblies. The Common Language Specification is defined in
Partition I, Clauses 7 through 11 of the ECMA-335 Standard: Common Language Infrastructure.
If your component conforms to the Common Language Specification, it is guaranteed to be CLS-compliant and can
be accessed from code in assemblies written in any programming language that supports the CLS. You can
determine whether your component conforms to the Common Language Specification at compile time by
applying the CLSCompliantAttribute attribute to your source code. For more information, see The
CLSCompliantAttribute attribute.
In this article:
CLS compliance rules
Types and type member signatures
Naming conventions
Type conversion
Arrays
Interfaces
Enumerations
Type members in general
Member accessibility
Generic types and members
Constructors
Properties
Events
Overloads
Exceptions
Attributes
The CLSCompliantAttribute attribute
Cross-Language Interoperability
NOTE
The Common Language Specification discusses each rule for CLS compliance as it applies to consumers (developers who are
programmatically accessing a component that is CLS-compliant), frameworks (developers who are using a language compiler
to create CLS-compliant libraries), and extenders (developers who are creating a tool such as a language compiler or a code
parser that creates CLS-compliant components). This article focuses on the rules as they apply to frameworks. Note, though,
that some of the rules that apply to extenders may also apply to assemblies that are created using Reflection.Emit.
To design a component that is language independent, you only need to apply the rules for CLS compliance to your
component's public interface. Your private implementation does not have to conform to the specification.
IMPORTANT
The rules for CLS compliance apply only to a component's public interface, not to its private implementation.
For example, unsigned integers other than Byte are not CLS-compliant. Because the Person class in the following
example exposes an Age property of type UInt16, the following code displays a compiler warning.
using System;
[assembly: CLSCompliant(true)]
You can make the Person class CLS-compliant by changing the type of Age property from UInt16 to Int16, which
is a CLS-compliant, 16-bit signed integer. You do not have to change the type of the private personAge field.
using System;
[assembly: CLSCompliant(true)]
<Assembly: CLSCompliant(True)>
Types Type and type member Boxed value types are not 3
signatures CLS-compliant.
[assembly: CLSCompliant(true)]
[CLSCompliant(false)]
public class Counter
{
UInt32 ctr;
public Counter()
{
ctr = 0;
}
<CLSCompliant(False)> _
Public Class Counter
Dim ctr As UInt32
All types that appear in member signatures, including a method's return type or a property type, must be CLS-
compliant. In addition, for generic types:
All types that compose an instantiated generic type must be CLS-compliant.
All types used as constraints on generic parameters must be CLS-compliant.
The .NET Framework common type system includes a number of built-in types that are supported directly by the
common language runtime and are specially encoded in an assembly's metadata. Of these intrinsic types, the
types listed in the following table are CLS-compliant.
The intrinsic types listed in the following table are not CLS-Compliant.
The .NET Framework Class Library or any other class library may include other types that aren't CLS-compliant; for
example:
Boxed value types. The following C# example creates a class that has a public property of type int* named
Value . Because an int* is a boxed value type, the compiler flags it as non-CLS-compliant.
using System;
[assembly:CLSCompliant(true)]
Typed references, which are special constructs that contain a reference to an object and a reference to a
type. Typed references are represented in the .NET Framework by the TypedReference class.
If a type is not CLS-compliant, you should apply the CLSCompliantAttribute attribute with an isCompliant value of
false to it. For more information, see the The CLSCompliantAttribute attribute section.
The following example illustrates the problem of CLS compliance in a method signature and in generic type
instantiation. It defines an InvoiceItem class with a property of type UInt32, a property of type
Nullable(Of UInt32) , and a constructor with parameters of type UInt32 and Nullable(Of UInt32) . You get four
compiler warnings when you try to compile this example.
using System;
[assembly: CLSCompliant(true)]
To eliminate the compiler warnings, replace the non-CLS-compliant types in the InvoiceItem public interface with
compliant types:
using System;
[assembly: CLSCompliant(true)]
qty = quantity;
}
In addition to the specific types listed, some categories of types are not CLS compliant. These include unmanaged
pointer types and function pointer types. The following example generates a compiler warning because it uses a
pointer to an integer to create an array of integers.
using System;
[assembly: CLSCompliant(true)]
For CLS-compliant abstract classes (that is, classes marked as abstract in C# or as MustInherit in Visual Basic),
all members of the class must also be CLS-compliant.
Naming conventions
Because some programming languages are case-insensitive, identifiers (such as the names of namespaces, types,
and members) must differ by more than case. Two identifiers are considered equivalent if their lowercase
mappings are the same. The following C# example defines two public classes, Person and person . Because they
differ only by case, the C# compiler flags them as not CLS-compliant.
using System;
[assembly: CLSCompliant(true)]
}
// Compilation produces a compiler warning like the following:
// Naming1.cs(11,14): warning CS3005: Identifier 'person' differing
// only in case is not CLS-compliant
// Naming1.cs(6,14): (Location of symbol related to previous warning)
Programming language identifiers, such as the names of namespaces, types, and members, must conform to the
Unicode Standard 3.0, Technical Report 15, Annex 7. This means that:
The first character of an identifier can be any Unicode uppercase letter, lowercase letter, title case letter,
modifier letter, other letter, or letter number. For information on Unicode character categories, see the
System.Globalization.UnicodeCategory enumeration.
Subsequent characters can be from any of the categories as the first character, and can also include non-
spacing marks, spacing combining marks, decimal numbers, connector punctuations, and formatting codes.
Before you compare identifiers, you should filter out formatting codes and convert the identifiers to Unicode
Normalization Form C, because a single character can be represented by multiple UTF-16-encoded code units.
Character sequences that produce the same code units in Unicode Normalization Form C are not CLS-compliant.
The following example defines a property named Å , which consists of the character ANGSTROM SIGN (U+212B),
and a second property named Å , which consists of the character LATIN CAPITAL LETTER A WITH RING ABOVE
(U+00C5). Both the C# and Visual Basic compilers flag the source code as non-CLS-compliant.
public class Size
{
private double a1;
private double a2;
public double Å
{
get { return a1; }
set { a1 = value; }
}
public double Å
{
get { return a2; }
set { a2 = value; }
}
}
// Compilation produces a compiler warning like the following:
// Naming2a.cs(16,18): warning CS3005: Identifier 'Size.Å' differing only in case is not
// CLS-compliant
// Naming2a.cs(10,18): (Location of symbol related to previous warning)
// Naming2a.cs(18,8): warning CS3005: Identifier 'Size.Å.get' differing only in case is not
// CLS-compliant
// Naming2a.cs(12,8): (Location of symbol related to previous warning)
// Naming2a.cs(19,8): warning CS3005: Identifier 'Size.Å.set' differing only in case is not
// CLS-compliant
// Naming2a.cs(13,8): (Location of symbol related to previous warning)
<Assembly: CLSCompliant(True)>
Public Class Size
Private a1 As Double
Private a2 As Double
Member names within a particular scope (such as the namespaces within an assembly, the types within a
namespace, or the members within a type) must be unique except for names that are resolved through
overloading. This requirement is more stringent than that of the common type system, which allows multiple
members within a scope to have identical names as long as they are different kinds of members (for example, one
is a method and one is a field). In particular, for type members:
Fields and nested types are distinguished by name alone.
Methods, properties, and events that have the same name must differ by more than just return type.
The following example illustrates the requirement that member names must be unique within their scope. It
defines a class named Converter that includes four members named Conversion . Three are methods, and one is a
property. The method that includes an Int64 parameter is uniquely named, but the two methods with an Int32
parameter are not, because return value is not considered a part of a member's signature. The Conversion
property also violates this requirement, because properties cannot have the same name as overloaded methods.
using System;
[assembly: CLSCompliant(true)]
Individual languages include unique keywords, so languages that target the common language runtime must also
provide some mechanism for referencing identifiers (such as type names) that coincide with keywords. For
example, case is a keyword in both C# and Visual Basic. However, the following Visual Basic example is able to
disambiguate a class named case from the case keyword by using opening and closing braces. Otherwise, the
example would produce the error message, "Keyword is not valid as an identifier," and fail to compile.
The following C# example is able to instantiate the case class by using the @ symbol to disambiguate the
identifier from the language keyword. Without it, the C# compiler would display two error messages, "Type
expected" and "Invalid expression term 'case'."
using System;
Type conversion
The Common Language Specification defines two conversion operators:
op_Implicit, which is used for widening conversions that do not result in loss of data or precision. For
example, the Decimal structure includes an overloaded op_Implicit operator to convert values of integral
types and Char values to Decimal values.
op_Explicit , which is used for narrowing conversions that can result in loss of magnitude (a value is
converted to a value that has a smaller range) or precision. For example, the Decimal structure includes an
overloaded op_Explicit operator to convert Double and Single values to Decimal and to convert Decimal
values to integral values, Double, Single, and Char.
However, not all languages support operator overloading or the definition of custom operators. If you choose to
implement these conversion operators, you should also provide an alternate way to perform the conversion. We
recommend that you provide From Xxx and To Xxx methods.
The following example defines CLS-compliant implicit and explicit conversions. It creates a UDouble class that
represents an signed double-precision, floating-point number. It provides for implicit conversions from UDouble
to Double and for explicit conversions from UDouble to Single, Double to UDouble , and Single to UDouble . It also
defines a ToDouble method as an alternative to the implicit conversion operator and the ToSingle , FromDouble ,
and FromSingle methods as alternatives to the explicit conversion operators.
using System;
number = value;
}
number = value;
}
Arrays
CLS-compliant arrays conform to the following rules:
All dimensions of an array must have a lower bound of zero. The following example creates a non-CLS-
compliant array with a lower bound of one. Note that, despite the presence of the CLSCompliantAttribute
attribute, the compiler does not detect that the array returned by the Numbers.GetTenPrimes method is not
CLS-compliant.
[assembly: CLSCompliant(true)]
return arr;
}
}
<Assembly: CLSCompliant(True)>
Return arr
End Function
End Class
All array elements must consist of CLS-compliant types. The following example defines two methods that
return non-CLS-compliant arrays. The first returns an array of UInt32 values. The second returns an Object
array that includes Int32 and UInt32 values. Although the compiler identifies the first array as non-
compliant because of its UInt32 type, it fails to recognize that the second array includes non-CLS-compliant
elements.
using System;
[assembly: CLSCompliant(true)]
<Assembly: CLSCompliant(True)>
Overload resolution for methods that have array parameters is based on the fact that they are arrays and on
their element type. For this reason, the following definition of an overloaded GetSquares method is CLS-
compliant.
using System;
using System.Numerics;
[assembly: CLSCompliant(true)]
}
return numbersOut;
}
return numbersOut;
}
}
Imports System.Numerics
<Assembly: CLSCompliant(True)>
Interfaces
CLS-compliant interfaces can define properties, events, and virtual methods (methods with no implementation). A
CLS-compliant interface cannot have any of the following:
Static methods or static fields. Both the C# and Visual Basic compilers generate compiler errors if you define
a static member in an interface.
Fields. Both the C# and Visual Basic compilers generate compiler errors if you define a field in an interface.
Methods that are not CLS-compliant. For example, the following interface definition includes a method,
INumber.GetUnsigned , that is marked as non-CLS-compliant. This example generates a compiler warning.
using System;
[assembly:CLSCompliant(true)]
<Assembly: CLSCompliant(True)>
Because of this rule, CLS-compliant types are not required to implement non-CLS-compliant members. If a
CLS-compliant framework does expose a class that implements a non-CLS compliant interface, it should
also provide concrete implementations of all non-CLS-compliant members.
CLS-compliant language compilers must also allow a class to provide separate implementations of members that
have the same name and signature in multiple interfaces. Both C# and Visual Basic support explicit interface
implementations to provide different implementations of identically named methods. Visual Basic also supports
the Implements keyword, which enables you to explicitly designate which interface and member a particular
member implements. The following example illustrates this scenario by defining a Temperature class that
implements the ICelsius and IFahrenheit interfaces as explicit interface implementations.
using System;
[assembly: CLSCompliant(true)]
decimal IFahrenheit.GetTemperature()
{
return _value * 9 / 5 + 32;
}
decimal ICelsius.GetTemperature()
{
return _value;
}
}
public class Example
{
public static void Main()
{
Temperature temp = new Temperature(100.0m);
ICelsius cTemp = temp;
IFahrenheit fTemp = temp;
Console.WriteLine("Temperature in Celsius: {0} degrees",
cTemp.GetTemperature());
Console.WriteLine("Temperature in Fahrenheit: {0} degrees",
fTemp.GetTemperature());
}
}
// The example displays the following output:
// Temperature in Celsius: 100.0 degrees
// Temperature in Fahrenheit: 212.0 degrees
<Assembly: CLSCompliant(True)>
Module Example
Public Sub Main()
Dim temp As New Temperature(100.0d)
Console.WriteLine("Temperature in Celsius: {0} degrees",
temp.GetCelsius())
Console.WriteLine("Temperature in Fahrenheit: {0} degrees",
temp.GetFahrenheit())
End Sub
End Module
' The example displays the following output:
' Temperature in Celsius: 100.0 degrees
' Temperature in Fahrenheit: 212.0 degrees
Enumerations
CLS-compliant enumerations must follow these rules:
The underlying type of the enumeration must be an intrinsic CLS-compliant integer (Byte, Int16, Int32, or
Int64). For example, the following code tries to define an enumeration whose underlying type is UInt32 and
generates a compiler warning.
using System;
[assembly: CLSCompliant(true)]
<Assembly: CLSCompliant(True)>
An enumeration type must have a single instance field named Value__ that is marked with the
System.Reflection.FieldAttributes.RTSpecialName attribute. This enables you to reference the field value
implicitly.
An enumeration includes literal static fields whose types match the type of the enumeration itself. For
example, if you define a State enumeration with values of State.On and State.Off , State.On and
State.Off are both literal static fields whose type is State .
[assembly: CLSCompliant(true)]
Types in the signature of a member must be accessible whenever that member is accessible. For example, this
means that a public member cannot include a parameter whose type is private, protected, or internal. The
following example illustrates the compiler error that results when a StringWrapper class constructor exposes an
internal StringOperationType enumeration value that determines how a string value should be wrapped.
using System;
using System.Text;
Imports System.Text
<Assembly:CLSCompliant(True)>
using System;
[assembly:CLSCompliant(true)]
Generic type names are encoded in the form name`n, where name is the type name, ` is a character literal, and n is
the number of parameters declared on the type, or, for nested generic types, the number of newly introduced type
parameters. This encoding of generic type names is primarily of interest to developers who use reflection to access
CLS-complaint generic types in a library.
If constraints are applied to a generic type, any types used as constraints must also be CLS-compliant. The
following example defines a class named BaseClass that is not CLS-compliant and a generic class named
BaseCollection whose type parameter must derive from BaseClass . But because BaseClass is not CLS-compliant,
the compiler emits a warning.
using System;
[assembly:CLSCompliant(true)]
<Assembly: CLSCompliant(True)>
If a generic type is derived from a generic base type, it must redeclare any constraints so that it can guarantee that
constraints on the base type are also satisfied. The following example defines a Number<T> that can represent any
numeric type. It also defines a FloatingPoint<T> class that represents a floating point value. However, the source
code fails to compile, because it does not apply the constraint on Number<T> (that T must be a value type) to
FloatingPoint<T> .
using System;
[assembly:CLSCompliant(true)]
The example compiles successfully if the constraint is added to the FloatingPoint<T> class.
using System;
[assembly:CLSCompliant(true)]
The Common Language Specification imposes a conservative per-instantiation model for nested types and
protected members. Open generic types cannot expose fields or members with signatures that contain a specific
instantiation of a nested, protected generic type. Non-generic types that extend a specific instantiation of a generic
base class or interface cannot expose fields or members with signatures that contain a different instantiation of a
nested, protected generic type.
The following example defines a generic type, C1<T> (or C1(Of T) in Visual Basic), and a protected class, C1<T>.N
(or C1(Of T).N in Visual Basic). C1<T> has two methods, M1 and M2 . However, M1 is not CLS-compliant
because it tries to return a C1<int>.N (or C1(Of Integer).N ) object from C1<T> (or C1(Of T) ). A second class,
C2 , is derived from C1<long> (or C1(Of Long) ). It has two methods, M3 and M4 . M3 is not CLS-compliant
because it tries to return a C1<int>.N (or C1(Of Integer).N ) object from a subclass of C1<long> . Note that
language compilers can be even more restrictive. In this example, Visual Basic displays an error when it tries to
compile M4 .
using System;
[assembly:CLSCompliant(true)]
Protected Sub M1(n As C1(Of Integer).N) ' Not CLS-compliant - C1<int>.N not
' accessible from within C1(Of T) in all
End Sub ' languages
Protected Sub M2(n As C1(Of T).N) ' CLS-compliant – C1(Of T).N accessible
End Sub ' inside C1(Of T)
End Class
Constructors
Constructors in CLS-compliant classes and structures must follow these rules:
A constructor of a derived class must call the instance constructor of its base class before it accesses
inherited instance data. This requirement is due to the fact that base class constructors are not inherited by
their derived classes. This rule does not apply to structures, which do not support direct inheritance.
Typically, compilers enforce this rule independently of CLS compliance, as the following example shows. It
creates a Doctor class that is derived from a Person class, but the Doctor class fails to call the Person
class constructor to initialize inherited instance fields.
using System;
[assembly: CLSCompliant(true)]
fName = firstName;
lName = lastName;
_id = id;
}
public string Id
{
get { return _id; }
}
fName = firstName
lName = lastName
_id = id
End Sub
An object constructor cannot be called except to create an object. In addition, an object cannot be initialized
twice. For example, this means that System.Object.MemberwiseClone and deserialization methods such as
System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize must not call constructors.
Properties
Properties in CLS-compliant types must follow these rules:
A property must have a setter, a getter, or both. In an assembly, these are implemented as special methods,
which means that they will appear as separate methods (the getter is named get_ propertyname and the
setter is set_ propertyname) marked as SpecialName in the assembly's metadata. The C# and Visual Basic
compilers enforce this rule automatically without the need to apply the CLSCompliantAttribute attribute.
A property's type is the return type of the property getter and the last argument of the setter. These types
must be CLS compliant, and arguments cannot be assigned to the property by reference (that is, they
cannot be managed pointers).
If a property has both a getter and a setter, they must both be virtual, both static, or both instance. The C#
and Visual Basic compilers automatically enforce this rule through their property definition syntax.
Events
An event is defined by its name and its type. The event type is a delegate that is used to indicate the event. For
example, the System.AppDomain.AssemblyResolve event is of type ResolveEventHandler. In addition to the event
itself, three methods with names based on the event name provide the event's implementation and are marked as
SpecialName in the assembly's metadata:
A method for adding an event handler, named add_ EventName. For example, the event subscription
method for the System.AppDomain.AssemblyResolve event is named add_AssemblyResolve .
A method for removing an event handler, named remove_ EventName. For example, the removal method
for the System.AppDomain.AssemblyResolve event is named remove_AssemblyResolve .
A method for indicating that the event has occurred, named raise_ EventName.
NOTE
Most of the Common Language Specification's rules regarding events are implemented by language compilers and are
transparent to component developers.
The methods for adding, removing, and raising the event must have the same accessibility. They must also all be
static, instance, or virtual. The methods for adding and removing an event have one parameter whose type is the
event delegate type. The add and remove methods must both be present or both be absent.
The following example defines a CLS-compliant class named Temperature that raises a TemperatureChanged event
if the change in temperature between two readings equals or exceeds a threshold value. The Temperature class
explicitly defines a raise_TemperatureChanged method so that it can selectively execute event handlers.
using System;
using System.Collections;
using System.Collections.Generic;
[assembly: CLSCompliant(true)]
public Example()
{
temp = new Temperature(65, 3);
temp.TemperatureChanged += this.TemperatureNotification;
RecordTemperatures();
Example ex = new Example(temp);
ex.RecordTemperatures();
}
public Example(Temperature t)
{
temp = t;
RecordTemperatures();
}
Imports System.Collections
Imports System.Collections.Generic
<Assembly: CLSCompliant(True)>
End Sub
Overloads
The Common Language Specification imposes the following requirements on overloaded members:
Members can be overloaded based on the number of parameters and the type of any parameter. Calling
convention, return type, custom modifiers applied to the method or its parameter, and whether parameters
are passed by value or by reference are not considered when differentiating between overloads. For an
example, see the code for the requirement that names must be unique within a scope in the Naming
conventions section.
Only properties and methods can be overloaded. Fields and events cannot be overloaded.
Generic methods can be overloaded based on the number of their generic parameters.
NOTE
The op_Explicit and op_Implicit operators are exceptions to the rule that return value is not considered part of a
method signature for overload resolution. These two operators can be overloaded based on both their parameters and their
return value.
Exceptions
Exception objects must derive from System.Exception or from another type derived from System.Exception. The
following example illustrates the compiler error that results when a custom class named ErrorClass is used for
exception handling.
using System;
[assembly: CLSCompliant(true)]
<Assembly: CLSCompliant(True)>
To correct this error, the ErrorClass class must inherit from System.Exception. In addition, the Message property
must be overridden. The following example corrects these errors to define an ErrorClass class that is CLS-
compliant.
using System;
[assembly: CLSCompliant(true)]
Imports System.Runtime.CompilerServices
<Assembly: CLSCompliant(True)>
Attributes
In.NET Framework assemblies, custom attributes provide an extensible mechanism for storing custom attributes
and retrieving metadata about programming objects, such as assemblies, types, members, and method
parameters. Custom attributes must derive from System.Attribute or from a type derived from System.Attribute.
The following example violates this rule. It defines a NumericAttribute class that does not derive from
System.Attribute. Note that a compiler error results only when the non-CLS-compliant attribute is applied, not
when the class is defined.
using System;
[assembly: CLSCompliant(true)]
[AttributeUsageAttribute(AttributeTargets.Class | AttributeTargets.Struct)]
public class NumericAttribute
{
private bool _isNumeric;
<Assembly: CLSCompliant(True)>
<AttributeUsageAttribute(AttributeTargets.Class Or AttributeTargets.Struct)> _
Public Class NumericAttribute
Private _isNumeric As Boolean
using System;
[assembly:CLSCompliantAttribute(true)]
[AttributeUsage(AttributeTargets.All)]
public class DescriptionAttribute : Attribute
{
private Descriptor desc;
public DescriptionAttribute(Descriptor d)
{
desc = d;
}
<AttributeUsage(AttributeTargets.All)> _
Public Class DescriptionAttribute : Inherits Attribute
Private desc As Descriptor
WARNING
In some cases, language compilers enforce CLS-compliant rules regardless of whether the CLSCompliantAttribute attribute is
used. For example, defining a static member in an interface violates a CLS rule. However, if you define a static (in C#) or
Shared (in Visual Basic) member in an interface, both the C# and Visual Basic compilers display an error message and fail to
compile the app.
The CLSCompliantAttribute attribute is marked with an AttributeUsageAttribute attribute that has a value of
System.AttributeTargets.All. This value allows you to apply the CLSCompliantAttribute attribute to any program
element, including assemblies, modules, types (classes, structures, enumerations, interfaces, and delegates), type
members (constructors, methods, properties, fields, and events), parameters, generic parameters, and return
values. However, in practice, you should apply the attribute only to assemblies, types, and type members.
Otherwise, compilers ignore the attribute and continue to generate compiler warnings whenever they encounter a
non-compliant parameter, generic parameter, or return value in your library's public interface.
The value of the CLSCompliantAttribute attribute is inherited by contained program elements. For example, if an
assembly is marked as CLS-compliant, its types are also CLS-compliant. If a type is marked as CLS-compliant, its
nested types and members are also CLS-compliant.
You can explicitly override the inherited compliance by applying the CLSCompliantAttribute attribute to a
contained program element. For example, you can use the CLSCompliantAttribute attribute with an isCompliant
value of false to define a non-compliant type in a compliant assembly, and you can use the attribute with an
isCompliant value of true to define a compliant type in a non-compliant assembly. You can also define non-
compliant members in a compliant type. However, a non-compliant type cannot have compliant members, so you
cannot use the attribute with an isCompliant value of true to override inheritance from a non-compliant type.
When you are developing components, you should always use the CLSCompliantAttribute attribute to indicate
whether your assembly, its types, and its members are CLS-compliant.
To create CLS-compliant components:
1. Use the CLSCompliantAttribute to mark you assembly as CLS-compliant.
2. Mark any publicly exposed types in the assembly that are not CLS-compliant as non-compliant.
3. Mark any publicly exposed members in CLS-compliant types as non-compliant.
4. Provide a CLS-compliant alternative for non-CLS-compliant members.
If you've successfully marked all your non-compliant types and members, your compiler should not emit any non-
compliance warnings. However, you should indicate which members are not CLS-compliant and list their CLS-
compliant alternatives in your product documentation.
The following example uses the CLSCompliantAttribute attribute to define a CLS-compliant assembly and a type,
CharacterUtilities , that has two non-CLS-compliant members. Because both members are tagged with the
CLSCompliant(false) attribute, the compiler produces no warnings. The class also provides a CLS-compliant
alternative for both methods. Ordinarily, we would just add two overloads to the ToUTF16 method to provide CLS-
compliant alternatives. However, because methods cannot be overloaded based on return value, the names of the
CLS-compliant methods are different from the names of the non-compliant methods.
using System;
using System.Text;
[assembly:CLSCompliant(true)]
if (chars.Length == 2) {
if (! Char.IsSurrogatePair(chars[0], chars[1]))
throw new ArgumentException("The array must contain a low and a high surrogate.");
else
return Char.ConvertToUtf32(chars[0], chars[1]);
}
else {
return Char.ConvertToUtf32(chars.ToString(), 0);
}
}
}
Imports System.Text
<Assembly:CLSCompliant(True)>
If you are developing an app rather than a library (that is, if you aren't exposing types or members that can be
consumed by other app developers), the CLS compliance of the program elements that your app consumes are of
interest only if your language does not support them. In that case, your language compiler will generate an error
when you try to use a non-CLS-compliant element.
Cross-Language Interoperability
Language independence has a number of possible meanings. One meaning, which is discussed in the article
Language Independence and Language-Independent Components, involves seamlessly consuming types written in
one language from an app written in another language. A second meaning, which is the focus of this article,
involves combining code written in multiple languages into a single .NET Framework assembly.
The following example illustrates cross-language interoperability by creating a class library named Utilities.dll that
includes two classes, NumericLib and StringLib . The NumericLib class is written in C#, and the StringLib class is
written in Visual Basic. Here's the source code for StringUtil.vb, which includes a single member, ToTitleCase , in
its StringLib class.
Imports System.Collections.Generic
Imports System.Runtime.CompilerServices
Sub New()
Dim words() As String = { "a", "an", "and", "of", "the" }
exclusions = New List(Of String)
exclusions.AddRange(words)
End Sub
<Extension()> _
Public Function ToTitleCase(title As String) As String
Dim words() As String = title.Split()
Dim result As String = String.Empty
Here's the source code for NumberUtil.cs, which defines a NumericLib class that has two members, IsEven and
NearZero .
using System;
To package the two classes in a single assembly, you must compile them into modules. To compile the Visual Basic
source code file into a module, use this command:
For more information about the command-line syntax of the Visual Basic compiler, see Building from the
Command Line.
To compile the C# source code file into a module, use this command:
For more information about the command-line syntax of the C# compiler, see Command-line Building With
csc.exe.
You then use the Link tool (Link.exe) to compile the two modules into an assembly:
The following example then calls the NumericLib.NearZero and StringLib.ToTitleCase methods. Note that both the
Visual Basic code and the C# code are able to access the methods in both classes.
using System;
Module Example
Public Sub Main()
Dim dbl As Double = 0.0 - Double.Epsilon
Console.WriteLine(NumericLib.NearZero(dbl))
To compile with C#, change the name of the compiler from vbc to csc, and change the file extension from .vb to
.cs:
See Also
CLSCompliantAttribute
Framework Libraries
8/10/2017 • 2 min to read • Edit Online
.NET has an expansive standard set of class libraries, referred to as either the base class libraries (core set) or
framework class libraries (complete set). These libraries provide implementations for many general and app-
specific types, algorithms and utility functionality. Both commercial and community libraries build on top of the
framework class libraries, providing easy to use off-the-shelf libraries for a wide set of computing tasks.
A subset of these libraries are provided with each .NET implementation. Base Class Library (BCL) APIs are expected
with any .NET implementation, both because developers will want them and because popular libraries will need
them to run. App-specific libraries above the BCL, such as ASP.NET, will not be available on all .NET
implementations.
Primitive Types
.NET includes a set of primitive types, which are used (to varying degrees) in all programs. These types contain
data, such as numbers, strings, bytes and arbitrary objects. The C# language includes keywords for these types. A
sample set of these types is listed below, with the matching C# keywords.
System.Object (object) - The ultimate base class in the CLR type system. It is the root of the type hierarchy.
System.Int16 (short) - A 16-bit signed integer type. The unsigned UInt16 also exists.
System.Int32 (int) - A 32-bit signed integer type. The unsigned UInt32 also exists.
System.Single (float) - A 32-bit floating-point type.
System.Decimal (decimal) - A 128-bit decimal type.
System.Byte (byte) - An unsigned 8-bit integer that represents a byte of memory.
System.Boolean (bool) - A boolean type that represents true or false .
System.Char (char) - A 16-bit numeric type that represents a Unicode character.
System.String (string) - Represents a series of characters. Different than a char[] , but enables indexing into
each individual char in the string .
Data Structures
.NET includes a set of data structures that are the workhorses of almost any .NET apps. These are mostly collections,
but also include other types.
Array - Represents an array of strongly types objects that can be accessed by index. Has a fixed size, per its
construction.
List<T> - Represents a strongly typed list of objects that can be accessed by index. Is automatically resized as
needed.
Dictionary<TKey,TValue> - Represents a collection of values that are indexed by a key. Values can be accessed
via key. Is automatically resized as needed.
Uri - Provides an object representation of a uniform resource identifier (URI) and easy access to the parts of the
URI.
DateTime - Represents an instant in time, typically expressed as a date and time of day.
Utility APIs
.NET includes a set of utility APIs that provide functionality for many important tasks.
HttpClient - An API for sending HTTP requests and receiving HTTP responses from a resource identified by a
URI.
XDocument - An API for loading, and querying XML documents with LINQ.
StreamReader - An API for reading files (StringWriter) Can be used to write files.
App-Model APIs
There are many app-models that can be used with .NET, provided by several companies.
ASP.NET - Provides a web framework for building Web sites and services. Supported on Windows, Linux and
macOS (depends on ASP.NET version).
.NET Framework Class Library Overview
7/29/2017 • 4 min to read • Edit Online
The .NET Framework includes classes, interfaces, and value types that expedite and optimize the development
process and provide access to system functionality. To facilitate interoperability between languages, most .NET
Framework types are CLS-compliant and can therefore be used from any programming language whose compiler
conforms to the common language specification (CLS).
The .NET Framework types are the foundation on which .NET applications, components, and controls are built. The
.NET Framework includes types that perform the following functions:
Represent base data types and exceptions.
Encapsulate data structures.
Perform I/O.
Access information about loaded types.
Invoke .NET Framework security checks.
Provide data access, rich client-side GUI, and server-controlled, client-side GUI.
The .NET Framework provides a rich set of interfaces, as well as abstract and concrete (non-abstract) classes. You
can use the concrete classes as is or, in many cases, derive your own classes from them. To use the functionality of
an interface, you can either create a class that implements the interface or derive a class from one of the .NET
Framework classes that implements the interface.
Naming Conventions
.NET Framework types use a dot syntax naming scheme that connotes a hierarchy. This technique groups related
types into namespaces so they can be searched and referenced more easily. The first part of the full name — up to
the rightmost dot — is the namespace name. The last part of the name is the type name. For example,
System.Collections.ArrayList represents the ArrayList type, which belongs to the System.Collections
namespace. The types in System.Collections can be used to manipulate collections of objects.
This naming scheme makes it easy for library developers extending the .NET Framework to create hierarchical
groups of types and name them in a consistent, informative manner. It also allows types to be unambiguously
identified by their full name (that is, by their namespace and type name), which prevents type name collisions.
Library developers are expected to use the following convention when creating names for their namespaces:
CompanyName.TechnologyName
For example, the namespace Microsoft.Word conforms to this guideline.
The use of naming patterns to group related types into namespaces is a very useful way to build and document
class libraries. However, this naming scheme has no effect on visibility, member access, inheritance, security, or
binding. A namespace can be partitioned across multiple assemblies and a single assembly can contain types from
multiple namespaces. The assembly provides the formal structure for versioning, deployment, security, loading, and
visibility in the common language runtime.
For more information on namespaces and type names, see Common Type System.
System Namespace
The System namespace is the root namespace for fundamental types in the .NET Framework. This namespace
includes classes that represent the base data types used by all applications: Object (the root of the inheritance
hierarchy), Byte, Char, Array, Int32, String, and so on. Many of these types correspond to the primitive data types
that your programming language uses. When you write code using .NET Framework types, you can use your
language's corresponding keyword when a .NET Framework base data type is expected.
The following table lists the base types that the .NET Framework supplies, briefly describes each type, and indicates
the corresponding type in Visual Basic, C#, C++, and JScript.
long
Not CLS-
compliant.
Not CLS-
compliant.
VISUAL BASIC JSCRIPT DATA
CATEGORY CLASS NAME DESCRIPTION DATA TYPE C# DATA TYPE C++ DATA TYPE TYPE
Not CLS-
compliant.
In addition to the base data types, the System namespace contains over 100 classes, ranging from classes that
handle exceptions to classes that deal with core runtime concepts, such as application domains and the garbage
collector. The System namespace also contains many second-level namespaces.
For more information about namespaces, browse the .NET Framework Class Library. The reference documentation
provides a brief overview of each namespace as well as a formal description of each type and its members.
See Also
Common Type System
.NET Framework Class Library
Overview
Working with Base Types in .NET
7/29/2017 • 1 min to read • Edit Online
This section describes .NET base type operations, including formatting, conversion, and common operations.
In This Section
Type Conversion in the .NET Framework
Describes how to convert from one type to another.
Formatting Types
Describes how to format strings using the string format specifiers.
Manipulating Strings
Describes how to manipulate and format strings.
Parsing Strings
Describes how to convert strings into .NET Framework types.
Related Sections
Common Type System
Describes types used by the .NET Framework.
Dates, Times, and Time Zones
Describes how to work with time zones and time zone conversions in time zone-aware applications.
.NET Class Libraries
8/5/2017 • 3 min to read • Edit Online
Class libraries are the shared library concept for .NET. They enable you to componentize useful functionality into
modules that can be used by multiple applications. They can also be used as a means of loading functionality that is
not needed or not known at application startup. Class libraries are described using the .NET Assembly file format.
There are three types of class libraries that you can use:
Platform-specific class libraries have access to all the APIs in a given platform (for example, .NET Framework,
Xamarin iOS), but can only be used by apps and libraries that target that platform.
Portable class libraries have access to a subset of APIs, and can be used by apps and libraries that target
multiple platforms.
.NET Core class libraries are a merger of the platform-specific and portable library concept into a single model
that provides the best of both.
Want to make your libraries multi-platform? Want to see how much work is required to make your application
compatible with other .NET implementations? The .NET Portability Analyzer is a tool that provides you with a
detailed report on how flexible your program is across .NET implementations by analyzing assemblies. The
Portability Analyzer is offered as a Visual Studio Extension and as a console app.
New targets
.NET Core: Has a modular design, employs side-by-side, and targets cross-platform scenarios. Side-by-side
allows you to adopt new .NET Core versions without breaking other apps.
ASP.NET Core: is a modern web-framework built on .NET Core thus giving developers the same benefits.
Universal Windows Platform: Improve performance of your Windows Store apps that run on x64 and ARM
machines by using .NET Native’s static compilation.
.NET Core + Platform Extensions: Includes the .NET Core APIs in addition to other APIs in the .NET ecosystem
such as WCF, ASP.NET Core, FSharp, and Azure.
.NET Standard + Platform Extensions: Includes the .NET Standard APIs in addition to other .NET ecosystem such
as WCF, ASP.NET Core, FSharp, and Azure.
After running the analysis, you will see your .NET Portability Report. Only types that are unsupported by a target
platform appear in the list and you can review recommendations in the Messages tab in the Error List. You can
also jump to problem areas directly from the Messages tab.
Don’t want to use Visual Studio? You can also use the Portability Analyzer from the command prompt. Just
download the API Portability Analyzer.
Type the following command to analyze the current directory: \...\ApiPort.exe analyze -f .
To analyze a specific list of .dll files, type the following command:
\...\ApiPort.exe analyze -f first.dll -f second.dll -f third.dll
Your .NET Portability Report is saved as an Excel file (.xlsx) in your current directory. The Details tab in the Excel
Workbook contains more information.
For more information on the .NET Portability Analyzer, visit the GitHub documentation and A Brief Look at the .NET
Portability Analyzer Channel 9 video.
Handling and throwing exceptions in .NET
7/29/2017 • 2 min to read • Edit Online
Applications must be able to handle errors that occur during execution in a consistent manner. .NET provides a
model for notifying applications of errors in a uniform way: .NET operations indicate failure by throwing exceptions.
Exceptions
An exception is any error condition or unexpected behavior that is encountered by an executing program.
Exceptions can be thrown because of a fault in your code or in code that you call (such as a shared library),
unavailable operating system resources, unexpected conditions that the runtime encounters (such as code that
cannot be verified), and so on. Your application can recover from some of these conditions, but not from others.
Although you can recover from most application exceptions, you cannot recover from most runtime exceptions.
In .NET, an exception is an object that inherits from the System.Exception class. An exception is thrown from an area
of code where a problem has occurred. The exception is passed up the stack until the application handles it or the
program terminates.
Common Exceptions
The following table lists some common exceptions with examples of what can cause them.
Exception Object Base class for all exceptions. None (use a derived class of
this exception).
IndexOutOfRangeException Exception Thrown by the runtime only Indexing an array outside its
when an array is indexed valid range:
improperly. arr[arr.Length+1]
EXCEPTION TYPE BASE TYPE DESCRIPTION EXAMPLE
ArgumentException Exception Base class for all argument None (use a derived class of
exceptions. this exception).
See Also
Exception Class and Properties
How to: Use the Try-Catch Block to Catch Exceptions
How to: Use Specific Exceptions in a Catch Block
How to: Explicitly Throw Exceptions
How to: Create User-Defined Exceptions
Using User-Filtered Exception Handlers
How to: Use Finally Blocks
Handling COM Interop Exceptions
Best Practices for Exceptions
To learn more about how exceptions work in .NET, see What Every Dev needs to Know About Exceptions in the
Runtime.
.NET Assembly File Format
8/10/2017 • 2 min to read • Edit Online
.NET defines a binary file format - "assembly" - that is used to fully-describe and contain .NET programs.
Assemblies are used for the programs themselves as well as any dependent libraries. A .NET program can be
executed as one of more assemblies, with no other required artifacts, beyond the appropriate .NET implementation.
Native dependencies, including operating system APIs, are a separate concern and are not contained within the
.NET assembly format, although are sometimes described with this format (for example, WinRT).
Each CLI component carries the metadata for declarations, implementations, and references specific to that
component. Therefore, the component-specific metadata is referred to as component metadata, and the
resulting component is said to be self-describing – from ECMA 335 I.9.1, Components and assemblies.
The format is fully specified and standardized as ECMA 335. All .NET compilers and runtimes use this format. The
presence of a documented and infrequently updated binary format has been a major benefit (arguably a
requirement) for interoperatibility. The format was last updated in a substantive way in 2005 (.NET 2.0) to
accommodate generics and processor architecture.
The format is CPU- and OS-agnostic. It has been used as part of .NET implementations that target many chips and
CPUs. While the format itself has Windows heritage, it is implementable on any operating system. It’s arguably
most significant choice for OS interoperability is that most values are stored in little-endian format. It doesn’t have
a specific affinity to machine pointer size (for example, 32-bit, 64-bit).
The .NET assembly format is also very descriptive about the structure of a given program or library. It describes the
internal components of an assembly, specifically: assembly references and types defined and their internal
structure. Tools or APIs can read and process this information for display or to make programmatic decisions.
Format
The .NET binary format is based on the Windows PE file format. In fact, .NET class libraries are conformant
Windows PEs, and appear on first glance to be Windows dynamic link libraries (DLLs) or application executables
(EXEs). This is a very useful characteristic on Windows, where they can masquerade as native executable binaries
and get some of the same treatment (for example, OS load, PE tools).
Assembly Headers from ECMA 335 II.25.1, Structure of the runtime file format.
This section of the documentation provides information about managing memory in .NET.
In This Section
Cleaning Up Unmanaged Resources
Describes how to properly manage and clean up unmanaged resources..
Garbage Collection
Provides information about the .NET garbage collector.
Related Sections
Development Guide
Generic Types (Generics) Overview
8/10/2017 • 3 min to read • Edit Online
We use generics all the time in C#, whether implicitly or explicitly. When you use LINQ in C#, did you ever notice
that you are working with IEnumerable? Or if you ever saw an online sample of a "generic repository" for talking to
databases using Entity Framework, did you see that most methods return IQueryable? You may have wondered
what the T is in these examples and why is it in there?
First introduced to the .NET Framework 2.0, generics involved changes to both the C# language and the Common
Language Runtime (CLR). Generics are essentially a "code template" that allows developers to define type-safe
data structures without committing to an actual data type. For example, List<T> is a Generic Collection that can be
declared and used with any type: List<int> , List<string> , List<Person> , etc.
So, what’s the point? Why are generics useful? In order to understand this, we need to take a look at a specific class
before and after adding generics. Let’s look at the ArrayList . In C# 1.0, the ArrayList elements were of type
object . This meant that any element that was added was silently converted into an object ; same thing happens
on reading the elements from the list (this process is known as boxing and unboxing respectively). Boxing and
unboxing have an impact of performance. More than that, however, there is no way to tell at compile time what is
the actual type of the data in the list. This makes for some fragile code. Generics solve this problem by providing
additional information the type of data each instance of list will contain. Put simply, you can only add integers to
List<int> and only add Persons to List<Person> , etc.
Generics are also available at runtime, or reified. This means the runtime knows what type of data structure you
are using and can store it in memory more efficiently.
Here is a small program that illustrates the efficiency of knowing the data structure type at runtime:
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
namespace GenericsExample {
class Program {
static void Main(string[] args) {
//generic list
List<int> ListGeneric = new List<int> { 5, 9, 1, 4 };
//non-generic list
ArrayList ListNonGeneric = new ArrayList { 5, 9, 1, 4 };
// timer for generic list sort
Stopwatch s = Stopwatch.StartNew();
ListGeneric.Sort();
s.Stop();
Console.WriteLine($"Generic Sort: {ListGeneric} \n Time taken: {s.Elapsed.TotalMilliseconds}ms");
The first thing you notice here is that sorting the generic list is significantly faster than for the non-generic list. You
might also notice that the type for the generic list is distinct ([System.Int32]) whereas the type for the non-generic
list is generalized. Because the runtime knows the generic List<int> is of type int, it can store the list elements in
an underlying integer array in memory while the non-generic ArrayList has to cast each list element as an object
as stored in an object array in memory. As shown through this example, the extra castings take up time and slow
down the list sort.
The last useful thing about the runtime knowing the type of your generic is a better debugging experience. When
you are debugging a generic in C#, you know what type each element is in your data structure. Without generics,
you would have no idea what type each element was.
Delegates define a type, which specify a particular method signature. A method (static or instance) that satisfies this
signature can be assigned to a variable of that type, then called directly (with the appropriate arguments) or passed
as an argument itself to another method and then called. The following example demonstrates delegate use.
Console.WriteLine(rev("a string"));
}
}
On line 4 we create a delegate type of a certain signature, in this case a method that takes a string parameter
and then returns a string parameter.
On line 6, we define the implementation of the delegate by providing a method that has the exact same
signature.
On line 13, the method is assigned to a type that conforms to the Reverse delegate.
Finally, on line 15 we invoke the delegate passing a string to be reversed.
In order to streamline the development process, .NET includes a set of delegate types that programmers can reuse
and not have to create new types. These are Func<> , Action<> and Predicate<> , and they can be used in various
places throughout the .NET APIs without the need to define new delegate types. Of course, there are some
differences between the three as you will see in their signatures which mostly have to do with the way they were
meant to be used:
Action<> is used when there is a need to perform an action using the arguments of the delegate.
Func<> is used usually when you have a transformation on hand, that is, you need to transform the arguments
of the delegate into a different result. Projections are a prime example of this.
Predicate<> is used when you need to determine if the argument satisfies the condition of the delegate. It can
also be written as a Func<T, bool> .
We can now take our example above and rewrite it using the Func<> delegate instead of a custom type. The
program will continue running exactly the same.
public class Program
{
Console.WriteLine(rev("a string"));
}
}
For this simple example, having a method defined outside of the Main() method seems a bit superfluous. It is
because of this that .NET Framework 2.0 introduced the concept of anonymous delegates. With their support you
are able to create "inline" delegates without having to specify any additional type or method. You simply inline the
definition of the delegate where you need it.
For an example, we are going to switch it up and use our anonymous delegate to filter out a list of only even
numbers and then print them to the console.
Notice the highlighted lines. As you can see, the body of the delegate is just a set of expressions, as any other
delegate. But instead of it being a separate definition, we’ve introduced it ad hoc in our call to the FindAll()
method of the List<T> type.
However, even with this approach, there is still much code that we can throw away. This is where lambda
expressions come into play.
Lambda expressions, or just "lambdas" for short, were introduced first in C# 3.0, as one of the core building blocks
of Language Integrated Query (LINQ). They are just a more convenient syntax for using delegates. They declare a
signature and a method body, but don’t have an formal identity of their own, unless they are assigned to a
delegate. Unlike delegates, they can be directly assigned as the left-hand side of event registration or in various
Linq clauses and methods.
Since a lambda expression is just another way of specifying a delegate, we should be able to rewrite the above
sample to use a lambda expression instead of an anonymous delegate.
If you take a look at the highlighted lines, you can see how a lambda expression looks like. Again, it is just a very
convenient syntax for using delegates, so what happens under the covers is similar to what happens with the
anonymous delegate.
Again, lambdas are just delegates, which means that they can be used as an event handler without any problems,
as the following code snippet illustrates.
public MainWindow()
{
InitializeComponent();
What is it?
LINQ provides language-level querying capabilities and a higher-order function API to C# and VB as a way to write
expressive, declarative code.
Language-level query syntax:
LINQ is Expressive
Imagine you have a list of pets, but want to convert it into a dictionary where you can access a pet directly by its
RFID value.
The intention behind the code is not to create a new Dictionary<int, Pet> and add to it via a loop, it is to convert
an existing list into a dictionary! LINQ preserves the intention whereas the imperative code does not.
Equivalent LINQ expression:
The code using LINQ is valuable because it evens the playing field between intent and code when reasoning as a
programmer. Another bonus is code brevity. Imagine reducing large portions of a codebase by 1/3 as done above.
Pretty sweet deal, right?
Writing code to manually traverse the XML document to perform this task would be far more challenging.
Interacting with XML isn’t the only thing you can do with LINQ Providers. Linq to SQL is a fairly bare-bones Object-
Relational Mapper (ORM) for an MSSQL Server Database. The JSON.NET library provides efficient JSON Document
traversal via LINQ. Furthermore, if there isn’t a library which does what you need, you can also write your own
LINQ Provider!
Isn’t the API syntax just a more concise way to do the query syntax?
No. The query syntax allows for the use the let clause, which allows you to introduce and bind a variable within the
scope of the expression, using it in subsequent pieces of the expression. Reproducing the same code with only the
API syntax can be done, but will most likely lead to code which is hard to read.
So this begs the question, should you just use the query syntax?
The answer to this question is yes if...
Your existing codebase already uses the query syntax
You need to scope variables within your queries due to complexity
You prefer the query syntax and it won’t distract from your codebase
The answer to this question is no if...
Your existing codebase already uses the API syntax
You have no need to scope variables within your queries
You prefer the API syntax and it won’t distract from your codebase
Essential Samples
For a truly comprehensive list of LINQ samples, visit 101 LINQ Samples.
The following is a quick demonstration of some of the essential pieces of LINQ. This is in no way comprehensive, as
LINQ provides significantly more functionality than what is showcased here.
The bread and butter - Where , Select , and Aggregate :
// Filtering a list
var germanShepards = dogs.Where(dog => dog.Breed == DogBreed.GermanShepard);
...
Ordering:
// Get driving directions, ordering by if it's toll-free before estimated driving time.
var results = DirectionsProcessor.GetDirections(start, end)
.OrderBy(direction => direction.HasNoTolls)
.ThenBy(direction => direction.EstimatedTime);
Finally, a more advanced sample: determining if the values of the properties of two instances of the same type
are equal (Borrowed and modified from this StackOverflow post):
public static bool PublicInstancePropertiesEqual<T>(this T self, T to, params string[] ignore) where T : class
{
if (self != null && to != null)
{
var type = typeof(T);
var ignoreList = new List<string>(ignore);
// Selects the properties which have unequal values into a sequence of those properties.
var unequalProperties = from pi in type.GetProperties(BindingFlags.Public | BindingFlags.Instance)
where !ignoreList.Contains(pi.Name)
let selfValue = type.GetProperty(pi.Name).GetValue(self, null)
let toValue = type.GetProperty(pi.Name).GetValue(to, null)
where selfValue != toValue && (selfValue == null ||
!selfValue.Equals(toValue))
select new { Prop = pi.Name, selfValue, toValue };
return !unequalProperties.Any();
}
PLINQ
PLINQ, or Parallel LINQ, is a parallel execution engine for LINQ expressions. In other words, a regular LINQ
expressions can be trivially parallelized across any number of threads. This is accomplished via a call to
AsParallel() preceding the expression.
return facebookUsers.AsParallel()
.Aggregate(seed, threadAccumulator, threadResultAccumulator, resultSelector);
}
This code will partition facebookUsers across system threads as necessary, sum up the total likes on each thread in
parallel, sum the results computed by each thread, and project that result into a nice string.
In diagram form:
Parallelizable CPU-bound jobs which can be easily expressed via LINQ (in other words, are pure functions and have
no side effects) are a great candidate for PLINQ. For jobs which do have a side effect, consider using the Task
Parallel Library.
Further Resources:
101 LINQ Samples
Linqpad, a playground environment and Database querying engine for C#/F#/VB
EduLinq, an e-book for learning how LINQ-to-objects is implemented
Common Type System & Common Language
Specification
8/5/2017 • 2 min to read • Edit Online
Again, two terms that are freely used in the .NET world, they actually are crucial to understand how a .NET
implementation enables multi-language development and to understand how it works.
CTS defines two main kinds of types that should be supported: reference and value types. Their names point to
their definitions.
Reference types’ objects are represented by a reference to the object’s actual value; a reference here is similar to a
pointer in C/C++. It simply refers to a memory location where the objects’ values are. This has a profound impact
on how these types are used. If you assign a reference type to a variable and then pass that variable into a method,
for instance, any changes to the object will be reflected on the main object; there is no copying.
Value types are the opposite, where the objects are represented by their values. If you assign a value type to a
variable, you are essentially copying a value of the object.
CTS defines several categories of types, each with their specific semantics and usage:
Classes
Structures
Enums
Interfaces
Delegates
CTS also defines all other properties of the types, such as access modifiers, what are valid type members, how
inheritance and overloading works and so on. Unfortunately, going deep into any of those is beyond the scope of
an introductory article such as this, but you can consult More resources section at the end for links to more in-
depth content that covers these topics.
More resources
Common Type System
Common Language Specification
Async Overview
7/29/2017 • 1 min to read • Edit Online
Not so long ago, apps got faster simply by buying a newer PC or server and then that trend stopped. In fact, it
reversed. Mobile phones appeared with 1ghz single core ARM chips and server workloads transitioned to VMs.
Users still want responsive UI and business owners want servers that scale with their business. The transition to
mobile and cloud and an internet-connected population of >3B users has resulted in a new set of software
patterns.
Client applications are expected to be always-on, always-connected and constantly responsive to user
interaction (for example, touch) with high app store ratings!
Services are expected to handle spikes in traffic by gracefully scaling up and down.
Async programming is a key technique that makes it straightforward to handle blocking I/O and concurrent
operations on multiple cores. .NET provides the capability for apps and services to be responsive and elastic with
easy-to-use, language-level asynchronous programming models in C#, VB, and F#.
What's next?
For a deep dive into async concepts and programming, see Async in depth and Task-based asynchronous
programming.
Async in depth
8/29/2017 • 9 min to read • Edit Online
Writing I/O- and CPU-bound asynchronous code is straightforward using the .NET Task-based async model. The
model is exposed by the Task and Task<T> types and the async and await keywords in C# and Visual Basic.
(Language-specific resources are found in the See also section.) This article explains how to use .NET async and
provides insight into the async framework used under the covers.
return client.GetStringAsync("http://www.dotnetfoundation.org");
}
The second example adds the use of the async and await keywords to operate on the task.
public async Task<string> GetFirstCharactersCountAsync(string url, int count)
{
// Execution is synchronous here
var client = new HttpClient();
The call to GetStringAsync() calls through lower-level .NET libraries (perhaps calling other async methods) until it
reaches a P/Invoke interop call into a native networking library. The native library may subsequently call into a
System API call (such as write() to a socket on Linux). A task object will be created at the native/managed
boundary, possibly using TaskCompletionSource. The task object will be passed up through the layers, possibly
operated on or directly returned, eventually returned to the initial caller.
In the second example above, a Task<T> object will be returned from GetStringAsync . The use of the await
keyword causes the method to return a newly created task object. Control returns to the caller from this location in
the GetFirstCharactersCountAsync method. The methods and properties of the Task<T> object enable callers to
monitor the progress of the task, which will complete when the remaining code in GetFirstCharactersCountAsync
has executed.
After the System API call, the request is now in kernel space, making its way to the networking subsystem of the
OS (such as /net in the Linux Kernel). Here the OS will handle the networking request asynchronously. Details
may be different depending on the OS used (the device driver call may be scheduled as a signal sent back to the
runtime, or a device driver call may be made and then a signal sent back), but eventually the runtime will be
informed that the networking request is in progress. At this time, the work for the device driver will either be
scheduled, in-progress, or already finished (the request is already out "over the wire") - but because this is all
happening asynchronously, the device driver is able to immediately handle something else!
For example, in Windows an OS thread makes a call to the network device driver and asks it to perform the
networking operation via an Interrupt Request Packet (IRP) which represents the operation. The device driver
receives the IRP, makes the call to the network, marks the IRP as "pending", and returns back to the OS. Because
the OS thread now knows that the IRP is "pending", it doesn't have any more work to do for this job and "returns"
back so that it can be used to perform other work.
When the request is fulfilled and data comes back through the device driver, it notifies the CPU of new data
received via an interrupt. How this interrupt gets handled will vary depending on the OS, but eventually the data
will be passed through the OS until it reaches a system interop call (for example, in Linux an interrupt handler will
schedule the bottom half of the IRQ to pass the data up through the OS asynchronously). Note that this also
happens asynchronously! The result is queued up until the next available thread is able execute the async method
and "unwrap" the result of the completed task.
Throughout this entire process, a key takeaway is that no thread is dedicated to running the task. Although
work is executed in some context (that is, the OS does have to pass data to a device driver and respond to an
interrupt), there is no thread dedicated to waiting for data from the request to come back. This allows the system
to handle a much larger volume of work rather than waiting for some I/O call to finish.
Although the above may seem like a lot of work to be done, when measured in terms of wall clock time, it’s
miniscule compared to the time it takes to do the actual I/O work. Although not at all precise, a potential timeline
for such a call would look like this:
0-1
————————————————————————————————————————————————–2-
3
Time spent from points 0 to 1 is everything up until an async method yields control to its caller.
Time spent from points 1 to 2 is the time spent on I/O, with no CPU cost.
Finally, time spent from points 2 to 3 is passing control back (and potentially a value) to the async method, at
which point it is executing again.
What does this mean for a server scenario?
This model works well with a typical server scenario workload. Because there are no threads dedicated to blocking
on unfinished tasks, the server threadpool can service a much higher volume of web requests.
Consider two servers: one that runs async code, and one that does not. For the purpose of this example, each
server only has 5 threads available to service requests. Note that these numbers are imaginarily small and serve
only in a demonstrative context.
Assume both servers receive 6 concurrent requests. Each request performs an I/O operation. The server without
async code has to queue up the 6th request until one of the 5 threads have finished the I/O-bound work and
written a response. At the point that the 20th request comes in, the server might start to slow down, because the
queue is getting too long.
The server with async code running on it still queues up the 6th request, but because it uses async and await ,
each of its threads are freed up when the I/O-bound work starts, rather than when it finishes. By the time the 20th
request comes in, the queue for incoming requests will be far smaller (if it has anything in it at all), and the server
won't slow down.
Although this is a contrived example, it works in a very similar fashion in the real world. In fact, you can expect a
server to be able to handle an order of magnitude more requests using async and await than if it were
dedicating a thread for each request it receives.
What does this mean for client scenario?
The biggest gain for using async and await for a client app is an increase in responsiveness. Although you can
make an app responsive by spawning threads manually, the act of spawning a thread is an expensive operation
relative to just using async and await . Especially for something like a mobile game, impacting the UI thread as
little as possible where I/O is concerned is crucial.
More importantly, because I/O-bound work spends virtually no time on the CPU, dedicating an entire CPU thread
to perform barely any useful work would be a poor use of resources.
Additionally, dispatching work to the UI thread (such as updating a UI) is very simple with async methods, and
does not require extra work (such as calling a thread-safe delegate).
// Note that at this point, you can do some other work concurrently,
// as CalculateResult() is still executing!
return result;
}
CalculateResult() executes on the thread it was called on. When it calls Task.Run , it queues the expensive CPU-
bound operation, DoExpensiveCalculation() , on the thread pool and receives a Task<int> handle.
DoExpensiveCalculation() is eventually run concurrently on the next available thread, likely on another CPU core.
It's possible to do concurrent work while DoExpensiveCalculation() is busy on another thread, because the thread
which called CalculateResult() is still executing.
Once await is encountered, the execution of CalculateResult() is yielded to its caller, allowing other work to be
done with the current thread while DoExpensiveCalculation() is churning out a result. Once it has finished, the
result is queued up to run on the main thread. Eventually, the main thread will return to executing
CalculateResult() , at which point it will have the result of DoExpensiveCalculation() .
See also
Asynchronous programming in C#
Async Programming in F#
Asynchronous Programming with Async and Await (Visual Basic)
Asynchronous Programming Patterns
7/29/2017 • 2 min to read • Edit Online
The .NET Framework provides three patterns for performing asynchronous operations:
Asynchronous Programming Model (APM) pattern (also called the IAsyncResult pattern), where
asynchronous operations require Begin and End methods (for example, BeginWrite and EndWrite for
asynchronous write operations). This pattern is no longer recommended for new development. For more
information, see Asynchronous Programming Model (APM).
Event-based Asynchronous Pattern (EAP), which requires a method that has the Async suffix, and also
requires one or more events, event handler delegate types, and EventArg -derived types. EAP was
introduced in the .NET Framework 2.0. It is no longer recommended for new development. For more
information, see Event-based Asynchronous Pattern (EAP).
Task-based Asynchronous Pattern (TAP), which uses a single method to represent the initiation and
completion of an asynchronous operation. TAP was introduced in the .NET Framework 4 and is the
recommended approach to asynchronous programming in the .NET Framework. The async and await
keywords in C# and the Async and Await operators in Visual Basic Language add language support for TAP.
For more information, see Task-based Asynchronous Pattern (TAP).
Comparing Patterns
For a quick comparison of how the three patterns model asynchronous operations, consider a Read method that
reads a specified amount of data into a provided buffer starting at a specified offset:
The APM counterpart of this method would expose the BeginRead and EndRead methods:
The EAP counterpart would expose the following set of types and members:
The TAP counterpart would expose the following single ReadAsync method:
public class MyClass
{
public Task<int> ReadAsync(byte [] buffer, int offset, int count);
}
For a comprehensive discussion of TAP, APM, and EAP, see the links provided in the next section.
Related topics
TITLE DESCRIPTION
Asynchronous Programming Model (APM) Describes the legacy model that uses the IAsyncResult
interface to provide asynchronous behavior. This model is no
longer recommended for new development.
Event-based Asynchronous Pattern (EAP) Describes the event-based legacy model for providing
asynchronous behavior. This model is no longer recommended
for new development.
Task-based Asynchronous Pattern (TAP) Describes the new asynchronous pattern based on the
System.Threading.Tasks namespace. This model is the
recommended approach to asynchronous programming in the
.NET Framework 4 and later versions.
See also
Asynchronous programming in C#
Async Programming in F#
Asynchronous Programming with Async and Await (Visual Basic)
Native Interoperability
8/5/2017 • 10 min to read • Edit Online
In this document, we will dive a little bit deeper into all three ways of doing "native interoperability" that are
available using .NET.
There are a few of reasons why you would want to call into native code:
Operating Systems come with a large volume of APIs that are not present in the managed class libraries. A
prime example for this would be access to hardware or operating system management functions.
Communicating with other components that have or can produce C-style ABIs (native ABIs). This covers, for
example, Java code that is exposed via Java Native Interface (JNI) or any other managed language that could
produce a native component.
On Windows, most of the software that gets installed, such as Microsoft Office suite, registers COM
components that represent their programs and allow developers to automate them or use them. This also
requires native interoperability.
Of course, the list above does not cover all of the potential situations and scenarios in which the developer would
want/like/need to interface with native components. .NET class library, for instance, uses the native interoperability
support to implement a fair number of its APIs, like console support and manipulation, file system access and
others. However, it is important to note that there is an option, should one need it.
NOTE
Most of the examples in this document will be presented for all three supported platforms for .NET Core (Windows, Linux
and macOS). However, for some short and illustrative examples, just one sample is shown that uses Windows filenames and
extensions (that is, "dll" for libraries). This does not mean that those features are not available on Linux or macOS, it was
done merely for convenience sake.
The example above is pretty simple, but it does show off what is needed to invoke unmanaged functions from
managed code. Let’s step through the example:
Line #1 shows the using statement for the System.Runtime.InteropServices which is the namespace that holds
all of the items we need.
Line #5 introduces the DllImport attribute. This attribute is crucial, as it tells the runtime that it should load the
unmanaged DLL. This is the DLL into which we wish to invoke.
Line #6 is the crux of the P/Invoke work. It defines a managed method that has the exact same signature as
the unmanaged one. The declaration has a new keyword that you can notice, extern , which tells the runtime
this is an external method, and that when you invoke it, the runtime should find it in the DLL specified in
DllImport attribute.
The rest of the example is just invoking the method as you would any other managed method.
The sample is similar for macOS. One thing that needs to change is, of course, the name of the library in the
DllImport attribute, as macOS has a different scheme of naming dynamic libraries. The sample below uses the
getpid(2) function to get the process ID of the application and print it out to the console.
using System;
using System.Runtime.InteropServices;
namespace PInvokeSamples {
public static class Program {
// Import the libc and define the method corresponding to the native function.
[DllImport("libSystem.dylib")]
private static extern int getpid();
It is similar on Linux, of course. The function name is same, since getpid(2) is POSIX system call.
using System;
using System.Runtime.InteropServices;
namespace PInvokeSamples {
public static class Program {
// Import the libc and define the method corresponding to the native function.
[DllImport("libc.so.6")]
private static extern int getpid();
using System;
using System.Runtime.InteropServices;
namespace ConsoleApplication1 {
class Program {
// Define the implementation of the delegate; here, we simply output the window handle.
static bool OutputWindow(IntPtr hwnd, IntPtr lParam) {
Console.WriteLine(hwnd.ToInt64());
return true;
}
Before we walk through our example, it is good to go over the signatures of the unmanaged functions we need to
work with. The function we want to call to enumerate all of the windows has the following signature:
BOOL EnumWindows (WNDENUMPROC lpEnumFunc, LPARAM lParam);
The first parameter is a callback. The said callback has the following signature:
BOOL CALLBACK EnumWindowsProc (HWND hwnd, LPARAM lParam);
With this in mind, let’s walk through the example:
Line #8 in the example defines a delegate that matches the signature of the callback from unmanaged code.
Notice how the LPARAM and HWND types are represented using IntPtr in the managed code.
Lines #10 and #11 introduce the EnumWindows function from the user32.dll library.
Lines #13 - 16 implement the delegate. For this simple example, we just want to output the handle to the
console.
Finally, in line #19 we invoke the external method and pass in the delegate.
The Linux and macOS examples are shown below. For them, we use the ftw function that can be found in libc ,
the C library. This function is used to traverse directory hierarchies and it takes a pointer to a function as one of its
parameters. The said function has the following signature:
int (*fn) (const char *fpath, const struct stat *sb, int typeflag) .
using System;
using System.Runtime.InteropServices;
namespace PInvokeSamples {
public static class Program {
// Define a delegate that has the same signature as the native function.
delegate int DirClbk(string fName, StatClass stat, int typeFlag);
// Import the libc and define the method to represent the native function.
[DllImport("libc.so.6")]
static extern int ftw(string dirpath, DirClbk cl, int descriptors);
macOS example uses the same function, and the only difference is the argument to the DllImport attribute, as
macOS keeps libc in a different place.
using System;
using System.Runtime.InteropServices;
namespace PInvokeSamples {
public static class Program {
// Define a delegate that has the same signature as the native function.
delegate int DirClbk(string fName, StatClass stat, int typeFlag);
// Import the libc and define the method to represent the native function.
[DllImport("libSystem.dylib")]
static extern int ftw(string dirpath, DirClbk cl, int descriptors);
Both of the above examples depend on parameters, and in both cases, the parameters are given as managed types.
Runtime does the "right thing" and processes these into its equivalents on the other side. Since this process is
really important to writing quality native interop code, let’s take a look at what happens when the runtime
marshals the types.
Type marshalling
Marshalling is the process of transforming types when they need to cross the managed boundary into native and
vice versa.
The reason marshalling is needed is because the types in the managed and unmanaged code are different. In
managed code, for instance, you have a String , while in the unmanaged world strings can be Unicode ("wide"),
non-Unicode, null-terminated, ASCII, etc. By default, the P/Invoke subsystem will try to do the Right Thing based on
the default behavior which you can see on MSDN. However, for those situations where you need extra control, you
can employ the MarshalAs attribute to specify what is the expected type on the unmanaged side. For instance, if
we want the string to be sent as a null-terminated ANSI string, we could do it like this:
[DllImport("somenativelibrary.dll")]
static extern int MethodA([MarshalAs(UnmanagedType.LPStr)] string parameter);
[DllImport("kernel32.dll")]
static extern void GetSystemTime(SystemTime systemTime);
[StructLayout(LayoutKind.Sequential)]
class SystemTime {
public ushort Year;
public ushort Month;
public ushort DayOfWeek;
public ushort Day;
public ushort Hour;
public ushort Minute;
public ushort Second;
public ushort Milsecond;
}
The example above shows off a simple example of calling into GetSystemTime() function. The interesting bit is on
line 4. The attribute specifies that the fields of the class should be mapped sequentially to the struct on the other
(unmanaged) side. This means that the naming of the fields is not important, only their order is important, as it
needs to correspond to the unmanaged struct, shown below:
We already saw the Linux and macOS example for this in the previous example. It is shown again below.
[StructLayout(LayoutKind.Sequential)]
public class StatClass {
public uint DeviceID;
public uint InodeNumber;
public uint Mode;
public uint HardLinks;
public uint UserID;
public uint GroupID;
public uint SpecialDeviceID;
public ulong Size;
public ulong BlockSize;
public uint Blocks;
public long TimeLastAccess;
public long TimeLastModification;
public long TimeLastStatusChange;
}
The StatClass class represents a structure that is returned by the stat system call on UNIX systems. It represents
information about a given file. The class above is the stat struct representation in managed code. Again, the fields
in the class have to be in the same order as the native struct (you can find these by perusing man pages on your
favorite UNIX implementation) and they have to be of the same underlying type.
More resources
PInvoke.net wiki an excellent Wiki with information on common Win32 APIs and how to call them.
P/Invoke on MSDN
Mono documentation on P/Invoke
Collections and Data Structures
7/29/2017 • 5 min to read • Edit Online
Similar data can often be handled more efficiently when stored and manipulated as a collection. You can use the
System.Array class or the classes in the System.Collections, System.Collections.Generic,
System.Collections.Concurrent, System.Collections.Immutable namespaces to add, remove, and modify either
individual elements or a range of elements in a collection.
There are two main types of collections; generic collections and non-generic collections. Generic collections were
added in the .NET Framework 2.0 and provide collections that are type-safe at compile time. Because of this,
generic collections typically offer better performance. Generic collections accept a type parameter when they are
constructed and do not require that you cast to and from the Object type when you add or remove items from the
collection. In addition, most generic collections are supported in Windows Store apps. Non-generic collections
store items as Object, require casting, and most are not supported for Windows Store app development. However,
you may see non-generic collections in older code.
Starting with the .NET Framework 4, the collections in the System.Collections.Concurrent namespace provide
efficient thread-safe operations for accessing collection items from multiple threads. The immutable collection
classes in the System.Collections.Immutable namespace (NuGet package) are inherently thread-safe because
operations are performed on a copy of the original collection and the original collection cannot be modified.
Choosing a collection
In general, you should use generic collections. The following table describes some common collection scenarios
and the collection classes you can use for those scenarios. If you are new to generic collections, this table will help
you choose the generic collection that works the best for your task.
ImmutableDictionary(TKey,
TValue) Class
ImmutableQueue(T) Class
ImmutableStack(T) Class
GENERIC COLLECTION NON-GENERIC COLLECTION THREAD-SAFE OR IMMUTABLE
I WANT TO… OPTION(S) OPTION(S) COLLECTION OPTION(S)
ImmutableSortedSet(T)
Class
System.Collections.Generic.S ImmutableSortedSet(T)
Class
ortedSet<T>
Related Topics
TITLE DESCRIPTION
Selecting a Collection Class Describes the different collections and helps you select one for
your scenario.
Commonly Used Collection Types Describes commonly used generic and nongeneric collection
types such as System.Array,
System.Collections.Generic.List<T>, and
System.Collections.Generic.Dictionary<TKey,TValue>.
When to Use Generic Collections Discusses the use of generic collection types.
Comparisons and Sorts Within Collections Discusses the use of equality comparisons and sorting
comparisons in collections.
Hashtable and Dictionary Collection Types Describes the features of generic and non-generic hash-based
dictionary types.
The .NET Framework supports the standard numeric integral and floating-point primitives, as well as BigInteger, an
integral type with no theoretical upper or lower bound, Complex, a type that represents complex numbers, and a
set of SIMD-enabled vector types in the System.Numerics namespace.
In addition, System.Numerics.Vectors, the SIMD-enabled library of vectory types, was released as a NuGet package.
Integral types
The .NET Framework supports both signed and unsigned integers ranging from one byte to eight bytes in length.
The following table lists the integral types and their size, indicates whether they are signed or unsigned, and
documents their range. All integers are value types.
Each integral type supports a standard set of arithmetic, comparison, equality, explicit conversion, and implicit
conversion operators. Each integer also includes methods to perform equality comparisons and relative
comparisons, to convert the string representation of a number to that integer, and to convert an integer to its string
representation. Some additional mathematical operations beyond those handled by the standard operators, such as
rounding and identifying the smaller or larger value of two integers, are available from the Math class. You can also
work with the individual bits in an integer value by using the BitConverter class.
Note that the unsigned integral types are not CLS-compliant. For more information, see Language Independence
and Language-Independent Components.
Floating-point types
The .NET Framework includes three primitive floating point types, which are listed in the following table.
TYPE SIZE (IN BYTES) MINIMUM MAXIMUM
System.Decimal 16 - 79,228,162,514,264,337,593
79,228,162,514,264,337,59 ,543,950,335
3,543,950,335
Each floating-point type supports a standard set of arithmetic, comparison, equality, explicit conversion, and
implicit conversion operators. Each also includes methods to perform equality comparisons and relative
comparisons, to convert the string representation of a floating-point number, and to convert a floating-point
number to its string representation. Some additional mathematical, algebraic, and trigonometric operations are
available from the Math class. You can also work with the individual bits in Double and Single values by using the
BitConverter class. The System.Decimal structure has its own methods, System.Decimal.GetBits and
System.Decimal.Decimal(Int32[]), for working with a decimal value's individual bits, as well as its own set of
methods for performing some additional mathematical operations.
The Double and Single types are intended to be used for values that by their nature are imprecise (such as the
distance between two stars in the solar system) and for applications in which a high degree of precision and small
rounding error is not required. You should use the System.Decimal type for cases in which greater precision is
required and rounding error is undesirable,
BigInteger
System.Numerics.BigInteger is an immutable type that represents an arbitrarily large integer whose value in theory
has no upper or lower bounds. The methods of the BigInteger type closely parallel those of the other integral types.
Complex
The Complex type represents a complex number, that is, a number with a real number part and an imaginary
number part. It supports a standard set of arithmetic, comparison, equality, explicit conversion, and implicit
conversion operators, as well as mathematical, algebraic, and trigonometric methods.
See Also
Application Essentials
Dates, times, and time zones
7/29/2017 • 2 min to read • Edit Online
In addition to the basic DateTime structure, .NET provides the following classes that support working with time
zones:
TimeZone
Use this class to work with the system's local time zone and the Coordinated Universal Time (UTC) zone.The
functionality of the TimeZone class is largely superseded by the TimeZoneInfo class.
TimeZoneInfo
Use this class to work with any time zone that is predefined on a system, to create new time zones, and to
easily convert dates and times from one time zone to another. For new development, use the TimeZoneInfo
class instead of the TimeZone class.
DateTimeOffset
Use this structure to work with dates and times whose offset (or difference) from UTC is known. The
DateTimeOffset structure combines a date and time value with that time's offset from UTC. Because of its
relationship to UTC, an individual date and time value unambiguously identifies a single point in time. This
makes a DateTimeOffset value more portable from one computer to another than a DateTime value.
This section of the documentation provides the information that you need to work with time zones and to create
time zone-aware applications that can convert dates and times from one time zone to another.
In this section
Time zone overview Discusses the terminology, concepts, and issues involved in creating time zone-aware
applications.
Choosing between DateTime, DateTimeOffset, TimeSpan, and TimeZoneInfo Discusses when to use the DateTime,
DateTimeOffset, and TimeZoneInfo types when working with date and time data.
Finding the time zones defined on a local system Describes how to enumerate the time zones found on a local
system.
How to: Enumerate time zones present on a computer Provides examples that enumerate the time zones defined in
a computer's registry and that let users select a predefined time zone from a list.
How to: Access the predefined UTC and local time zone objects Describes how to access Coordinated Universal
Time and the local time zone.
How to: Instantiate a TimeZoneInfo object Describes how to instantiate a TimeZoneInfo object from the local
system registry.
Instantiating a DateTimeOffset object Discusses the ways in which a DateTimeOffset object can be instantiated, and
the ways in which a DateTime value can be converted to a DateTimeOffset value.
How to: Create time zones without adjustment rules Describes how to create a custom time zone that does not
support the transition to and from daylight saving time.
How to: Create time zones with adjustment rules Describes how to create a custom time zone that supports one or
more transitions to and from daylight saving time.
Saving and restoring time zones Describes TimeZoneInfo support for serialization and deserialization of time zone
data and illustrates some of the scenarios in which these features can be used.
How to: Save time zones to an embedded resource Describes how to create a custom time zone and save its
information in a resource file.
How to: Restore time zones from an embedded resource Describes how to instantiate custom time zones that have
been saved to an embedded resource file.
Performing arithmetic operations with dates and times Discusses the issues involved in adding, subtracting, and
comparing DateTime and DateTimeOffset values.
How to: Use time zones in date and time arithmetic Discusses how to perform date and time arithmetic that reflects
a time zone's adjustment rules.
Converting between DateTime and DateTimeOffset Describes how to convert between DateTime and
DateTimeOffset values.
Converting times between time zones Describes how to convert times from one time zone to another.
How to: Resolve ambiguous times Describes how to resolve an ambiguous time by mapping it to the time zone's
standard time.
How to: Let users resolve ambiguous times Describes how to let a user determine the mapping between an
ambiguous local time and Coordinated Universal Time.
Reference
System.TimeZoneInfo
Handling and Raising Events
7/29/2017 • 7 min to read • Edit Online
Events in the .NET Framework are based on the delegate model. The delegate model follows the observer design
pattern, which enables a subscriber to register with, and receive notifications from, a provider. An event sender
pushes a notification that an event has happened, and an event receiver receives that notification and defines a
response to it. This article describes the major components of the delegate model, how to consume events in
applications, and how to implement events in your code.
For information about handling events in Windows 8.x Store apps, see Events and routed events overview
(Windows store apps).
Events
An event is a message sent by an object to signal the occurrence of an action. The action could be caused by user
interaction, such as a button click, or it could be raised by some other program logic, such as changing a property’s
value. The object that raises the event is called the event sender. The event sender doesn't know which object or
method will receive (handle) the events it raises. The event is typically a member of the event sender; for example,
the Click event is a member of the Button class, and the PropertyChanged event is a member of the class that
implements the INotifyPropertyChanged interface.
To define an event, you use the event (in C#) or Event (in Visual Basic) keyword in the signature of your event
class, and specify the type of delegate for the event. Delegates are described in the next section.
Typically, to raise an event, you add a method that is marked as protected and virtual (in C#) or Protected and
Overridable (in Visual Basic). Name this method On EventName; for example, OnDataReceived . The method
should take one parameter that specifies an event data object. You provide this method to enable derived classes
to override the logic for raising the event. A derived class should always call the On EventName method of the
base class to ensure that registered delegates receive the event.
The following example shows how to declare an event named ThresholdReached . The event is associated with the
EventHandler delegate and raised in a method named OnThresholdReached .
class Counter
{
public event EventHandler ThresholdReached;
Delegates
A delegate is a type that holds a reference to a method. A delegate is declared with a signature that shows the
return type and parameters for the methods it references, and can hold references only to methods that match its
signature. A delegate is thus equivalent to a type-safe function pointer or a callback. A delegate declaration is
sufficient to define a delegate class.
Delegates have many uses in the .NET Framework. In the context of events, a delegate is an intermediary (or
pointer-like mechanism) between the event source and the code that handles the event. You associate a delegate
with an event by including the delegate type in the event declaration, as shown in the example in the previous
section. For more information about delegates, see the Delegate class.
The .NET Framework provides the EventHandler and EventHandler<TEventArgs> delegates to support most event
scenarios. Use the EventHandler delegate for all events that do not include event data. Use the
EventHandler<TEventArgs> delegate for events that include data about the event. These delegates have no return
type value and take two parameters (an object for the source of the event and an object for event data).
Delegates are multicast, which means that they can hold references to more than one event-handling method. For
details, see the Delegate reference page. Delegates provide flexibility and fine-grained control in event handling. A
delegate acts as an event dispatcher for the class that raises the event by maintaining a list of registered event
handlers for the event.
For scenarios where the EventHandler and EventHandler<TEventArgs> delegates do not work, you can define a
delegate. Scenarios that require you to define a delegate are very rare, such as when you must work with code that
does not recognize generics. You mark a delegate with the delegate in (C#) and Delegate (in Visual Basic)
keyword in the declaration. The following example shows how to declare a delegate named
ThresholdReachedEventHandler .
Event Data
Data that is associated with an event can be provided through an event data class. The .NET Framework provides
many event data classes that you can use in your applications. For example, the SerialDataReceivedEventArgs class
is the event data class for the System.IO.Ports.SerialPort.DataReceived event. The .NET Framework follows a
naming pattern of ending all event data classes with EventArgs . You determine which event data class is
associated with an event by looking at the delegate for the event. For example, the
SerialDataReceivedEventHandler delegate includes the SerialDataReceivedEventArgs class as one of its parameters.
The EventArgs class is the base type for all event data classes. EventArgs is also the class you use when an event
does not have any data associated with it. When you create an event that is only meant to notify other classes that
something happened and does not need to pass any data, include the EventArgs class as the second parameter in
the delegate. You can pass the System.EventArgs.Empty value when no data is provided. The EventHandler
delegate includes the EventArgs class as a parameter.
When you want to create a customized event data class, create a class that derives from EventArgs, and then
provide any members needed to pass data that is related to the event. Typically, you should use the same naming
pattern as the .NET Framework and end your event data class name with EventArgs .
The following example shows an event data class named ThresholdReachedEventArgs . It contains properties that are
specific to the event being raised.
Event Handlers
To respond to an event, you define an event handler method in the event receiver. This method must match the
signature of the delegate for the event you are handling. In the event handler, you perform the actions that are
required when the event is raised, such as collecting user input after the user clicks a button. To receive
notifications when the event occurs, your event handler method must subscribe to the event.
The following example shows an event handler method named c_ThresholdReached that matches the signature for
the EventHandler delegate. The method subscribes to the ThresholdReached event.
class Program
{
static void Main(string[] args)
{
Counter c = new Counter();
c.ThresholdReached += c_ThresholdReached;
Sub Main()
Dim c As Counter = New Counter()
AddHandler c.ThresholdReached, AddressOf c_ThresholdReached
Related Topics
TITLE DESCRIPTION
How to: Raise and Consume Events Contains examples of raising and consuming events.
How to: Handle Multiple Events Using Event Properties Shows how to use event properties to handle multiple events.
Observer Design Pattern Describes the design pattern that enables a subscriber to
register with, and receive notifications from, a provider.
How to: Consume Events in a Web Forms Application Shows how to handle an event that is raised by a Web Forms
control.
See Also
EventHandler
EventHandler<TEventArgs>
EventArgs
Delegate
Events and routed events overview (Windows store apps)
Events (Visual Basic)
Events (C# Programming Guide)
Managed Execution Process
7/29/2017 • 7 min to read • Edit Online
The managed execution process includes the following steps, which are discussed in detail later in this topic:
1. Choosing a compiler.
To obtain the benefits provided by the common language runtime, you must use one or more language
compilers that target the runtime.
2. Compiling your code to MSIL.
Compiling translates your source code into Microsoft intermediate language (MSIL) and generates the
required metadata.
3. Compiling MSIL to native code.
At execution time, a just-in-time (JIT) compiler translates the MSIL into native code. During this compilation,
code must pass a verification process that examines the MSIL and metadata to find out whether the code
can be determined to be type safe.
4. Running code.
The common language runtime provides the infrastructure that enables execution to take place and
services that can be used during execution.
Choosing a Compiler
To obtain the benefits provided by the common language runtime (CLR), you must use one or more language
compilers that target the runtime, such as Visual Basic, C#, Visual C++, F#, or one of many third-party compilers
such as an Eiffel, Perl, or COBOL compiler.
Because it is a multilanguage execution environment, the runtime supports a wide variety of data types and
language features. The language compiler you use determines which runtime features are available, and you
design your code using those features. Your compiler, not the runtime, establishes the syntax your code must use.
If your component must be completely usable by components written in other languages, your component's
exported types must expose only language features that are included in the Language Independence and
Language-Independent Components (CLS). You can use the CLSCompliantAttribute attribute to ensure that your
code is CLS-compliant. For more information, see Language Independence and Language-Independent
Components.
Back to top
Compiling to MSIL
When compiling to managed code, the compiler translates your source code into Microsoft intermediate language
(MSIL), which is a CPU-independent set of instructions that can be efficiently converted to native code. MSIL
includes instructions for loading, storing, initializing, and calling methods on objects, as well as instructions for
arithmetic and logical operations, control flow, direct memory access, exception handling, and other operations.
Before code can be run, MSIL must be converted to CPU-specific code, usually by a just-in-time (JIT) compiler.
Because the common language runtime supplies one or more JIT compilers for each computer architecture it
supports, the same set of MSIL can be JIT-compiled and run on any supported architecture.
When a compiler produces MSIL, it also produces metadata. Metadata describes the types in your code, including
the definition of each type, the signatures of each type's members, the members that your code references, and
other data that the runtime uses at execution time. The MSIL and metadata are contained in a portable executable
(PE) file that is based on and that extends the published Microsoft PE and common object file format (COFF) used
historically for executable content. This file format, which accommodates MSIL or native code as well as metadata,
enables the operating system to recognize common language runtime images. The presence of metadata in the
file together with MSIL enables your code to describe itself, which means that there is no need for type libraries or
Interface Definition Language (IDL). The runtime locates and extracts the metadata from the file as needed during
execution.
Back to top
Running Code
The common language runtime provides the infrastructure that enables managed execution to take place and
services that can be used during execution. Before a method can be run, it must be compiled to processor-specific
code. Each method for which MSIL has been generated is JIT-compiled when it is called for the first time, and then
run. The next time the method is run, the existing JIT-compiled native code is run. The process of JIT-compiling and
then running the code is repeated until execution is complete.
During execution, managed code receives services such as garbage collection, security, interoperability with
unmanaged code, cross-language debugging support, and enhanced deployment and versioning support.
In Microsoft Windows XP and Windows Vista, the operating system loader checks for managed modules by
examining a bit in the COFF header. The bit being set denotes a managed module. If the loader detects managed
modules, it loads mscoree.dll, and _CorValidateImage and _CorImageUnloading notify the loader when the
managed module images are loaded and unloaded. _CorValidateImage performs the following actions:
1. Ensures that the code is valid managed code.
2. Changes the entry point in the image to an entry point in the runtime.
On 64-bit Windows, _CorValidateImage modifies the image that is in memory by transforming it from PE32 to
PE32+ format.
Back to top
See Also
Overview
Language Independence and Language-Independent Components
Metadata and Self-Describing Components
Ilasm.exe (IL Assembler)
Security
Interoperating with Unmanaged Code
Deployment
Assemblies in the Common Language Runtime
Application Domains
Metadata and Self-Describing Components
7/29/2017 • 8 min to read • Edit Online
In the past, a software component (.exe or .dll) that was written in one language could not easily use a software
component that was written in another language. COM provided a step towards solving this problem. The .NET
Framework makes component interoperation even easier by allowing compilers to emit additional declarative
information into all modules and assemblies. This information, called metadata, helps components to interact
seamlessly.
Metadata is binary information describing your program that is stored either in a common language runtime
portable executable (PE) file or in memory. When you compile your code into a PE file, metadata is inserted into
one portion of the file, and your code is converted to Microsoft intermediate language (MSIL) and inserted into
another portion of the file. Every type and member that is defined and referenced in a module or assembly is
described within metadata. When code is executed, the runtime loads metadata into memory and references it to
discover information about your code's classes, members, inheritance, and so on.
Metadata describes every type and member defined in your code in a language-neutral manner. Metadata stores
the following information:
Description of the assembly.
Identity (name, version, culture, public key).
The types that are exported.
Other assemblies that this assembly depends on.
Security permissions needed to run.
Description of types.
Name, visibility, base class, and interfaces implemented.
Members (methods, fields, properties, events, nested types).
Attributes.
Additional descriptive elements that modify types and members.
Benefits of Metadata
Metadata is the key to a simpler programming model, and eliminates the need for Interface Definition Language
(IDL) files, header files, or any external method of component reference. Metadata enables .NET Framework
languages to describe themselves automatically in a language-neutral manner, unseen by both the developer and
the user. Additionally, metadata is extensible through the use of attributes. Metadata provides the following major
benefits:
Self-describing files.
Common language runtime modules and assemblies are self-describing. A module's metadata contains
everything needed to interact with another module. Metadata automatically provides the functionality of IDL
in COM, so you can use one file for both definition and implementation. Runtime modules and assemblies
do not even require registration with the operating system. As a result, the descriptions used by the runtime
always reflect the actual code in your compiled file, which increases application reliability.
Language interoperability and easier component-based design.
Metadata provides all the information required about compiled code for you to inherit a class from a PE file
written in a different language. You can create an instance of any class written in any managed language
(any language that targets the common language runtime) without worrying about explicit marshaling or
using custom interoperability code.
Attributes.
The .NET Framework lets you declare specific kinds of metadata, called attributes, in your compiled file.
Attributes can be found throughout the .NET Framework and are used to control in more detail how your
program behaves at run time. Additionally, you can emit your own custom metadata into .NET Framework
files through user-defined custom attributes. For more information, see Attributes.
0x06000004
The top byte ( 0x06 ) indicates that this is a MethodDef token. The lower three bytes ( 000004 ) tells the common
language runtime to look in the fourth row of the MethodDef table for the information that describes this method
definition.
Metadata within a PE File
When a program is compiled for the common language runtime, it is converted to a PE file that consists of three
parts. The following table describes the contents of each part.
PE header The index of the PE file's main sections and the address of the
entry point.
Metadata Metadata tables and heaps. The runtime uses this section to
record information about every type and member in your
code. This section also includes custom attributes and security
information.
using System;
public class MyApp
{
public static int Main()
{
int ValueOne = 10;
int ValueTwo = 20;
Console.WriteLine("The Value is: {0}", Add(ValueOne, ValueTwo));
return 0;
}
public static int Add(int One, int Two)
{
return (One + Two);
}
}
When the code runs, the runtime loads the module into memory and consults the metadata for this class. Once
loaded, the runtime performs extensive analysis of the method's Microsoft intermediate language (MSIL) stream to
convert it to fast native machine instructions. The runtime uses a just-in-time (JIT) compiler to convert the MSIL
instructions to native machine code one method at a time as needed.
The following example shows part of the MSIL produced from the previous code's Main function. You can view the
MSIL and metadata from any .NET Framework application using the MSIL Disassembler (Ildasm.exe).
.entrypoint
.maxstack 3
.locals ([0] int32 ValueOne,
[1] int32 ValueTwo,
[2] int32 V_2,
[3] int32 V_3)
IL_0000: ldc.i4.s 10
IL_0002: stloc.0
IL_0003: ldc.i4.s 20
IL_0005: stloc.1
IL_0006: ldstr "The Value is: {0}"
IL_000b: ldloc.0
IL_000c: ldloc.1
IL_000d: call int32 ConsoleApplication.MyApp::Add(int32,int32) /* 06000003 */
The JIT compiler reads the MSIL for the whole method, analyzes it thoroughly, and generates efficient native
instructions for the method. At IL_000d , a metadata token for the Add method ( /* 06000003 */ ) is encountered
and the runtime uses the token to consult the third row of the MethodDef table.
The following table shows part of the MethodDef table referenced by the metadata token that describes the Add
method. While other metadata tables exist in this assembly and have their own unique values, only this table is
discussed.
NAME
SIGNATURE
RELATIVE VIRTUAL (POINTS TO (POINTS TO BLOB
ROW ADDRESS (RVA) IMPLFLAGS FLAGS STRING HEAP.) HEAP.)
Managed ReuseSlot
SpecialName
RTSpecialName
.ctor
Managed Static
ReuseSlot
Managed Static
ReuseSlot
Each column of the table contains important information about your code. The RVA column allows the runtime to
calculate the starting memory address of the MSIL that defines this method. The ImplFlags and Flags columns
contain bitmasks that describe the method (for example, whether the method is public or private). The Name
column indexes the name of the method from the string heap. The Signature column indexes the definition of the
method's signature in the blob heap.
The runtime calculates the desired offset address from the RVA column in the third row and returns this address to
the JIT compiler, which then proceeds to the new address. The JIT compiler continues to process MSIL at the new
address until it encounters another metadata token and the process is repeated.
Using metadata, the runtime has access to all the information it needs to load your code and process it into native
machine instructions. In this manner, metadata enables self-describing files and, together with the common type
system, cross-language inheritance.
Related Topics
TITLE DESCRIPTION
Applications in the .NET Framework can use the System.Console class to read characters from and write characters
to the console. Data from the console is read from the standard input stream, data to the console is written to the
standard output stream, and error data to the console is written to the standard error output stream. These streams
are automatically associated with the console when the application starts and are presented as the In, Out, and
Error properties, respectively.
The value of the System.Console.In property is a System.IO.TextReader object, whereas the values of the
System.Console.Out and System.Console.Error properties are System.IO.TextWriter objects. You can associate these
properties with streams that do not represent the console, making it possible for you to point the stream to a
different location for input or output. For example, you can redirect the output to a file by setting the
System.Console.Out property to a System.IO.StreamWriter, which encapsulates a System.IO.FileStream by means of
the System.Console.SetOut method. The System.Console.In and System.Console.Out properties do not need to refer
to the same stream.
NOTE
For more information about building console applications, including examples in C#, Visual Basic, and C++, see the
documentation for the Console class.
If the console does not exist, as in a Windows-based application, output written to the standard output stream will
not be visible, because there is no console to write the information to. Writing information to an inaccessible
console does not cause an exception to be raised.
Alternately, to enable the console for reading and writing within a Windows-based application that is developed
using Visual Studio, open the project's Properties dialog box, click the Application tab, and set the Application
type to Console Application.
Console applications lack a message pump that starts by default. Therefore, console calls to Microsoft Win32 timers
might fail.
The System.Console class has methods that can read individual characters or entire lines from the console. Other
methods convert data and format strings, and then write the formatted strings to the console. For more
information on formatting strings, see Formatting Types.
See Also
System.Console
Formatting Types
Parallel Processing and Concurrency in the .NET
Framework
7/29/2017 • 1 min to read • Edit Online
The .NET Framework provides several ways for you to use multiple threads of execution to keep your application
responsive to your user while maximizing the performance of your user's computer.
In This Section
Threading
Describes the basic concurrency and synchronization mechanisms provided by the .NET Framework.
Asynchronous Programming Patterns
Provides a brief overview of the three asynchronous programming patterns supported in the .NET Framework:
Asynchronous Programming Model (APM) (legacy)
Event-based Asynchronous Pattern (EAP) (legacy)
Task-based Asynchronous Pattern (TAP) (recommended for new development)
Parallel Programming
Describes a task-based programming model that simplifies parallel development, enabling you to write efficient,
fine-grained, and scalable parallel code in a natural idiom without having to work directly with threads or the
thread pool.
See Also
Development Guide
.NET Framework Application Essentials
8/4/2017 • 1 min to read • Edit Online
This section of the .NET Framework documentation provides information about basic application development
tasks in the .NET Framework.
In This Section
Base Types
Discusses formatting and parsing base data types and using regular expressions to process text.
Collections and Data Structures
Discusses the various collection types available in the .NET Framework, including stacks, queues, lists, arrays, and
structs.
Generics
Describes the Generics feature, including the generic collections, delegates, and interfaces provided by the .NET
Framework. Provides links to feature documentation for C#, Visual Basic and Visual C++, and to supporting
technologies such as Reflection.
Numerics
Describes the numeric types in the .NET Framework.
Events
Provides an overview of the event model in the .NET Framework.
Exceptions
Describes error handling provided by the .NET Framework and the fundamentals of handling exceptions.
File and Stream I-O
Explains how you can perform synchronous and asynchronous file and data stream access and how to use to
isolated storage.
Dates, Times, and Time Zones
Describes how to work with time zones and time zone conversions in time zone-aware applications.
Application Domains and Assemblies
Describes how to create and work with assemblies and application domains.
Serialization
Discusses the process of converting the state of an object into a form that can be persisted or transported.
Resources in Desktop Apps
Describes the .NET Framework support for creating and storing resources. This section also describes support for
localized resources and the satellite assembly resource model for packaging and deploying those localized
resources.
Globalization and Localization
Provides information to help you design and develop world-ready applications.
Accessibility
Provides information about Microsoft UI Automation, which is an accessibility framework that addresses the needs
of assistive technology products and automated test frameworks by providing programmatic access to information
about the user interface (UI).
Attributes
Describes how you can use attributes to customize metadata.
64-bit Applications
Discusses issues relevant to developing applications that will run on a Windows 64-bit operating system.
Related Sections
Development Guide
Provides a guide to all key technology areas and tasks for application development, including creating, configuring,
debugging, securing, and deploying your application, and information about dynamic programming,
interoperability, extensibility, memory management, and threading.
Security
Provides information about the classes and services in the common language runtime and the .NET Framework
that facilitate secure application development.
File and Stream I/O
7/29/2017 • 7 min to read • Edit Online
File and stream I/O (input/output) refers to the transfer of data either to or from a storage medium. In the .NET
Framework, the System.IO namespaces contain types that enable reading and writing, both synchronously and
asynchronously, on data streams and files. These namespaces also contain types that perform compression and
decompression on files, and types that enable communication through pipes and serial ports.
A file is an ordered and named collection of bytes that has persistent storage. When you work with files, you work
with directory paths, disk storage, and file and directory names. In contrast, a stream is a sequence of bytes that
you can use to read from and write to a backing store, which can be one of several storage mediums (for example,
disks or memory). Just as there are several backing stores other than disks, there are several kinds of streams other
than file streams, such as network, memory, and pipe streams.
Streams
The abstract base class Stream supports reading and writing bytes. All classes that represent streams inherit from
the Stream class. The Stream class and its derived classes provide a common view of data sources and repositories,
and isolate the programmer from the specific details of the operating system and underlying devices.
Streams involve three fundamental operations:
Reading - transferring data from a stream into a data structure, such as an array of bytes.
Writing - transferring data to a stream from a data source.
Seeking - querying and modifying the current position within a stream.
Depending on the underlying data source or repository, a stream might support only some of these capabilities.
For example, the PipeStream class does not support seeking. The CanRead, CanWrite, and CanSeek properties of a
stream specify the operations that the stream supports.
Here are some commonly used stream classes:
FileStream – for reading and writing to a file.
IsolatedStorageFileStream – for reading and writing to a file in isolated storage.
MemoryStream – for reading and writing to memory as the backing store.
BufferedStream – for improving performance of read and write operations.
NetworkStream – for reading and writing over network sockets.
PipeStream – for reading and writing over anonymous and named pipes.
CryptoStream – for linking data streams to cryptographic transformations.
For an example of working with streams asynchronously, see Asynchronous File I/O.
Compression
Compression refers to the process of reducing the size of a file for storage. Decompression is the process of
extracting the contents of a compressed file so they are in a usable format. The System.IO.Compression namespace
contains types for compressing and decompressing files and streams.
The following classes are frequently used when compressing and decompressing files and streams:
ZipArchive – for creating and retrieving entries in the zip archive.
ZipArchiveEntry – for representing a compressed file.
ZipFile – for creating, extracting, and opening a compressed package.
ZipFileExtensions – for creating and extracting entries in a compressed package.
DeflateStream – for compressing and decompressing streams using the Deflate algorithm.
GZipStream – for compressing and decompressing streams in gzip data format.
See How to: Compress and Extract Files.
Isolated Storage
Isolated storage is a data storage mechanism that provides isolation and safety by defining standardized ways of
associating code with saved data. The storage provides a virtual file system that is isolated by user, assembly, and
(optionally) domain. Isolated storage is particularly useful when your application does not have permission to
access user files. You can save settings or files for your application in a manner that is controlled by the computer's
security policy.
Isolated storage is not available for Windows 8.x Store apps; instead, use application data classes in the
Windows.Storage namespace. For more information, see Application data in the Windows Dev Center.
The following classes are frequently used when implementing isolated storage:
IsolatedStorage – provides the base class for isolated storage implementations.
IsolatedStorageFile – provides an isolated storage area that contains files and directories.
IsolatedStorageFileStream - exposes a file within isolated storage.
See Isolated Storage.
Related Topics
Common I/O Tasks
Provides a list of I/O tasks associated with files, directories, and streams, and links to relevant content and examples
for each task.
Asynchronous File I/O
Describes the performance advantages and basic operation of asynchronous I/O.
Isolated Storage
Describes a data storage mechanism that provides isolation and safety by defining standardized ways of
associating code with saved data.
Pipes
Describes anonymous and named pipe operations in the .NET Framework.
Memory-Mapped Files
Describes memory-mapped files, which contain the contents of files on disk in virtual memory. You can use
memory-mapped files to edit very large files and to create shared memory for interprocess communication.
Globalizing and Localizing .NET Framework
Applications
7/29/2017 • 2 min to read • Edit Online
Developing a world-ready application, including an application that can be localized into one or more languages,
involves three steps: globalization, localizability review, and localization.
Globalization
This step involves designing and coding an application that is culture-neutral and language-neutral, and that
supports localized user interfaces and regional data for all users. It involves making design and programming
decisions that are not based on culture-specific assumptions. While a globalized application is not localized, it
nevertheless is designed and written so that it can be subsequently localized into one or more languages with
relative ease.
Localizability Review
This step involves reviewing an application's code and design to ensure that it can be localized easily and to
identify potential roadblocks for localization, and verifying that the application's executable code is separated from
its resources. If the globalization stage was effective, the localizability review will confirm the design and coding
choices made during globalization. The localizability stage may also identify any remaining issues so that an
application's source code doesn't have to be modified during the localization stage.
Localization
This step involves customizing an application for specific cultures or regions. If the globalization and localizability
steps have been performed correctly, localization consists primarily of translating the user interface.
Following these three steps provides two advantages:
It frees you from having to retrofit an application that is designed to support a single culture, such as U.S.
English, to support additional cultures.
It results in localized applications that are more stable and have fewer bugs.
The .NET Framework provides extensive support for the development of world-ready and localized applications. In
particular, many type members in the .NET Framework class library aid globalization by returning values that
reflect the conventions of either the current user's culture or a specified culture. Also, the .NET Framework supports
satellite assemblies, which facilitate the process of localizing an application.
For additional information, see the Go Global Developer Center.
In This Section
Globalization
Discusses the first stage of creating a world-ready application, which involves designing and coding an application
that is culture-neutral and language-neutral.
Localizability Review
Discusses the second stage of creating a localized application, which involves identifying potential roadblocks to
localization.
Localization
Discusses the final stage of creating a localized application, which involves customizing an application's user
interface for specific regions or cultures.
Culture-Insensitive String Operations
Describes how to use .NET Framework methods and classes that are culture-sensitive by default to obtain culture-
insensitive results.
Best Practices for Developing World-Ready Applications
Describes the best practices to follow for globalization, localization, and developing world-ready ASP.NET
applications.
Reference
System.Globalization namespace
Contains classes that define culture-related information, including the language, the country/region, the calendars
in use, the format patterns for dates, currency, and numbers, and the sort order for strings.
System.Resources namespace
Provides classes for creating, manipulating, and using resources.
System.Text namespace
Contains classes representing ASCII, ANSI, Unicode, and other character encodings.
Resgen.exe (Resource File Generator)
Describes how to use Resgen.exe to convert .txt files and XML-based resource format (.resx) files to common
language runtime binary .resources files.
Winres.exe (Windows Forms Resource Editor)
Describes how to use Winres.exe to localize Windows Forms forms.
Extending Metadata Using Attributes
7/29/2017 • 1 min to read • Edit Online
The common language runtime allows you to add keyword-like descriptive declarations, called attributes, to
annotate programming elements such as types, fields, methods, and properties. When you compile your code for
the runtime, it is converted into Microsoft intermediate language (MSIL) and placed inside a portable executable
(PE) file along with metadata generated by the compiler. Attributes allow you to place extra descriptive information
into metadata that can be extracted using runtime reflection services. The compiler creates attributes when you
declare instances of special classes that derive from System.Attribute.
The .NET Framework uses attributes for a variety of reasons and to address a number of issues. Attributes describe
how to serialize data, specify characteristics that are used to enforce security, and limit optimizations by the just-
in-time (JIT) compiler so the code remains easy to debug. Attributes can also record the name of a file or the
author of code, or control the visibility of controls and members during forms development.
Related Topics
TITLE DESCRIPTION
Retrieving Information Stored in Attributes Describes how to retrieve custom attributes for code that is
loaded into the execution context.
Metadata and Self-Describing Components Provides an overview of metadata and describes how it is
implemented in a .NET Framework portable executable (PE)
file.
How to: Load Assemblies into the Reflection-Only Context Explains how to retrieve custom attribute information in the
reflection-only context.
Reference
System.Attribute
Framework Design Guidelines
7/29/2017 • 1 min to read • Edit Online
This section provides guidelines for designing libraries that extend and interact with the .NET Framework. The goal
is to help library designers ensure API consistency and ease of use by providing a unified programming model that
is independent of the programming language used for development. We recommend that you follow these design
guidelines when developing classes and components that extend the .NET Framework. Inconsistent library design
adversely affects developer productivity and discourages adoption.
The guidelines are organized as simple recommendations prefixed with the terms Do , Consider , Avoid , and
Do not . These guidelines are intended to help class library designers understand the trade-offs between different
solutions. There might be situations where good library design requires that you violate these design guidelines.
Such cases should be rare, and it is important that you have a clear and compelling reason for your decision.
These guidelines are excerpted from the book Framework Design Guidelines: Conventions, Idioms, and Patterns for
Reusable .NET Libraries, 2nd Edition, by Krzysztof Cwalina and Brad Abrams.
In This Section
Naming Guidelines
Provides guidelines for naming assemblies, namespaces, types, and members in class libraries.
Type Design Guidelines
Provides guidelines for using static and abstract classes, interfaces, enumerations, structures, and other types.
Member Design Guidelines
Provides guidelines for designing and using properties, methods, constructors, fields, events, operators, and
parameters.
Designing for Extensibility
Discusses extensibility mechanisms such as subclassing, using events, virtual members, and callbacks, and explains
how to choose the mechanisms that best meet your framework's requirements.
Design Guidelines for Exceptions
Describes design guidelines for designing, throwing, and catching exceptions.
Usage Guidelines
Describes guidelines for using common types such as arrays, attributes, and collections, supporting serialization,
and overloading equality operators.
Common Design Patterns
Provides guidelines for choosing and implementing dependency properties and the dispose pattern.
Portions © 2005, 2009 Microsoft Corporation. All rights reserved.
Reprinted by permission of Pearson Education, Inc. from Framework Design Guidelines: Conventions, Idioms, and
Patterns for Reusable .NET Libraries, 2nd Edition by Krzysztof Cwalina and Brad Abrams, published Oct 22, 2008 by
Addison-Wesley Professional as part of the Microsoft Windows Development Series.
See Also
Overview
Roadmap for the .NET Framework
Development Guide
XML Documents and Data
7/29/2017 • 2 min to read • Edit Online
The .NET Framework provides a comprehensive and integrated set of classes that enable you to build XML-aware
apps easily. The classes in the following namespaces support parsing and writing XML, editing XML data in
memory, data validation, and XSLT transformation.
System.Xml
System.Xml.XPath
System.Xml.Xsl
System.Xml.Schema
System.Xml.Linq
For a full list, see the System.Xml Namespaces webpage.
The classes in these namespaces support World Wide Web Consortium (W3C) recommendations. For example:
The System.Xml.XmlDocument class implements the W3C Document Object Model (DOM) Level 1 Core and
DOM Level 2 Core recommendations.
The System.Xml.XmlReader and System.Xml.XmlWriter classes support the W3C XML 1.0 and the
Namespaces in XML recommendations.
Schemas in the System.Xml.Schema.XmlSchemaSet class support the W3C XML Schema Part 1: Structures
and XML Schema Part 2: Datatypes recommendations.
Classes in the System.Xml.Xsl namespace support XSLT transformations that conform to the W3C XSLT 1.0
recommendation.
The XML classes in the .NET Framework provide these benefits:
Productivity. LINQ to XML makes it easier to program with XML and provides a query experience that is
similar to SQL.
Extensibility. The XML classes in the .NET Framework are extensible through the use of abstract base
classes and virtual methods. For example, you can create a derived class of the XmlUrlResolver class that
stores the cache stream to the local disk.
Pluggable architecture. The .NET Framework provides an architecture in which components can utilize
one another, and data can be streamed between components. For example, a data store, such as an
XPathDocument or XmlDocument object, can be transformed with the XslCompiledTransform class, and the
output can then be streamed either into another store or returned as a stream from a web service.
Performance. For better app performance, some of the XML classes in the .NET Framework support a
streaming-based model with the following characteristics:
Minimal caching for forward-only, pull-model parsing (XmlReader).
Forward-only validation (XmlReader).
Cursor style navigation that minimizes node creation to a single virtual node while providing random
access to the document (XPathNavigator).
For better performance whenever XSLT processing is required, you can use the XPathDocument class, which
is an optimized, read-only store for XPath queries designed to work efficiently with the
XslCompiledTransform class.
Integration with ADO.NET. The XML classes and ADO.NET are tightly integrated to bring together
relational data and XML. The DataSet class is an in-memory cache of data retrieved from a database. The
DataSet class has the ability to read and write XML by using the XmlReader and XmlWriter classes, to persist
its internal relational schema structure as XML schemas (XSD), and to infer the schema structure of an XML
document.
In This Section
XML Processing Options
Discusses options for processing XML data.
Processing XML Data In-Memory
Discusses the three models for processing XML data in-memory. LINQ to XML, the XmlDocument class (based on
the W3C Document Object Model), and the XPathDocument class (based on the XPath data model).
XSLT Transformations
Describes how to use the XSLT processor.
XML Schema Object Model (SOM)
Describes the classes used for building and manipulating XML Schemas (XSD) by providing an XmlSchema class to
load and edit a schema.
XML Integration with Relational Data and ADO.NET
Describes how the .NET Framework enables real-time, synchronous access to both the relational and hierarchical
representations of data through the DataSet object and the XmlDataDocument object.
Managing Namespaces in an XML Document
Describes how the XmlNamespaceManager class is used to store and maintain namespace information.
Type Support in the System.Xml Classes
Describes how XML data types map to CLR types, how to convert XML data types, and other type support features
in the System.Xml classes.
Related Sections
ADO.NET
Provides information on how to access data using ADO.NET.
Security
Provides an overview of the .NET Framework security system.
XML Developer Center
Provides additional technical information, downloads, newsgroups, and other resources for XML developers.
Managed Threading
7/29/2017 • 1 min to read • Edit Online
Whether you are developing for computers with one processor or several, you want your application to provide the
most responsive interaction with the user, even if the application is currently doing other work. Using multiple
threads of execution is one of the most powerful ways to keep your application responsive to the user and at the
same time make use of the processor in between or even during user events. While this section introduces the
basic concepts of threading, it focuses on managed threading concepts and using managed threading.
NOTE
Starting with the .NET Framework 4, multithreaded programming is greatly simplified with the
System.Threading.Tasks.Parallel and System.Threading.Tasks.Task classes, Parallel LINQ (PLINQ), new concurrent collection
classes in the System.Collections.Concurrent namespace, and a new programming model that is based on the concept of
tasks rather than threads. For more information, see Parallel Programming.
In This Section
Managed Threading Basics
Provides an overview of managed threading and discusses when to use multiple threads.
Using Threads and Threading
Explains how to create, start, pause, resume, and abort threads.
Managed Threading Best Practices
Discusses levels of synchronization, how to avoid deadlocks and race conditions, single-processor and
multiprocessor computers, and other threading issues.
Threading Objects and Features
Describes the managed classes you can use to synchronize the activities of threads and the data of objects accessed
on different threads, and provides an overview of thread pool threads.
Reference
System.Threading
Contains classes for using and synchronizing managed threads.
System.Collections.Concurrent
Contains collection classes that are safe for use with multiple threads.
System.Threading.Tasks
Contains classes for creating and scheduling concurrent processing tasks.
Related Sections
Application Domains
Provides an overview of application domains and their use by the Common Language Infrastructure.
Asynchronous File I/O
Describes the performance advantages and basic operation of asynchronous I/O.
Event-based Asynchronous Pattern (EAP)
Provides an overview of asynchronous programming.
Calling Synchronous Methods Asynchronously
Explains how to call methods on thread pool threads using built-in features of delegates.
Parallel Programming
Describes the parallel programming libraries, which simplify the use of multiple threads in applications.
Parallel LINQ (PLINQ)
Describes a system for running queries in parallel, to take advantage of multiple processors.
Parallel Programming in the .NET Framework
7/29/2017 • 1 min to read • Edit Online
Many personal computers and workstations have two or four cores (that is, CPUs) that enable multiple threads to
be executed simultaneously. Computers in the near future are expected to have significantly more cores. To take
advantage of the hardware of today and tomorrow, you can parallelize your code to distribute work across multiple
processors. In the past, parallelization required low-level manipulation of threads and locks. Visual Studio 2010 and
the .NET Framework 4 enhance support for parallel programming by providing a new runtime, new class library
types, and new diagnostic tools. These features simplify parallel development so that you can write efficient, fine-
grained, and scalable parallel code in a natural idiom without having to work directly with threads or the thread
pool. The following illustration provides a high-level overview of the parallel programming architecture in the .NET
Framework 4.
Related Topics
TECHNOLOGY DESCRIPTION
Data Structures for Parallel Programming Provides links to documentation for thread-safe collection
classes, lightweight synchronization types, and types for lazy
initialization.
Parallel Diagnostic Tools Provides links to documentation for Visual Studio debugger
windows for tasks and parallel stacks, and the Concurrency
Visualizer, which consists of a set of views in the Visual Studio
Application Lifecycle Management Profiler that you can use to
debug and to tune the performance of parallel code.
TECHNOLOGY DESCRIPTION
Custom Partitioners for PLINQ and TPL Describes how partitioners work and how to configure the
default partitioners or create a new partitioner.
Task Schedulers Describes how schedulers work and how the default
schedulers may be configured.
Lambda Expressions in PLINQ and TPL Provides a brief overview of lambda expressions in C# and
Visual Basic, and shows how they are used in PLINQ and the
Task Parallel Library.
See Also
Patterns for Parallel Programming: Understanding and Applying Parallel Patterns with the .NET Framework 4
Samples for Parallel Programming with the .NET Framework
Security in the .NET Framework
7/29/2017 • 1 min to read • Edit Online
The common language runtime and the .NET Framework provide many useful classes and services that enable
developers to easily write secure code and enable system administrators to customize the permissions granted to
code so that it can access protected resources. In addition, the runtime and the .NET Framework provide useful
classes and services that facilitate the use of cryptography and role-based security.
In This Section
Security Changes
Describes important changes to the .NET Framework security system.
Key Security Concepts
Provides an overview of common language runtime security features. This section is of interest to developers and
system administrators.
Role-Based Security
Describes how to interact with role-based security in your code. This section is of interest to developers.
Cryptography Model
Provides an overview of cryptographic services provided by the .NET Framework. This section is of interest to
developers.
Secure Coding Guidelines
Describes some of the best practices for creating reliable .NET Framework applications. This section is of interest to
developers.
Secure Coding Guidelines for Unmanaged Code
Describes some of the best practices and security concerns when calling unmanaged code.
Windows Identity Foundation
Describes how you can implement claims-based identity in your applications.
Related Sections
Development Guide
Provides a guide to all key technology areas and tasks for application development, including creating, configuring,
debugging, securing, and deploying your application, and information about dynamic programming,
interoperability, extensibility, memory management, and threading.
Serialization in .NET
8/4/2017 • 1 min to read • Edit Online
Serialization is the process of converting the state of an object into a form that can be persisted or transported. The
complement of serialization is deserialization, which converts a stream into an object. Together, these processes
allow data to be easily stored and transferred.
.NET features two serialization technologies:
Binary serialization preserves type fidelity, which is useful for preserving the state of an object between
different invocations of an application. For example, you can share an object between different applications
by serializing it to the Clipboard. You can serialize an object to a stream, to a disk, to memory, over the
network, and so forth. Remoting uses serialization to pass objects "by value" from one computer or
application domain to another.
XML serialization serializes only public properties and fields and does not preserve type fidelity. This is
useful when you want to provide or consume data without restricting the application that uses the data.
Because XML is an open standard, it is an attractive choice for sharing data across the Web. SOAP is likewise
an open standard, which makes it an attractive choice.
In This Section
Serialization How-to Topics
Lists links to How-to topics contained in this section.
Binary Serialization
Describes the binary serialization mechanism that is included with the common language runtime.
XML and SOAP Serialization
Describes the XML and SOAP serialization mechanism that is included with the common language runtime.
Serialization Tools
These tools help develop serialization code.
Serialization Samples
The samples demonstrate how to do serialization.
Reference
System.Runtime.Serialization Contains classes that can be used for serializing and deserializing objects.
System.Xml.Serialization
Contains classes that can be used to serialize objects into XML format documents or streams.
Developing for Multiple Platforms with the .NET
Framework
7/29/2017 • 2 min to read • Edit Online
You can develop apps for both Microsoft and non-Microsoft platforms by using the .NET Framework and Visual
Studio.
Share source code between Windows Phone 8.1 and Windows Shared projects (Universal Apps template in Visual Studio
8.1 apps 2013, Update 2).
Share binaries between apps that target different platforms Portable Class Library projects for code that is platform-
agnostic.
Share source code between apps for platforms other than Add as link feature.
Windows 8.1 and Windows Phone 8.1
- This approach is suitable for app logic that's common to
both apps but not portable, for some reason. You can use this
feature for C# or Visual Basic code.
For example, Windows Phone 8 and Windows 8 share
Windows Runtime APIs, but Portable Class Libraries do not
support Windows Runtime for those platforms. You can use
Add as link to share common Windows Runtime code
between a Windows Phone 8 app and a Windows Store app
that targets Windows 8.
Write Windows Store apps using the .NET Framework or call Windows Runtime APIs from your .NET Framework C# or
Windows Runtime APIs from .NET Framework code Visual Basic code, and use the .NET Framework to create
Windows Store apps. You should be aware of API differences
between the two platforms. However, there are classes to help
you work with those differences.
Build .NET Framework apps for non-Microsoft platforms Portable Class Library reference assemblies in the .NET
Framework, and a Visual Studio extension or third-party tool
such as Xamarin.
Use JavaScript and HTML for cross-platform development Universal App templates in Visual Studio 2013, Update 2 to
develop against Windows Runtime APIs for Windows 8.1 and
Windows Phone 8.1. Currently, you can’t use JavaScript and
HTML with .NET Framework APIs to develop cross-platform
apps.
Check out the "Getting Started" tutorials to learn how to create a simple .NET Core application. It only takes a
few minutes to get your first app up and running.
.NET Core is a general purpose development platform maintained by Microsoft and the .NET community on
GitHub. It is cross-platform, supporting Windows, macOS and Linux, and can be used in device, cloud, and
embedded/IoT scenarios.
The following characteristics best define .NET Core:
Flexible deployment: Can be included in your app or installed side-by-side user- or machine-wide.
Cross-platform: Runs on Windows, macOS and Linux; can be ported to other operating systems. The
supported Operating Systems (OS), CPUs and application scenarios will grow over time, provided by
Microsoft, other companies, and individuals.
Command-line tools: All product scenarios can be exercised at the command-line.
Compatible: .NET Core is compatible with .NET Framework, Xamarin and Mono, via the .NET Standard.
Open source: The .NET Core platform is open source, using MIT and Apache 2 licenses. Documentation is
licensed under CC-BY. .NET Core is a .NET Foundation project.
Supported by Microsoft: .NET Core is supported by Microsoft, per .NET Core Support
Composition
.NET Core is composed of the following parts:
A .NET runtime, which provides a type system, assembly loading, a garbage collector, native interop and other
basic services.
A set of framework libraries, which provide primitive data types, app composition types and fundamental
utilities.
A set of SDK tools and language compilers that enable the base developer experience, available in the .NET
Core SDK.
The 'dotnet' app host, which is used to launch .NET Core apps. It selects the runtime and hosts the runtime,
provides an assembly loading policy and launches the app. The same host is also used to launch SDK tools in
much the same way.
Languages
The C# and F# languages (Visual Basic is coming) can be used to write applications and libraries for .NET Core.
The compilers run on .NET Core, enabling you to develop for .NET Core anywhere it runs. In general, you will not
use the compilers directly, but indirectly using the SDK tools.
The C# and F# compilers and the .NET Core tools are or can be integrated into several text editors and IDEs,
including Visual Studio, Visual Studio Code, Sublime Text and Vim, making .NET Core development an option in
your favorite coding environment and OS. This integration is provided, in part, by the good folks of the
OmniSharp project.
.NET APIs and Compatibility
.NET Core can be thought of as a cross-platform version of the .NET Framework, at the layer of the .NET
Framework Base Class Libraries (BCL). It implements the .NET Standard specification. .NET Core provides a subset
of the APIs that are available in the .NET Framework or Mono/Xamarin. In some cases, types are not fully
implemented (some members are not available or have been moved).
Look at the .NET Core roadmap to learn more about the .NET Core API roadmap.
Relationship to .NET Standard
The .NET Standard is an API spec that describes the consistent set of .NET APIs that developers can expect in each
.NET implementation. .NET implementations need to implement this spec in order to be considered .NET
Standard-compliant and to support libraries that target .NET Standard.
.NET Core implements .NET Standard, and therefore supports .NET Standard libraries.
Workloads
By itself, .NET Core includes a single application model -- console apps -- which is useful for tools, local services
and text-based games. Additional application models have been built on top of .NET Core to extend its
functionality, such as:
ASP.NET Core
Windows 10 Universal Windows Platform (UWP)
Xamarin.Forms when targeting UWP
Open Source
.NET Core is open source (MIT license) and was contributed to the .NET Foundation by Microsoft in 2014. It is now
one of the most active .NET Foundation projects. It can be freely adopted by individuals and companies, including
for personal, academic or commercial purposes. Multiple companies use .NET Core as part of apps, tools, new
platforms and hosting services. Some of these companies make significant contributions to .NET Core on GitHub
and provide guidance on the product direction as part of the .NET Foundation Technical Steering Group.
Acquisition
.NET Core is distributed in two main ways, as packages on NuGet.org and as standalone distributions.
Distributions
You can download .NET Core at the .NET Core Getting Started page.
The Microsoft .NET Core distribution includes the CoreCLR runtime, associated libraries, a console application
host and the dotnet app launcher. It is described by the Microsoft.NETCore.App metapackage.
The Microsoft .NET Core SDK distribution includes .NET Core and a set of tools for restoring NuGet packages
and compiling and building apps.
Typically, you will first install the .NET Core SDK to get started with .NET Core development. You may choose to
install additional .NET Core (perhaps pre-release) builds.
Packages
.NET Core Packages contain the .NET Core runtime and libraries (reference assemblies and implementations).
For example, System.Net.Http.
.NET Core Metapackages describe various layers and app-models by referencing the appropriate set of
versioned library packages.
Architecture
.NET Core is a cross-platform .NET implementation. The primary architectural concerns unique to .NET Core are
related to providing platform-specific implementations for supported platforms.
Environments
.NET Core is supported by Microsoft on Windows, macOS and Linux. On Linux, Microsoft primarily supports .NET
Core running on Red Hat Enterprise Linux (RHEL) and Debian distribution families.
.NET Core currently supports X64 CPUs. On Windows, X86 is also supported. ARM64 and ARM32 are in progress.
The .NET Core Roadmap provides more detailed information on workload and OS and CPU environment support
and plans.
Other companies or groups may support .NET Core for other app types and environment.
Designed for Adaptability
.NET Core has been built as a very similar but unique product relative to other .NET products. It has been
designed to enable broad adaptability to new platforms, for new workloads and with new compiler toolchains. It
has several OS and CPU ports in progress and may be ported to many more. An example is the LLILC project,
which is an early prototype of native compilation for .NET Core via the LLVM compiler.
The product is broken into several pieces, enabling the various parts to be adapted to new platforms on different
schedules. The runtime and platform-specific foundational libraries must be ported as a unit. Platform-agnostic
libraries should work as-is on all platforms, by construction. There is a project bias to reducing platform-specific
implementations to increase developer efficiency, preferring platform-neutral C# code whenever an algorithm or
API can be implemented in-full or in-part that way.
People commonly ask how .NET Core is implemented in order to support multiple operating systems. They
typically ask if there are separate implementations or if conditional compilation is used. It's both, with a strong
bias towards conditional compilation.
You can see in the chart below that the vast majority of CoreFX is platform-neutral code that is shared across all
platforms. Platform-neutral code can be implemented as a single portable assembly that is used on all platforms.
Windows and Unix implementations are similar in size. Windows has a larger implementation since CoreFX
implements some Windows-only features, such as Microsoft.Win32.Registry but does not yet implement any
Unix-only concepts. You will also see that the majority of the Linux and macOS implementations are shared
across a Unix implementation, while the Linux- and macOS-specific implementations are roughly similar in size.
There are a mix of platform-specific and platform-neutral libraries in .NET Core. You can see the pattern in a few
examples:
CoreCLR is platform-specific. It's built in C/C++, so is platform-specific by construction.
System.IO and System.Security.Cryptography.Algorithms are platform-specific, given that the storage and
cryptography APIs differ significantly on each OS.
System.Collections and System.Linq are platform-neutral, given that they create and operate over data
structures.
Windows
Install .NET Core on Windows.
You can get started developing .NET Core apps by following these step-by-step tutorials.
Building a C# Hello World Application with .NET Core in Visual Studio 2017 - Learn to to build, debug, and
publish a simple .NET Core console application using C# and Visual Studio 2017.
Building a class library with C# and .NET Core in Visual Studio 2017 - Learn how to build a class library written
in C# using Visual Studio 2017.
Build a Visual Basic Hello World application with .NET Core in Visual Studio 2017 - Learn to to build, debug,
and publish a simple .NET Core console application using Visual Basic and Visual Studio 2017.
Build a class library with Visual Basic and .NET Core in Visual Studio 2017 - Learn how to build a class library
written in Visual Basic using Visual Studio 2017.
Get started with Visual Studio Code using C# and .NET Core on Windows - This Channel9 video shows you
how to install and use Visual Studio Code, Microsoft's lightweight cross-platform code editor, to create your
first console application in .NET Core.
Get Started with .NET Core and Visual Studio 2017 - This Channel9 video shows you how to install and use
Visual Studio 2017, Microsoft's fully-featured IDE, to create your first cross-platform console application in
.NET Core.
Getting started with .NET Core using the command-line - Use any code editor with the .NET Core cross-
platform command-line interface (CLI).
See the Prerequisites for Windows development topic for a list of the supported Windows versions.
Linux
Install .NET Core on your distribution/version:
Red Hat Enterprise Linux 7
Ubuntu 14.04, 16.04, 16.10, 17.04 & Linux Mint 17, 18
Debian 8.2+, 8.7+, 9
Fedora 24, 25, 26
CentOS 7.1 & Oracle Linux 7.1
SUSE Enterprise Linux (SLES) 12 SP2, openSUSE 42.1, 42.2
You can get started developing .NET Core apps by following these step-by-step tutorials.
Getting started with .NET Core using the command-line - Use any code editor with the .NET Core cross-
platform command-line interface (CLI).
Get started with Visual Studio Code using C# and .NET Core on Ubuntu - This Channel9 video shows you how
to install and use Visual Studio Code, Microsoft's lightweight cross-platform code editor, to create your first
console application in .NET Core on Ubuntu 14.04.
.NET Core is supported by the Linux distributions and versions listed above in the installation links.
OS X / macOS
Install .NET Core for macOS. .NET Core is supported on OS X El Capitan (version 10.11) and macOS Sierra (version
10.12).
You can get started developing .NET Core apps by following these step-by-step tutorials.
Get started with Visual Studio Code using C# and .NET Core on macOS - This Channel9 video shows you how
to install and use Visual Studio Code, Microsoft's lightweight cross-platform code editor, to create your first
console application in .NET Core.
Getting started with .NET Core on macOS, using Visual Studio Code - A tour of the steps and workflow to
create a .NET Core Solution using Visual Studio Code that includes unit tests, third-party libraries and how to
use the debugging tools.
Getting started with .NET Core using the command-line - Use any code editor with the .NET Core cross-
platform command-line interface (CLI).
Getting started with .NET Core on macOS using Visual Studio for Mac - This tutorial shows you how to build a
simple .NET Core console application using Visual Studio for Mac.
Building a complete .NET Core solution on macOS using Visual Studio for Mac - This tutorial shows you how to
build a complete .NET Core solution that includes a reusable library and unit testing.
See the Prerequisites for macOS development topic for a list of the supported OS X / macOS versions.
Get Started with C# and Visual Studio Code
8/4/2017 • 2 min 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 from the Visual Studio Code 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 the folder you want your C# project to be in and click Select Folder. For our example, we'll create a
folder for our project named 'HelloWorld'.
* Alternatively, you can select **File** > **Open Folder** from the main menu to open your project folder.
2. Initialize a C# project:
Open the Integrated Terminal from Visual Studio Code by typing CTRL+` (backtick). Alternatively, you
can select View > Integrated Terminal from the main menu.
In the terminal window, type dotnet new console .
This 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 .
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 will load in
the editor.
2. Visual Studio Code will 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 (the space on the left of the line numbers in
the editor) next to line 9.
6. Select F5 or the green arrow to start debugging. 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.
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
8/30/2017 • 3 min 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.
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 System.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 System.Console.WriteLine(String) method:
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.
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
System.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.
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-by-step tutorial, see Getting Started with Visual Studio Code.
Build a Visual Basic Hello World application with
.NET Core in Visual Studio 2017
8/14/2017 • 3 min 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.
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 System.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 System.Console.WriteLine(String) method:
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.
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
System.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.
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.
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);
}
}
}
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
8/14/2017 • 2 min 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.
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 top-level 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
<Extension>
Public Function StartsWithUpper(str As String) As Boolean
If String.IsNullOrWhiteSpace(str) Then
Return False
End If
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 System.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.
What's new in .NET Core
8/15/2017 • 5 min 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. In .NET Core 2.0, dotnet restore runs implicitly when the dotnet new command
executes. It also runs implicitly if dependencies need to be updated when other commands, such as the run ,
build , and publish commands, execute.
You can also disable the automatic invocation of dotnet restore by passing the --no-restore switch to the new ,
run , build , publish , pack , and test commands.
<PropertyGroup>
<TargetFramework>netcoreapp2.0</TargetFramework>
</PropertyGroup>
You can also retarget .NET Standard libraries to .NET Standard 2.0 the same way:
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup>
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 tools automatically compile and execute 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 distribution-specific 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.
Documentation improvements
.NET Application Architecture
.NET Application Architecture gives you access to a set of eBooks 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
Prerequisites for .NET Core on Windows
8/15/2017 • 2 min 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
NOTE
For Windows 7 and Windows Server 2008 machines only:
Make sure that your Windows installation is up-to-date and includes hotfix KB2533623 installed through Windows Update.
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.x apps, Visual Studio 2017 version 15.3 (26730.01) or higher.
For .NET Core 1.x apps, Visual Studio 2017 version 15.0 (26228.04) or higher.
Prerequisites for .NET Core on Mac
7/29/2017 • 1 min 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.
brew update
brew install openssl
mkdir -p /usr/local/lib
ln -s /usr/local/opt/openssl/lib/libcrypto.1.0.0.dylib /usr/local/lib/
ln -s /usr/local/opt/openssl/lib/libssl.1.0.0.dylib /usr/local/lib/
Download and install the .NET Core SDK from .NET Downloads. If you have problems with the installation on
macOS, consult the 1.0.0 Known Issues and 1.0.1 Known Issues topics.
.NET Core 2.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.
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
Visual Studio Code
NOTE
Ubuntu / Linux 16.10 is supported by the latest patch release of .NET Core 1.1
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.
See .NET Core 1.x Supported OS Versions for the complete list of .NET Core 1.x supported operating systems, out of
support OS versions, and lifecycle policy links.
IMPORTANT
Before running the script, install the required dependencies.
dotnet --help
NOTE
For Red Hat .NET channel access registration help, see Chapter 1 of the .NET Core 1.1 Getting Started Guide at Red Hat.
Install .NET Core for Ubuntu 14.04, 16.04, 16.10 & Linux Mint 17, 18 (64
bit)
WARNING
Before you start, remove any previous versions of .NET Core from your system.
Ubuntu 16.10
dotnet --help
dotnet --help
To Install .NET Core for Fedora 26,25(.NET Core 2.x) or 24 (.NET Core 1.x):
1. Get the prerequisites.
dotnet --help
Install .NET Core for CentOS 7.1 (64 bit) & Oracle Linux 7.1 (64 bit)
WARNING
Before you start, remove any previous versions of .NET Core from your system.
To Install .NET Core for CentOS 7.1 (64 bit) & Oracle Linux 7.1 (64 bit):
1. Get the prerequisites.
sudo dnf install libunwind libicu
dotnet --help
Install .NET Core for SUSE Linux Enterprise Server (64 bit) (.NET Core
2.x) and openSUSE (64 bit)
WARNING
Before you start, remove any previous versions of .NET Core from your system.
To Install .NET Core for SUSE Linux Enterprise Server (SLES) 12 SP2 (64 bit) and openSUSE 42.2 on NET Core 2.x, or
openSUSE 42.1(64 bit) on .NET Core 1.x:
1. Get the prerequisites.
dotnet --help
IMPORTANT
If you have problems with the .NET Core 2.x installation on a supported Linux distribution/version, consult the 2.0 Known
issues topic for your installed distributions/versions.
IMPORTANT
If you have problems with the .NET Core 1.x installation on a supported Linux distribution/version, consult the 1.0.0 Known
Issues and 1.0.1 Known Issues topics for your installed distributions/versions.
.NET Core Tutorials
8/14/2017 • 1 min to read • Edit Online
The following tutorials are available for learning about .NET Core.
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
7/29/2017 • 2 min 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.
.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 from the Visual Studio Code 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 the folder you want your C# project to be in and click Select Folder. For our example, we'll create
a folder for our project named 'HelloWorld'.
* Alternatively, you can select **File** > **Open Folder** from the main menu to open your project folder.
2. Initialize a C# project:
Open the Integrated Terminal from Visual Studio Code by typing CTRL+` (backtick). Alternatively, you
can select View > Integrated Terminal from the main menu.
In the terminal window, type dotnet new console .
This 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 .
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 will load
in the editor.
2. Visual Studio Code will 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 (the space on the left of the line numbers in
the editor) next to line 9.
6. Select F5 or the green arrow to start debugging. 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.
See also
Setting up Visual Studio Code
Debugging in Visual Studio Code
Getting started with .NET Core on macOS
8/24/2017 • 5 min 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/docs 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:
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:
Execute the dotnet sln command to add the newly created library.csproj project to the solution:
<PropertyGroup>
<TargetFramework>netstandard1.4</TargetFramework>
</PropertyGroup>
</Project>
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:
This adds Newtonsoft.Json and its dependencies to the library project. Alternatively, manually edit the
library.csproj file and add the following node:
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="10.0.1" />
</ItemGroup>
Execute dotnet restore , 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:
namespace Library
{
public class Thing
{
public int Get(int left, int right) =>
DeserializeObject<int>($"{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 interpolated strings.
Build the library with the dotnet build command. This produces a library.dll file under
golden/library/bin/Debug/netstandard1.4:
dotnet build
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:
Alternatively, manually edit the test-library.csproj file and add the following node:
<ItemGroup>
<ProjectReference Include="..\library\library.csproj" />
</ItemGroup>
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 Assert.NotEqual to Assert.Equal . Execute the following
command from the golden folder to re-run the test, which passes this time:
Create the dependency on the library by running the dotnet add reference command:
Run dotnet restore to restore the dependencies of the three projects in the solution. Open Program.cs and
replace the contents of the Main method with the following line:
Execute the following dotnet run command to run the executable, where the -p option to dotnet run specifies
the project for the main application. The app produces the string "The answer is 42".
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
Program class with a Main method. The Console.WriteLine statement will output "Hello World!" to the
console when the app is run.
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/29/2017 • 9 min 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 test-driven
development (TDD) 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;
}
// 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.
4. In order for the test library to work with the WordCount class, add a reference to the TextUtils project. In
the Solution sidebar, right-click Dependencies under TestLibrary. Select Edit References from the
context menu.
5. In the Edit References dialog, select the TextUtils project on the Projects tab. Select OK.
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.
Using TDD, 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.
1. Click the Dock icon to keep the panel open.
2. 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 .
3. 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.
4. 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.
5. Modify the CountInstancesCorrectly test method by changing Assert.NotEqual to Assert.Equal . Save the
file. Run the tests again. All tests pass.
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();
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 wordCount variable showing that you can replace variable values while debugging.
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
8/24/2017 • 5 min 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.
dotnet new creates an up-to-date Hello.csproj project file with the dependencies necessary to build a
console app. It also creates a Program.cs , a basic file containing the entry point for the application.
Hello.csproj :
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp1.0</TargetFramework>
</PropertyGroup>
</Project>
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 advance 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 System namespace into scope
for this file". The System namespace includes basic constructs such as string , or numeric types.
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.
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 <assembly.dll> 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!");
}
return a;
}
}
}
And that's it! You can augment Program.cs any way you like.
using System;
using System.Collections.Generic;
namespace Hello
{
public class FibonacciGenerator
{
private Dictionary<int, int> _cache = new Dictionary<int, int>();
return _cache[n];
}
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);
}
}
}
}
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/29/2017 • 6 min 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.
/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.
/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<IPet> pets = new List<IPet>
{
new Dog(),
new Cat()
};
NewTypes.csproj:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp1.1</TargetFramework>
</PropertyGroup>
</Project>
dotnet restore
dotnet run
Woof!
Meow!
Optional exercise: You can add a new pet type, such as a Bird , by extending this project. Make the bird's
TalkToOwner method give a Tweet! to the owner. Run the app again. The output will include Tweet!
You also have the option of manually adding the project reference by adding an <ItemGroup> node to the
NewTypesTests.csproj file:
<ItemGroup>
<ProjectReference Include="../../src/NewTypes/NewTypes.csproj" />
</ItemGroup>
NewTypesTests.csproj:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp1.1</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.0.0" />
<PackageReference Include="xunit" Version="2.2.0" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.2.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="../../src/NewTypes/NewTypes.csproj"/>
</ItemGroup>
</Project>
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;
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, the initial assertions with the Assert.NotEqual
checks specify that they are not equal. Always initially create your tests to fail once in order to check the logic of the tests.
This is an important step in test-driven design (TDD) methodology. After you confirm the tests fail, you adjust the assertions
to allow them to pass.
/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 dotnet restore command. Run the tests
with the dotnet test command. This command starts the test runner specified in the project file.
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.
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:
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
8/5/2017 • 10 min 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:
2.0, 3.0, and 3.5 .NET Framework 3.5 SP1 Runtime (or Windows 8+ version)
.NET
STANDAR
D 1.0 1.1 1.2 1.3 1.4 1.5 1.6 2.0
.NET Core 1.0 1.0 1.0 1.0 1.0 1.0 1.0 2.0
Windows 8.0
Phone
Silverlight
The columns represent .NET Standard versions. Each header cell is a link to a document that shows which APIs
got added in that version of .NET Standard.
The rows represent the different .NET implementations.
The version number in each cell indicates the minimum version of the implementation you'll need in order to
target that .NET Standard version.
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.
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard1.4</TargetFramework>
</PropertyGroup>
</Project>
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.
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.
You then insert this TFM into the TargetFramework section of your project file. For example, here's how you would
write a library which targets the .NET Framework 4.0:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net40</TargetFramework>
</PropertyGroup>
</Project>
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:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>netstandard1.4;net40;net45</TargetFrameworks>
</PropertyGroup>
<!-- Need to conditionally bring in references for the .NET Framework 4.0 target -->
<ItemGroup Condition="'$(TargetFramework)' == 'net40'">
<Reference Include="System.Net" />
</ItemGroup>
<!-- Need to conditionally bring in references for the .NET Framework 4.5 target -->
<ItemGroup Condition="'$(TargetFramework)' == 'net45'">
<Reference Include="System.Net.Http" />
<Reference Include="System.Threading.Tasks" />
</ItemGroup>
</Project>
The build system is aware of the following preprocessor symbols used in #if directives:
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/";
If you build this project with dotnet build , you'll notice three directories under the bin/ folder:
net40/
net45/
netstandard1.4/
NOTE
This uses some .NET Core CLI commands. See dotnet new and dotnet sln for more information.
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
dotnet restore
dotnet build
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 dotnet test command.
Your code will be automatically rebuilt when you invoke dotnet test command.
using AwesomeLibrary.CSharp;
open AwesomeLibrary.FSharp
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:
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:
The project files for both AwesomeLibrary.CSharp and AwesomeLibrary.FSharp will now reference
AwesomeLibrary.Core as a ProjectReference target. You can verify this by inspecting the project files and seeing
the following in them:
<ItemGroup>
<ProjectReference Include="..\AwesomeLibrary.Core\AwesomeLibrary.Core.csproj" />
</ItemGroup>
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
7/29/2017 • 1 min 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
7/29/2017 • 2 min 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.
"NETStandard.Library":"1.6.0"
"Microsoft.NETCore.App":"1.0.0"
"System.Net.Http":"4.1.0-*"
"System.Text.RegularExpressions":"4.0.10-rc3-24021-00"
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.
ICLRRuntimeHost2* runtimeHost;
FnGetCLRRuntimeHost pfnGetCLRRuntimeHost =
(FnGetCLRRuntimeHost)::GetProcAddress(coreCLRModule, "GetCLRRuntimeHost");
if (!pfnGetCLRRuntimeHost)
{
printf("ERROR - GetCLRRuntimeHost not found");
return -1;
}
hr = runtimeHost->Start();
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" 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';
// 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]);
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);
// 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.
// 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");
// 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";
DWORD domainId;
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.
((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.
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
8/14/2017 • 7 min to read • Edit Online
Prerequisites
Install the .NET Core 2.0 SDK or later versions.
Read the reference topic Custom templates for dotnet new.
{
"$schema": "http://json.schemastore.org/template",
"author": "Catalina Garcia",
"classifications": [ "Common", "Console" ],
"identity": "GarciaSoftware.ConsoleTemplate.CSharp",
"name": "Garcia Software Console Application",
"shortName": "garciaconsole"
}
The template is finished. At this point, you have two options for template distribution. To continue this tutorial,
choose one path or the other:
1. NuGet distribution: install the template from NuGet or from the local nupkg file, and use the installed template.
2. File system distribution.
Use NuGet Distribution
Pack the template into a NuGet package
1. Create a folder for the NuGet package. For the tutorial, the folder name
GarciaSoftware.ConsoleTemplate.CSharp is used, and the folder is created inside a
Documents/NuGetTemplates folder in the user's profile. Create a folder named content inside of the new
template folder to hold the project files.
2. Copy the contents of your project folder, together with its .template.config/template.json file, into the content
folder you created.
3. Next to the content folder, add a nuspec file. The nuspec file is an XML manifest file that describes a
package's contents and drives the process of creating the NuGet package.
4. Inside of a <packageTypes> element in the nuspec file, include a <packageType> element with a name
attribute value of Template . Both the content folder and the nuspec file should reside in the same directory.
The table shows the minimum nuspec file elements required to produce a template as a NuGet package.
See the .nuspec reference for the complete nuspec file schema.
The nuspec file for the tutorial is named GarciaSoftware.ConsoleTemplate.CSharp.nuspec and contains the
following content:
5. Create the package using the nuget pack <PATH_TO_NUSPEC_FILE> command. The following command
assumes that the folder that holds the NuGet assets is at
C:/Users/<USER>/Documents/Templates/GarciaSoftware.ConsoleTemplate.CSharp/. But wherever you
place the folder on your system, the nuget pack command accepts the path to the nuspec file:
nuget pack
C:/Users/<USER>/Documents/NuGetTemplates/GarciaSoftware.ConsoleTemplate.CSharp/GarciaSoftware.ConsoleTe
mplate.CSharp.nuspec
NOTE
The example is for demonstration purposes only. There isn't a GarciaSoftware.ConsoleTemplate.CSharp NuGet package
at nuget.org, and we don't recommend that you publish and consume test templates from NuGet. If you run the command,
no template is installed. However, you can install a template that hasn't been published to nuget.org by referencing the
nupkg file directly on your local file system as shown in the previous section Install the template from the local nupkg file.
If you'd like a live example of how to install a template from a package at nuget.org, you can use the NUnit 3
template for dotnet-new. This template sets up a project to use NUnit unit testing. Use the following command to
install it:
When you list the templates with dotnet new -l , you see the NUnit 3 Test Project with a short name of nunit in the
template list. You're ready to use the template in the next section.
The console shows that the project is created and that the project's packages are restored. After the command is
run, the project is ready for use.
To uninstall a template from a NuGet package stored at nuget.org
NOTE
The example is for demonstration purposes only. There isn't a GarciaSoftware.ConsoleTemplate.CSharp NuGet package
at nuget.org or installed with the .NET Core SDK. If you run the command, no package/template is uninstalled and you
receive the following exception:
If you installed the NUnit 3 template for dotnet-new and wish to uninstall it, use the following command:
See also
dotnet/templating GitHub repo Wiki
dotnet/dotnet-template-samples GitHub repo
How to create your own templates for dotnet new
template.json schema at the JSON Schema Store
Packages, Metapackages and Frameworks
8/5/2017 • 7 min to read • Edit Online
.NET Core is a platform made of NuGet packages. Some product experiences benefit from fine-grained definition
of packages while others from coarse-grained. To accommodate this duality, the product is distributed as a fine-
grained set of packages and then described in coarser chunks with a package type informally called a
"metapackage".
Each of the .NET Core packages support being run on multiple .NET implementations, represented as
frameworks. Some of those frameworks are traditional frameworks, like net46 , representing the .NET
Framework. Another set is new frameworks that can be thought of as "package-based frameworks", which
establish a new model for defining frameworks. These package-based frameworks are entirely formed and
defined as packages, forming a strong relationship between packages and frameworks.
Packages
.NET Core is split into a set of packages, which provide primitives, higher-level data types, app composition types
and common utilities. Each of these packages represent a single assembly of the same name. For example,
System.Runtime contains System.Runtime.dll.
There are advantages to defining packages in a fine-grained manner:
Fine-grained packages can ship on their own schedule with relatively limited testing of other packages.
Fine-grained packages can provide differing OS and CPU support.
Fine-grained packages can have dependencies specific to only one library.
Apps are smaller because unreferenced packages don't become part of the app distribution.
Some of these benefits are only used in certain circumstances. For example, NET Core packages will typically ship
on the same schedule with the same platform support. In the case of servicing, fixes can be distributed and
installed as small single package updates. Due to the narrow scope of change, the validation and time to make a
fix available is limited to what is needed for a single library.
The following is a list of the key NuGet packages for .NET Core:
System.Runtime - The most fundamental .NET Core package, including Object, String, Array, Action, and
IList<T>.
System.Collections - A set of (primarily) generic collections, including List<T> and Dictionary<TKey,TValue>.
System.Net.Http - A set of types for HTTP network communication, including HttpClient and
HttpResponseMessage.
System.IO.FileSystem - A set of types for reading and writing to local or networked disk-based storage,
including File and Directory.
System.Linq - A set of types for querying objects, including Enumerable and ILookup<TKey,TElement>.
System.Reflection - A set of types for loading, inspecting, and activating types, including Assembly, TypeInfo
and MethodInfo.
Typically, rather than including packages in your projects on a package-by-package basis, it is far easier to
include a metapackage, which is a set of packages that are often used together. (For more information on
metapackages, see the following section.) However, when you need a single package, you can include it as in the
example below, which references the System.Runtime package.
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard1.6</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="System.Runtime" Version="4.3.0" />
</ItemGroup>
</Project>
Metapackages
Metapackages are a NuGet package convention for describing a set of packages that are meaningful together.
They represent this set of packages by making them dependencies. They can optionally establish a framework for
this set of packages by specifying a framework.
Previous versions of the .NET Core tools (both project.json and csproj-based tools) by default specified both a
framework and a metapackage. Currently, however, the metapackage is implicitly referenced by the target
framework, so that each metapackage is tied to a target framework. For example, the netstandard1.6 framework
references the NetStandard.Library version 1.6.0 metapackage. Similarly, the netcoreapp1.1 framework
references the Microsoft.NETCore.App Version 1.1.0 metapackage. For more information, see Implicit
metapackage package reference in the .NET Core SDK.
Targeting a framework and implicitly referencing a metapackage means that you in effect are adding a reference
to each of its dependent packages as a single gesture. That makes all of the libraries in those packages available
for IntelliSense (or similar experience) and for publishing your app.
There are advantages to using metapackages:
Provides a convenient user experience to reference a large set of fine-grained packages.
Defines a set of packages (including specific versions) that are tested and work well together.
The .NET Standard metapackage is:
NETStandard.Library - Describes the libraries that are part of the ".NET Standard". Applies to all .NET
implementations (for example, .NET Framework, .NET Core and Mono) that support .NET Standard. Establishes
the 'netstandard' framework.
The key .NET Core metapackages are:
Microsoft.NETCore.App - Describes the libraries that are part of the .NET Core distribution. Establishes the
.NETCoreApp framework. Depends on the smaller NETStandard.Library .
Microsoft.NETCore.Portable.Compatibility - A set of compatibility facades that enable mscorlib-based Portable
Class Libraries (PCLs) to run on .NET Core.
Frameworks
.NET Core packages each support a set of runtime frameworks. Frameworks describe an available API set (and
potentially other characteristics) that you can rely on when you target a given framework. They are versioned as
new APIs are added.
For example, System.IO.FileSystem supports the following frameworks:
.NETFramework,Version=4.6
.NETStandard,Version=1.3
6 Xamarin platforms (for example, xamarinios10)
It is useful to contrast the first two of these frameworks, since they are examples of the two different ways that
frameworks are defined.
The .NETFramework,Version=4.6 framework represents the available APIs in the .NET Framework 4.6. You can
produce libraries compiled with the .NET Framework 4.6 reference assemblies and then distribute those libraries
in NuGet packages in a net46 lib folder. It will be used for apps that target the .NET Framework 4.6 or that are
compatible with it. This is how all frameworks have traditionally worked.
The .NETStandard,Version=1.3 framework is a package-based framework. It relies on packages that target the
framework to define and expose APIs in terms of the framework.
Package-based Frameworks
There is a two-way relationship between frameworks and packages. The first part is defining the APIs available
for a given framework, for example netstandard1.3 . Packages that target netstandard1.3 (or compatible
frameworks, like netstandard1.0 ) define the APIs available for netstandard1.3 . That may sound like a circular
definition, but it isn't. By virtue of being "package-based", the API definition for the framework comes from
packages. The framework itself doesn't define any APIs.
The second part of the relationship is asset selection. Packages can contain assets for multiple frameworks. Given
a reference to a set of packages and/or metapackages, the framework is needed to determine which asset should
be selected, for example net46 or netstandard1.3 . It is important to select the correct asset. For example, a
net46 asset is not likely to be compatible with .NET Framework 4.0 or .NET Core 1.0.
You can see this relationship in the image above. The API targets and defines the framework. The framework is
used for asset selection. The asset gives you the API.
The two primary package-based frameworks used with .NET Core are:
netstandard
netcoreapp
.NET Standard
The .NET Standard (target framework moniker: netstandard ) framework represents the APIs defined by and built
on top of the .NET Standard. Libraries that are intended to run on multiple runtimes should target this
framework. They will be supported on any .NET Standard compliant runtime, such as .NET Core, .NET Framework
and Mono/Xamarin. Each of these runtimes supports a set of .NET Standard versions, depending on which APIs
they implement.
The netstandard framework implicitly references the NETStandard.Library metapackage. For example, the
following MSBuild project file indicates that the project targets netstandard1.6 , which references the
NETStandard.Library version 1.6 metapackage.
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard1.6</TargetFramework>
</PropertyGroup>
</Project>
However, the framework and metapackage references in the project file do not need to match, and you can use
the <NetStandardImplicitPackageVersion> element in your project file to specify a framework version that is lower
than the metapackage version. For example, the following project file is valid.
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard1.3</TargetFramework>
</PropertyGroup>
<ItemGroup>
<NetStandardImplicitPackageVersion Include="NetStandardLibrary" Version="1.6.0" />
</ItemGroup>
</Project>
It may seem strange to target netstandard1.3 but use the 1.6.0 version of NETStandard.Library . It is a valid use-
case, since the metapackage maintains support for older netstandard versions. It could be the case you've
standardized on the 1.6.0 version of the metapackage and use it for all your libraries, which target a variety of
netstandard versions. With this approach, you only need to restore NETStandard.Library 1.6.0 and not earlier
versions.
The reverse would not be valid: targeting netstandard1.6 with the 1.3.0 version of NETStandard.Library . You
cannot target a higher framework with a lower metapackage, since the lower version metapackage will not
expose any assets for that higher framework. The versioning scheme for metapackages asserts that
metapackages match the highest version of the framework they describe. By virtue of the versioning scheme, the
first version of NETStandard.Library is v1.6.0 given that it contains netstandard1.6 assets. v1.3.0 is used in the
example above, for symmetry with the example above, but does not actually exist.
.NET Core Application
The .NET Core Application (TFM: netcoreapp ) framework represents the packages and associated APIs that come
with the .NET Core distribution and the console application model that it provides. .NET Core apps must use this
framework, due to targeting the console application model, as should libraries that intended to run only on .NET
Core. Using this framework restricts apps and libraries to running only on .NET Core.
The Microsoft.NETCore.App metapackage targets the netcoreapp framework. It provides access to ~60 libraries,
~40 provided by the NETStandard.Library package and ~20 more in addition. You can reference additional
libraries that target netcoreapp or compatible frameworks, such as netstandard , to get access to additional APIs.
Most of the additional libraries provided by Microsoft.NETCore.App also target netstandard given that their
dependencies are satisfied by other netstandard libraries. That means that netstandard libraries can also
reference those packages as dependencies.
High-level overview of changes in the .NET Core
tools
7/29/2017 • 4 min to read • Edit Online
This document describes the changes associated with moving from project.json to MSBuild and the csproj project
system with information on the changes to the layering of the .NET Core tooling and the implementation of the CLI
commands. These changes occurred with the release of .NET Core SDK 1.0 and Visual Studio 2017 on March 7,
2017 (see the announcement) but were initially implemented with the release of the .NET Core SDK Preview 3.
NOTE
If you are new to MSBuild and would like to learn more about it, you can start by reading the MSBuild Concepts article.
The layering of the tools is quite simple. At the bottom we have the .NET Core Command Line tools as a
foundation. All other, higher-level tools such as Visual Studio or Visual Studio Code, depend and rely on the CLI to
build projects, restore dependencies and so on. This meant that, for example, if Visual Studio wanted to perform a
restore operation, it would call into dotnet restore command in the CLI.
With the move to the new project system, the previous diagram changes:
The main difference is that the CLI is not the foundational layer anymore; this role is now filled by the "shared SDK
component". This shared SDK component is a set of targets and associated tasks that are responsible for compiling
your code, publishing it, packing NuGet packages etc. The SDK itself is open-source and is available on GitHub on
the SDK repo.
NOTE
A "target" is a MSBuild term that indicates a named operation that MSBuild can invoke. It is usually coupled with one or
more tasks that execute some logic that the target is supposed to do. MSBuild supports many ready-made targets such as
Copy or Execute ; it also allows users to write their own tasks using managed code and define targets to execute those
tasks. For more information, see MSBuild tasks.
All the toolsets now consume the shared SDK component and its targets, CLI included. For example, the next
version of Visual Studio will not call into dotnet restore command to restore dependencies for .NET Core projects,
it will use the "Restore" target directly. Since these are MSBuild targets, you can also use raw MSBuild to execute
them using the dotnet msbuild command.
CLI commands
The shared SDK component means that the majority of existing CLI commands have been re-implemented as
MSBuild tasks and targets. What does this mean for the CLI commands and your usage of the toolset?
From an usage perspective, it doesn't change the way you use the CLI. The CLI still has the core commands that
exist in Preview 2 release:
new
restore
run
build
publish
test
pack
These commands still do what you expect them to do (new up a project, build it, publish it, pack it and so on).
Majority of the options are not changed, and are still there, and you can consult either the commands' help screens
(using dotnet <command> --help ) or documentation on this site to get familiar with any changes.
From an execution perspective, the CLI commands will take their parameters and construct a call to "raw" MSBuild
that will set the needed properties and run the desired target. To better illustrate this, consider the following
command:
dotnet publish -o pub -c Release
This command is publishing an application into a pub folder using the "Release" configuration. Internally, this
command gets translated into the following MSBuild invocation:
dotnet msbuild /t:Publish /p:OutputPath=pub /p:Configuration=Release
The notable exception to this rule are new and run commands, as they have not been implemented as MSBuild
targets.
Managing dependencies with .NET Core SDK 1.0
7/29/2017 • 2 min to read • Edit Online
With the move of .NET Core projects from project.json to csproj and MSBuild, a significant investment also
happened that resulted in unification of the project file and assets that allow tracking of dependencies. For .NET
Core projects this is similar to what project.json did. There is no separate JSON or XML file that tracks NuGet
dependencies. With this change, we've also introduced another type of reference into the csproj syntax called the
<PackageReference> .
This document describes the new reference type. It also shows how to add a package dependency using this new
reference type to your project.
If you are familiar with MSBuild, it will look familiar to the other reference types that already exist. The key is the
Include statement which specifies the package id that you wish to add to the project. The <Version> child element
specifies the version to get. The versions are specified as per NuGet version rules.
NOTE
If you are not familiar with the overall csproj syntax, see the MSBuild project reference documentation for more
information.
Adding a dependency that is available only in a specific target is done using conditions like in the following
example:
The above means that the dependency will only be valid if the build is happening for that given target. The
$(TargetFramework) in the condition is a MSBuild property that is being set in the project. For most common .NET
Core applications, you will not need to do this.
After this, we save the project and run the dotnet restore command to install the dependency.
The full project looks like this:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp1.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="9.0.1" />
</ItemGroup>
</Project>
This document outlines the changes that were added to the project files as part of the move from project.json to
csproj and MSBuild. For more information about general project file syntax and reference, see the MSBuild project
file documentation.
<PropertyGroup>
<TargetFramework>netcoreapp1.1</TargetFramework>
</PropertyGroup>
<PropertyGroup>
<TargetFrameworks>netcoreapp1.1;net462</TargetFrameworks>
</PropertyGroup>
Recommendations
Since Microsoft.NETCore.App or NetStandard.Library metapackages are implicitly referenced, the following are
our recommended best practices:
Never have an explicit reference to the Microsoft.NETCore.App or NetStandard.Library metapackages via a
<PackageReference> item in your project file.
If you need a specific version of the runtime, you should use the <RuntimeFrameworkVersion> property in your
project (for example, 1.0.4 ) instead of referencing the metapackage.
This might happen if you are using self-contained deployments and you need a specific patch version of
1.0.0 LTS runtime, for example.
If you need a specific version of the NetStandard.Library metapackage, you can use the
<NetStandardImplicitPackageVersion> property and set the version you need.
If you have globs in your project and you try to build it using the newest SDK, you'll get the following error:
Duplicate Compile items were included. The .NET SDK includes Compile items from your project directory by
default. You can either remove these items from your project file, or set the 'EnableDefaultCompileItems'
property to 'false' if you want to explicitly include them in your project file.
In order to get around this error, you can either remove the explicit Compile items that match the ones listed on
the previous table, or you can set the <EnableDefaultCompileItems> property to false , like this:
<PropertyGroup>
<EnableDefaultCompileItems>false</EnableDefaultCompileItems>
</PropertyGroup>
Setting this property to false will override implicit inclusion and the behavior will revert back to the previous
SDKs where you had to specify the default globs in your project.
This change does not modify the main mechanics of other includes. However, if you wish to specify, for example,
some files to get published with your app, you can still use the known mechanisms in csproj for that (for example,
the <Content> element).
Recommendation
With csproj, we recommend that you remove the default globs from your project and only add file paths with
globs for those artifacts that your app/library needs for various scenarios (for example, runtime and NuGet
packaging).
If the project has multiple target frameworks, the results of the command should be focused on only one of them
by specifying it as an MSBuild property:
dotnet msbuild /p:TargetFramework=netcoreapp2.0 /pp:fullproject.xml
Additions
Sdk attribute
The <Project> element of the .csproj file has a new attribute called Sdk . Sdk specifies which SDK will be used by
the project. The SDK, as the layering document describes, is a set of MSBuild tasks and targets that can build .NET
Core code. We ship two main SDKs with the .NET Core tools:
1. The .NET Core SDK with the ID of Microsoft.NET.Sdk
2. The .NET Core web SDK with the ID of Microsoft.NET.Sdk.Web
You need to have the Sdk attribute set to one of those IDs on the <Project> element in order to use the .NET
Core tools and build your code.
PackageReference
Item that specifies a NuGet dependency in the project. The Include attribute specifies the package ID.
Version
Version specifies the version of the package to restore. The attribute respects the rules of the NuGet versioning
scheme. The default behavior is an exact version match. For example, specifying Version="1.2.3" is equivalent to
NuGet notation [1.2.3] for the exact 1.2.3 version of the package.
IncludeAssets, ExcludeAssets and PrivateAssets
IncludeAssets attribute specifies what assets belonging to the package specified by <PackageReference> should
be consumed.
ExcludeAssets attribute specifies what assets belonging to the package specified by <PackageReference> should
not be consumed.
PrivateAssetsattribute specifies what assets belonging to the package specified by <PackageReference> should
be consumed but that they should not flow to the next project.
NOTE
PrivateAssets is equivalent to the project.json/xproj SuppressParent element.
Version
Version specifies the version of the package to restore. The attribute respects the rules of the NuGet versioning
scheme. The default behavior is an exact version match. For example, specifying Version="1.2.3" is equivalent to
NuGet notation [1.2.3] for the exact 1.2.3 version of the package.
RuntimeIdentifiers
The <RuntimeIdentifiers> element lets you specify a semicolon-delimited list of Runtime Identifiers (RIDs) for the
project. RIDs enable publishing a self-contained deployments.
<RuntimeIdentifiers>win10-x64;osx.10.11-x64;ubuntu.16.04-x64</RuntimeIdentifiers>
RuntimeIdentifier
The <RuntimeIdentifier> element allows you to specify only one Runtime Identifier (RID) for the project. RIDs
enable publishing a self-contained deployment.
<RuntimeIdentifier>ubuntu.16.04-x64</RuntimeIdentifier>
PackageTargetFallback
The <PackageTargetFallback> element allows you to specify a set of compatible targets to be used when restoring
packages. It's designed to allow packages that use the dotnet TxM (Target x Moniker) to operate with packages that
don't declare a dotnet TxM. If your project uses the dotnet TxM, then all the packages it depends on must also have
a dotnet TxM, unless you add the <PackageTargetFallback> to your project in order to allow non-dotnet platforms
to be compatible with dotnet.
The following example provides the fallbacks for all targets in your project:
<PackageTargetFallback>
$(PackageTargetFallback);portable-net45+win8+wpa81+wp8
</PackageTargetFallback >
The following example specifies the fallbacks only for the netcoreapp1.0 target:
<PackageTargetFallback Condition="'$(TargetFramework)'=='netcoreapp1.0'">
$(PackageTargetFallback);portable-net45+win8+wpa81+wp8
</PackageTargetFallback >
NOTE
If the .nuspec file is specified, it's used exclusively for packaging information and any information in the projects is not used.
NuspecBasePath
Base path for the .nuspec file.
NuspecProperties
Semicolon separated list of key=value pairs.
Migrating .NET Core projects to the .csproj format
7/29/2017 • 4 min to read • Edit Online
This document will cover migration scenarios for .NET Core projects and will go over the following three migration
scenarios:
1. Migration from a valid latest schema of project.json to csproj
2. Migration from DNX to csproj
3. Migration from RC3 and previous .NET Core csproj projects to the final format
Visual Studio will migrate the projects chosen automatically. When migrating a solution, if you don't choose all
projects, the same dialog will appear asking you to upgrade the remaining projects from that solution. After the
project is migrated, you can see and modify its contents by right-clicking the project in the Solution Explorer
window and selecting Edit <project name>.csproj.
Files that were migrated (project.json, global.json, .xproj and solution file) will be moved to a Backup folder. The
solution file that is migrated will be upgraded to Visual Studio 2017 and you won't be able to open that solution file
in previous versions of Visual Studio. A file named UpgradeLog.htm is also saved and automatically opened that
contains a migration report.
IMPORTANT
The new tooling is not available in Visual Studio 2015, so you cannot migrate your projects using that version of Visual
Studio.
dotnet migrate
In the command-line scenario, you can use the dotnet migrate command. It will migrate a project, a solution or a
set of folders in that order, depending on which ones were found. When you migrate a project, the project and all
its dependencies are migrated.
Files that were migrated (project.json, global.json and .xproj) will be moved to a backup folder.
NOTE
If you are using Visual Studio Code, the dotnet migrate command will not modify Visual Studio Code-specific files such as
tasks.json . These files need to be changed manually. This is also true if you are using Project Ryder or any editor or
Integrated Development Environment (IDE) other than Visual Studio.
See A mapping between project.json and csproj properties for a comparison of project.json and csproj formats.
Common issues
If you get an error: "No executable found matching command dotnet-migrate":
Run dotnet --version to see which version you are using. dotnet migrate requires .NET Core CLI RC3 or higher.
You’ll get this error if you have a global.json file in the current or parent directory and the sdk version is set to an
older version.
NOTE
DNX has become officially deprecated during the Preview 1 release of the .NET Core CLI.
See also
Port, Migrate, and Upgrade Visual Studio Projects
A mapping between project.json and csproj
properties
7/29/2017 • 6 min to read • Edit Online
By Nate McMaster
During the development of the .NET Core tooling, an important design change was made to no longer support
project.json files and instead move the .NET Core projects to the MSBuild/csproj format.
This article shows how the settings in project.json are represented in the MSBuild/csproj format so you can learn
how to use the new format and understand the changes made by the migration tools when you're upgrading your
project to the latest version of the tooling.
<Project Sdk="Microsoft.NET.Sdk">
...
</Project>
{
"name": "MyProjectName"
}
No longer supported. In csproj, this is determined by the project filename, which is defined by the directory name.
For example, MyProjectName.csproj .
By default, the project filename also specifies the value of the <AssemblyName> and <PackageId> properties.
<PropertyGroup>
<AssemblyName>MyProjectName</AssemblyName>
<PackageId>MyProjectName</PackageId>
</PropertyGroup>
The <AssemblyName> will have a different value than <PackageId> if buildOptions\outputName property was defined
in project.json. For more information, see Other common build options.
version
{
"version": "1.0.0-alpha-*"
}
You can also use the Version property, but this may override version settings during packaging:
<PropertyGroup>
<Version>1.0.0-alpha</Version>
</PropertyGroup>
{
"authors": [ "Anne", "Bob" ],
"company": "Contoso",
"language": "en-US",
"title": "My library",
"description": "This is my library.\r\nAnd it's really great!",
"copyright": "Nugetizer 3000",
"userSecretsId": "xyz123"
}
<PropertyGroup>
<Authors>Anne;Bob</Authors>
<Company>Contoso</Company>
<NeutralLanguage>en-US</NeutralLanguage>
<AssemblyTitle>My library</AssemblyTitle>
<Description>This is my library.
And it's really great!</Description>
<Copyright>Nugetizer 3000</Copyright>
<UserSecretsId>xyz123</UserSecretsId>
</PropertyGroup>
frameworks
One target framework
{
"frameworks": {
"netcoreapp1.0": {}
}
}
<PropertyGroup>
<TargetFramework>netcoreapp1.0</TargetFramework>
</PropertyGroup>
Use the TargetFrameworks property to define your list of target frameworks. Use semi-colon to separate multiple
framework values.
<PropertyGroup>
<TargetFrameworks>netcoreapp1.0;net451</TargetFrameworks>
</PropertyGroup>
dependencies
IMPORTANT
If the dependency is a project and not a package, the format is different. For more information, see the dependency type
section.
NETStandard.Library metapackage
{
"dependencies": {
"NETStandard.Library": "1.6.0"
}
}
<PropertyGroup>
<NetStandardImplicitPackageVersion>1.6.0</NetStandardImplicitPackageVersion>
</PropertyGroup>
Microsoft.NETCore.App metapackage
{
"dependencies": {
"Microsoft.NETCore.App": "1.0.0"
}
}
<PropertyGroup>
<RuntimeFrameworkVersion>1.0.3</RuntimeFrameworkVersion>
</PropertyGroup>
Note that the <RuntimeFrameworkVersion> value in the migrated project is determined by the version of the SDK you
have installed.
Top-level dependencies
{
"dependencies": {
"Microsoft.AspNetCore": "1.1.0"
}
}
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore" Version="1.1.0" />
</ItemGroup>
Per-framework dependencies
{
"framework": {
"net451": {
"dependencies": {
"System.Collections.Immutable": "1.3.1"
}
},
"netstandard1.5": {
"dependencies": {
"Newtonsoft.Json": "9.0.1"
}
}
}
}
<ItemGroup Condition="'$(TargetFramework)'=='net451'">
<PackageReference Include="System.Collections.Immutable" Version="1.3.1" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)'=='netstandard1.5'">
<PackageReference Include="Newtonsoft.Json" Version="9.0.1" />
</ItemGroup>
imports
{
"dependencies": {
"YamlDotNet": "4.0.1-pre309"
},
"frameworks": {
"netcoreapp1.0": {
"imports": [
"dnxcore50",
"dotnet"
]
}
}
}
<PropertyGroup>
<PackageTargetFallback>dnxcore50;dotnet</PackageTargetFallback>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="YamlDotNet" Version="4.0.1-pre309" />
</ItemGroup>
dependency type
type: project
{
"dependencies": {
"MyOtherProject": "1.0.0-*",
"AnotherProject": {
"type": "project"
}
}
}
<ItemGroup>
<ProjectReference Include="..\MyOtherProject\MyOtherProject.csproj" />
<ProjectReference Include="..\AnotherProject\AnotherProject.csproj" />
</ItemGroup>
NOTE
This will break the way that dotnet pack --version-suffix $suffix determines the dependency version of a project
reference.
type: build
{
"dependencies": {
"Microsoft.EntityFrameworkCore.Design": {
"version": "1.1.0",
"type": "build"
}
}
}
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="1.1.0" PrivateAssets="All" />
</ItemGroup>
type: platform
{
"dependencies": {
"Microsoft.NETCore.App": {
"version": "1.1.0",
"type": "platform"
}
}
}
runtimes
{
"runtimes": {
"win7-x64": {},
"osx.10.11-x64": {},
"ubuntu.16.04-x64": {}
}
}
<PropertyGroup>
<RuntimeIdentifiers>win7-x64;osx.10.11-x64;ubuntu.16.04-x64</RuntimeIdentifiers>
</PropertyGroup>
tools
{
"tools": {
"Microsoft.EntityFrameworkCore.Tools.DotNet": "1.0.0-*"
}
}
<ItemGroup>
<DotNetCliToolReference Include="Microsoft.EntityFrameworkCore.Tools.DotNet" Version="1.0.0" />
</ItemGroup>
NOTE
imports on tools are not supported in csproj. Tools that need imports will not work with the new Microsoft.NET.Sdk .
buildOptions
See also Files.
emitEntryPoint
{
"buildOptions": {
"emitEntryPoint": true
}
}
<PropertyGroup>
<OutputType>Exe</OutputType>
</PropertyGroup>
If emitEntryPoint was false , the value of OutputType is converted to Library , which is the default value:
{
"buildOptions": {
"emitEntryPoint": false
}
}
<PropertyGroup>
<OutputType>Library</OutputType>
<!-- or, omit altogether. It defaults to 'Library' -->
</PropertyGroup>
keyFile
{
"buildOptions": {
"keyFile": "MyKey.snk"
}
}
<PropertyGroup>
<AssemblyOriginatorKeyFile>MyKey.snk</AssemblyOriginatorKeyFile>
<SignAssembly>true</SignAssembly>
<PublicSign Condition="'$(OS)' != 'Windows_NT'">true</PublicSign>
</PropertyGroup>
{
"buildOptions": {
"warningsAsErrors": true,
"nowarn": ["CS0168", "CS0219"],
"xmlDoc": true,
"preserveCompilationContext": true,
"outputName": "Different.AssemblyName",
"debugType": "portable",
"allowUnsafe": true,
"define": ["TEST", "OTHERCONDITION"]
}
}
<PropertyGroup>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<NoWarn>$(NoWarn);CS0168;CS0219</NoWarn>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<PreserveCompilationContext>true</PreserveCompilationContext>
<AssemblyName>Different.AssemblyName</AssemblyName>
<DebugType>portable</DebugType>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<DefineConstants>$(DefineConstants);TEST;OTHERCONDITION</DefineConstants>
</PropertyGroup>
packOptions
See also Files.
Common pack options
{
"packOptions": {
"summary": "numl is a machine learning library intended to ease the use of using standard modeling
techniques for both prediction and clustering.",
"tags": ["machine learning", "framework"],
"releaseNotes": "Version 0.9.12-beta",
"iconUrl": "http://numl.net/images/ico.png",
"projectUrl": "http://numl.net",
"licenseUrl": "https://raw.githubusercontent.com/sethjuarez/numl/master/LICENSE.md",
"requireLicenseAcceptance": false,
"repository": {
"type": "git",
"url": "https://raw.githubusercontent.com/sethjuarez/numl"
},
"owners": ["Seth Juarez"]
}
}
<PropertyGroup>
<!-- summary is not migrated from project.json, but you can use the <Description> property for that if
needed. -->
<PackageTags>machine learning;framework</PackageTags>
<PackageReleaseNotes>Version 0.9.12-beta</PackageReleaseNotes>
<PackageIconUrl>http://numl.net/images/ico.png</PackageIconUrl>
<PackageProjectUrl>http://numl.net</PackageProjectUrl>
<PackageLicenseUrl>https://raw.githubusercontent.com/sethjuarez/numl/master/LICENSE.md</PackageLicenseUrl>
<PackageRequireLicenseAcceptance>false</PackageRequireLicenseAcceptance>
<RepositoryType>git</RepositoryType>
<RepositoryUrl>https://raw.githubusercontent.com/sethjuarez/numl</RepositoryUrl>
<!-- owners is not supported in MSBuild -->
</PropertyGroup>
There is no equivalent for the owners element in MSBuild. For summary , you can use the MSBuild <Description>
property, even though the value of summary is not migrated automatically to that property, since that property is
mapped to the description element.
scripts
{
"scripts": {
"precompile": "generateCode.cmd",
"postpublish": [ "obfuscate.cmd", "removeTempFiles.cmd" ]
}
}
All settings in this group, except for the "System.GC.Server" property, are placed into a file called
runtimeconfig.template.json in the project folder, with options lifted to the root object during the migration
process:
{
"configProperties": {
"System.GC.Concurrent": true,
"System.GC.RetainVM": true,
"System.Threading.ThreadPool.MinThreads": 4,
"System.Threading.ThreadPool.MaxThreads": 25
}
}
<PropertyGroup>
<ServerGarbageCollection>true</ServerGarbageCollection>
</PropertyGroup>
However, you can set all those values in the csproj as well as MSBuild properties:
<PropertyGroup>
<ServerGarbageCollection>true</ServerGarbageCollection>
<ConcurrentGarbageCollection>true</ConcurrentGarbageCollection>
<RetainVMGarbageCollection>true</RetainVMGarbageCollection>
<ThreadPoolMinThreads>4</ThreadPoolMinThreads>
<ThreadPoolMaxThreads>25</ThreadPoolMaxThreads>
</PropertyGroup>
shared
{
"shared": "shared/**/*.cs"
}
Not supported in csproj. You must instead create include content files in your .nuspec file. For more information,
see Including content files.
files
In project.json, build and pack could be extended to compile and embed from different folders. In MSBuild, this is
done using items. The following example is a common conversion:
{
"buildOptions": {
"compile": {
"copyToOutput": "notes.txt",
"include": "../Shared/*.cs",
"exclude": "../Shared/Not/*.cs"
},
"embed": {
"include": "../Shared/*.resx"
}
},
"packOptions": {
"include": "Views/",
"mappings": {
"some/path/in/project.txt": "in/package.txt"
}
},
"publishOptions": {
"include": [
"files/",
"publishnotes.txt"
]
}
}
<ItemGroup>
<Compile Include="..\Shared\*.cs" Exclude="..\Shared\Not\*.cs" />
<EmbeddedResource Include="..\Shared\*.resx" />
<Content Include="Views\**\*" PackagePath="%(Identity)" />
<None Include="some/path/in/project.txt" Pack="true" PackagePath="in/package.txt" />
NOTE
Many of the default globbing patterns are added automatically by the .NET Core SDK. For more information, see Default
Compile Item Values.
PackagePath="%(Identity)" is a short way of setting package path to the project-relative file path.
testRunner
xUnit
{
"testRunner": "xunit",
"dependencies": {
"dotnet-test-xunit": "<any>"
}
}
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.0.0-*" />
<PackageReference Include="xunit" Version="2.2.0-*" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.2.0-*" />
</ItemGroup>
MSTest
{
"testRunner": "mstest",
"dependencies": {
"dotnet-test-mstest": "<any>"
}
}
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.0.0-*" />
<PackageReference Include="MSTest.TestAdapter" Version="1.1.12-*" />
<PackageReference Include="MSTest.TestFramework" Version="1.1.11-*" />
</ItemGroup>
See Also
High-level overview of changes in CLI
Migrating from DNX to .NET Core CLI (project.json)
7/29/2017 • 8 min to read • Edit Online
Overview
The RC1 release of .NET Core and ASP.NET Core 1.0 introduced DNX tooling. The RC2 release of .NET Core and
ASP.NET Core 1.0 moved from DNX to the .NET Core CLI.
As a slight refresher, let's recap what DNX was about. DNX was a runtime and a toolset used to build .NET Core
and, more specifically, ASP.NET Core 1.0 applications. It consisted of 3 main pieces:
1. DNVM - an install script for obtaining DNX
2. DNX (Dotnet Execution Runtime) - the runtime that executes your code
3. DNU (Dotnet Developer Utility) - tooling for managing dependencies, building and publishing your applications
With the introduction of the CLI, all of the above are now part of a single toolset. However, since DNX was available
in RC1 timeframe, you might have projects that were built using it that you would want to move off to the new CLI
tooling.
This migration guide will cover the essentials on how to migrate projects off of DNX and onto .NET Core CLI. If you
are just starting a project on .NET Core from scratch, you can freely skip this document.
dnx [command] (for example, "dnx N/A* In DNX world, run a command as
web") defined in the project.json.
{
"sdk": {
"version": "1.0.0-preview2-003121"
}
}
"buildOptions": {
"emitEntryPoint": true
}
This instructs dotnet build to emit an entry point for your application, effectively making your code runnable. If
you are building a class library, simply omit the above section. Of course, once you add the above snippet to your
project.json file, you need to add a static entry point. With the move off DNX, the DI services it provided are no
longer available and thus this needs to be a basic .NET entry point: static void Main() .
If you have a "commands" section in your project.json , you can remove it. Some of the commands that used to
exist as DNU commands, such as Entity Framework CLI commands, are being ported to be per-project extensions
to the CLI. If you built your own commands that you are using in your projects, you need to replace them with CLI
extensions. In this case, the commands node in project.json needs to be replaced by the tools node and it needs
to list the tools dependencies.
After these things are done, you need to decide which type of portability you wish for you app. With .NET Core, we
have invested into providing a spectrum of portability options that you can choose from. For instance, you may
want to have a fully portable application or you may want to have a self-contained application. The portable
application option is more like .NET Framework applications work: it needs a shared component to execute it on
the target machine (.NET Core). The self-contained application doesn't require .NET Core to be installed on the
target, but you have to produce one application for each OS you wish to support. These portability types and more
are discussed in the application portability type document.
Once you make a call on what type of portability you want, you need to change your targeted framework(s). If you
were writing applications for .NET Core, you were most likely using dnxcore50 as your targeted framework. With
the CLI and the changes that the new .NET Standard brought, the framework needs to be one of the following:
1. netcoreapp1.0 - if you are writing applications on .NET Core (including ASP.NET Core applications)
2. netstandard1.6 - if you are writing class libraries for .NET Core
If you are using other dnx targets, like dnx451 you will need to change those as well. dnx451 should be changed
to net451 . Please refer to the .NET Standard topic for more information.
Your project.json is now mostly ready. You need to go through your dependencies list and update the
dependencies to their newer versions, especially if you are using ASP.NET Core dependencies. If you were using
separate packages for BCL APIs, you can use the runtime package as explained in the application portability type
document.
Once you are ready, you can try restoring with dotnet restore . Depending on the version of your dependencies,
you may encounter errors if NuGet cannot resolve the dependencies for one of the targeted frameworks above.
This is a "point-in-time" problem; as time progresses, more and more packages will include support for these
frameworks. For now, if you run into this, you can use the imports statement within the framework node to
specify to NuGet that it can restore the packages targeting the framework within the "imports" statement. The
restoring errors you get in this case should provide enough information to tell you which frameworks you need to
import. If you are slightly lost or new to this, in general, specifying dnxcore50 and portable-net45+win8 in the
imports statement should do the trick. The JSON snippet below shows how this looks like:
"frameworks": {
"netcoreapp1.0": {
"imports": ["dnxcore50", "portable-net45+win8"]
}
}
Running dotnet build will show any eventual build errors, though there shouldn't be too many of them. After
your code is building and running properly, you can test it out with the runner. Execute
dotnet <path-to-your-assembly> and see it run.
.NET Core application deployment
7/29/2017 • 3 min to read • Edit Online
You can create two types of deployments for .NET Core applications:
Framework-dependent deployment. As the name implies, framework-dependent deployment (FDD) relies
on the presence of a shared system-wide version of .NET Core on the target system. Because .NET Core is
already present, your app is also portable between installations of .NET Core. Your app contains only its
own code and any third-party dependencies that are outside of the .NET Core libraries. FDDs contain .dll
files that can be launched by using the dotnet utility from the command line. For example, dotnet app.dll
runs an application named app .
Self-contained deployment. Unlike FDD, a self-contained deployment (SCD) doesn't rely on the presence
of shared components on the target system. All components, including both the .NET Core libraries and
the .NET Core runtime, are included with the application and are isolated from other .NET Core
applications. SCDs include an executable (such as app.exe on Windows platforms for an application
named app ), which is a renamed version of the platform-specific .NET Core host, and a .dll file (such as
app.dll), which is the actual application.
Step-by-step examples
For step-by-step examples of deploying .NET Core apps with CLI tools, see Deploying .NET Core Apps with CLI
Tools. For step-by-step examples of deploying .NET Core apps with Visual Studio, see Deploying .NET Core Apps
with Visual Studio. Each topic includes examples of the following deployments:
Framework-dependent deployment
Framework-dependent deployment with third-party dependencies
Self-contained deployment
Self-contained deployment with third-party dependencies
See also
Deploying .NET Core Apps with CLI Tools
Deploying .NET Core Apps with Visual Studio
Packages, Metapackages and Frameworks
.NET Core Runtime IDentifier (RID) catalog
Deploying .NET Core apps with command-line
interface (CLI) tools
7/29/2017 • 8 min to read • Edit Online
You can deploy a .NET Core application either as a framework-dependent deployment, which includes your
application binaries but depends on the presence of .NET Core on the target system, or as a self-contained
deployment, which includes both your application and the .NET Core binaries. For an overview, see .NET Core
Application Deployment.
The following sections show how to use .NET Core command-line interface tools to create the following kinds of
deployments:
Framework-dependent deployment
Framework-dependent deployment with third-party dependencies
Self-contained deployment
Self-contained deployment with third-party dependencies
When working from the command line, you can use a program editor of your choice. If your program editor is
Visual Studio Code, you can open a command console inside your Visual Studio Code environment by selecting
View > Integrated Terminal.
Framework-dependent deployment
Deploying a framework-dependent deployment with no third-party dependencies simply involves building, testing,
and publishing the app. A simple example written in C# illustrates the process.
1. Create a project directory.
Create a directory for your project and make it your current directory.
2. Create the project.
From the command line, type dotnet new console to create a new C# console project in that directory.
3. Add the application's source code.
Open the Program.cs file in your editor and replace the auto-generated code with the following code. It
prompts the user to enter text and displays the individual words entered by the user. It uses the regular
expression \w+ to separate the words in the input text.
using System;
using System.Text.RegularExpressions;
namespace Applications.ConsoleApps
{
public class ConsoleParser
{
public static void Main()
{
Console.WriteLine("Enter any text, followed by <Enter>:\n");
String s = Console.ReadLine();
ShowWords(s);
Console.Write("\nPress any key to continue... ");
Console.ReadKey();
}
This creates a Release (rather than a Debug) version of your app. The resulting files are placed in a directory
named publish that's in a subdirectory of your project's bin directory.
Along with your application's files, the publishing process emits a program database (.pdb) file that contains
debugging information about your app. The file is useful primarily for debugging exceptions. You can choose not
to distribute it with your application's files. You should, however, save it in the event that you want to debug the
Release build of your app.
You can deploy the complete set of application files in any way you like. For example, you can package them in a
Zip file, use a simple copy command, or deploy them with any installation package of your choice. Once installed,
users can execute your application by using the dotnet command and providing the application filename, such as
dotnet fdd.dll .
In addition to the application binaries, your installer should also either bundle the shared framework installer or
check for it as a prerequisite as part of the application installation. Installation of the shared framework requires
Administrator/root access.
1. Add references to required third-party libraries to the <ItemGroup> section of your csproj file. The following
<ItemGroup> section contains a dependency on Json.NET as a third-party library:
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="10.0.2" />
</ItemGroup>
2. If you haven't already, download the NuGet package containing the third-party dependency. To download
the package, execute the dotnet restore command after adding the dependency. Because the dependency
is resolved out of the local NuGet cache at publish time, it must be available on your system.
Note that a framework-dependent deployment with third-party dependencies is only as portable as its third-party
dependencies. For example, if a third-party library only supports macOS, the app isn't portable to Windows
systems. This happens if the third-party dependency itself depends on native code. A good example of this is
Kestrel server, which requires a native dependency on libuv. When an FDD is created for an application with this
kind of third-party dependency, the published output contains a folder for each Runtime Identifier (RID) that the
native dependency supports (and that exists in its NuGet package).
namespace Applications.ConsoleApps
{
public class ConsoleParser
{
public static void Main()
{
Console.WriteLine("Enter any text, followed by <Enter>:\n");
String s = Console.ReadLine();
ShowWords(s);
Console.Write("\nPress any key to continue... ");
Console.ReadKey();
}
<PropertyGroup>
<RuntimeIdentifiers>win10-x64;osx.10.11-x64</RuntimeIdentifiers>
</PropertyGroup>
Note that the <RuntimeIdentifiers> element can appear in any <PropertyGroup> in your csproj file. A
complete sample csproj file appears later in this section.
5. Update the project's dependencies and tools.
Run the dotnet restore command to restore the dependencies specified in your project.
6. Create a Debug build of your app.
From the command line, use the dotnet build command.
7. After you've debugged and tested the program, create the files to be deployed with your app for each
platform that it targets.
Use the dotnet publish command for both target platforms as follows:
This creates a Release (rather than a Debug) version of your app for each target platform. The resulting files
are placed in a subdirectory named publish that's in a subdirectory of your project's
.\bin\Release\netcoreapp1.1<runtime_identifier> subdirectory. Note that each subdirectory contains the
complete set of files (both your app files and all .NET Core files) needed to launch your app.
Along with your application's files, the publishing process emits a program database (.pdb) file that contains
debugging information about your app. The file is useful primarily for debugging exceptions. You can choose not
to package it with your application's files. You should, however, save it in the event that you want to debug the
Release build of your app.
Deploy the published files in any way you like. For example, you can package them in a Zip file, use a simple copy
command, or deploy them with any installation package of your choice.
The following is the complete csproj file for this project.
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp1.1</TargetFramework>
<RuntimeIdentifiers>win10-x64;osx.10.11-x64</RuntimeIdentifiers>
</PropertyGroup>
</Project>
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="10.0.2" />
</ItemGroup>
2. If you haven't already, download the NuGet package containing the third-party dependency to your system.
To make the dependency available to your app, execute the dotnet restore command after adding the
dependency. Because the dependency is resolved out of the local NuGet cache at publish time, it must be
available on your system.
The following is the complete csproj file for this project:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp1.1</TargetFramework>
<RuntimeIdentifiers>win10-x64;osx.10.11-x64</RuntimeIdentifiers>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="10.0.2" />
</ItemGroup>
</Project>
When you deploy your application, any third-party dependencies used in your app are also contained with your
application files. Third-party libraries aren't required on the system on which the app is running.
Note that you can only deploy a self-contained deployment with a third-party library to platforms supported by
that library. This is similar to having third-party dependencies with native dependencies in a framework-dependent
deployment, where the native dependencies must be compatible with the platform to which the app is deployed.
See also
.NET Core Application Deployment
.NET Core Runtime IDentifier (RID) catalog
Deploying .NET Core apps with Visual Studio
7/29/2017 • 10 min to read • Edit Online
You can deploy a .NET Core application either as a framework-dependent deployment, which includes your
application binaries but depends on the presence of .NET Core on the target system, or as a self-contained
deployment, which includes both your application and .NET Core binaries. For an overview of .NET Core application
deployment, see .NET Core Application Deployment.
The following sections show how to use Microsoft Visual Studio to create the following kinds of deployments:
Framework-dependent deployment
Framework-dependent deployment with third-party dependencies
Self-contained deployment
Self-contained deployment with third-party dependencies
For information on using Visual Studio to develop .NET Core applications, see Prerequisites for .NET Core on
Windows.
Framework-dependent deployment
Deploying a framework-dependent deployment with no third-party dependencies simply involves building, testing,
and publishing the app. A simple example written in C# illustrates the process.
1. Create the project.
Select File > New > Project. In the New Project dialog, select .NET Core in the Installed project types
pane, and select the Console App (.NET Core) template in the center pane. Enter a project name, such as
"FDD", in the Name text box. Select the OK button.
2. Add the application's source code.
Open the Program.cs file in the editor and replace the auto-generated code with the following code. It
prompts the user to enter text and displays the individual words entered by the user. It uses the regular
expression \w+ to separate the words in the input text.
using System;
using System.Text.RegularExpressions;
namespace Applications.ConsoleApps
{
public class ConsoleParser
{
public static void Main()
{
Console.WriteLine("Enter any text, followed by <Enter>:\n");
String s = Console.ReadLine();
ShowWords(s);
Console.Write("\nPress any key to continue... ");
Console.ReadKey();
}
In addition to the application binaries, your installer should also either bundle the shared framework installer or
check for it as a prerequisite as part of the application installation. Installation of the shared framework requires
Administrator/root access since it is machine-wide.
namespace Applications.ConsoleApps
{
public class ConsoleParser
{
public static void Main()
{
Console.WriteLine("Enter any text, followed by <Enter>:\n");
String s = Console.ReadLine();
ShowWords(s);
Console.Write("\nPress any key to continue... ");
Console.ReadKey();
}
<PropertyGroup>
<RuntimeIdentifiers>win10-x64;osx.10.11-x64</RuntimeIdentifiers>
</PropertyGroup>
Note that the <RuntimeIdentifiers> element can go into any <PropertyGroup> that you have in your csproj file. A
complete sample csproj file appears later in this section.
1. Create a Debug build of your app.
Select Build > Build Solution. You can also compile and run the Debug build of your application by
selecting Debug > Start Debugging.
2. Publish your app.
After you've debugged and tested the program, create the files to be deployed with your app for each
platform that it targets.
To publish your app from Visual Studio, do the following:
a. Change the solution configuration from Debug to Release on the toolbar to build a Release (rather
than a Debug) version of your app.
b. Right-click on the project (not the solution) in Solution Explorer and select Publish.
c. In the Publish tab, select Publish. Visual Studio writes the files that comprise your application to the
local file system.
d. The Publish tab now shows a single profile, FolderProfile. The profile's configuration settings are
shown in the Summary section of the tab. Target Runtime identifies which runtime has been
published, and Target Location identifies where the files for the self-contained deployment were
written.
e. Visual Studio by default writes all published files to a single directory. For convenience, it's best to
create separate profiles for each target runtime and to place published files in a platform-specific
directory. This involves creating a separate publishing profile for each target platform. So now
rebuild the application for each platform by doing the following:
a. Select Create new profile in the Publish dialog.
b. In the Pick a publish target dialog, change the Choose a folder location to
bin\Release\PublishOutput\win10-x64. Select OK.
c. Select the new profile (FolderProfile1) in the list of profiles, and make sure that the Target
Runtime is win10-x64 . If it isn't, select Settings. In the Profile Settings dialog, change the
Target Runtime to win10-x64 and select Save. Otherwise, select Cancel.
d. Select Publish to publish your app for 64-bit Windows 10 platforms.
e. Follow the previous steps again to create a profile for the osx.10.11-x64 platform. The Target
Location is bin\Release\PublishOutput\osx.10.11-x64, and the Target Runtime is
osx.10.11-x64 . The name that Visual Studio assigns to this profile is FolderProfile2.
Note that each target location contains the complete set of files (both your app files and all .NET Core files)
needed to launch your app.
Along with your application's files, the publishing process emits a program database (.pdb) file that contains
debugging information about your app. The file is useful primarily for debugging exceptions. You can choose not
to package it with your application's files. You should, however, save it in the event that you want to debug the
Release build of your app.
Deploy the published files in any way you like. For example, you can package them in a Zip file, use a simple copy
command, or deploy them with any installation package of your choice.
The following is the complete csproj file for this project.
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp1.1</TargetFramework>
<RuntimeIdentifiers>win10-x64;osx.10.11-x64</RuntimeIdentifiers>
</PropertyGroup>
</Project>
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp1.1</TargetFramework>
<RuntimeIdentifiers>win10-x64;osx.10.11-x64</RuntimeIdentifiers>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="10.0.2" />
</ItemGroup>
</Project>
When you deploy your application, any third-party dependencies used in your app are also contained with your
application files. Third-party libraries aren't required on the system on which the app is running.
Note that you can only deploy a self-contained deployment with a third-party library to platforms supported by
that library. This is similar to having third-party dependencies with native dependencies in your framework-
dependent deployment, where the native dependencies won't exist on the target platform unless they were
previously installed there.
See also
.NET Core Application Deployment
.NET Core Runtime IDentifier (RID) catalog
How to Create a NuGet Package with Cross Platform
Tools
7/29/2017 • 1 min to read • Edit Online
NOTE
The following shows command-line samples using Unix. The dotnet pack command as shown here works the same way on
Windows.
For .NET Core 1.0, libraries are expected to be distributed as NuGet packages. This is in fact how all of the .NET
Standard libraries are distributed and consumed. This is most easily done with the dotnet pack command.
Imagine that you just wrote an awesome new library that you would like to distribute over NuGet. You can create a
NuGet package with cross platform tools to do exactly that! The following example assumes a library called
SuperAwesomeLibrary which targets netstandard1.0 .
If you have transitive dependencies; that is, a project which depends on another project, you'll need to make sure to
restore packages for your entire solution with the dotnet restore command before creating a NuGet package.
Failing to do so will result in the dotnet pack command to not work properly.
After ensuring packages are restored, you can navigate to the directory where a library lives:
$ cd src/SuperAwesomeLibrary
$ ls bin/Debug
netstandard1.0/
SuperAwesomeLibrary.1.0.0.nupkg
SuperAwesomeLibrary.1.0.0.symbols.nupkg
Note that this will produce a package which is capable of being debugged. If you want to build a NuGet package
with release binaries, all you need to do is add the -c / --configuration switch and use release as the argument.
$ dotnet pack --configuration release
Your /bin folder will now have a release folder containing your NuGet package with release binaries:
$ ls bin/release
netstandard1.0/
SuperAwesomeLibrary.1.0.0.nupkg
SuperAwesomeLibrary.1.0.0.symbols.nupkg
And now you have the necessary files to publish a NuGet package!
Don't confuse dotnet pack with dotnet publish
It is important to note that at no point is the dotnet publish command involved. The dotnet publish command is
for deploying applications with all of their dependencies in the same bundle - not for generating a NuGet package
to be distributed and consumed via NuGet.
Runtime package store
8/16/2017 • 5 min to read • Edit Online
Starting with .NET Core 2.0, it's possible to package and deploy apps against a known set of packages that exist in
the target environment. The benefits are faster deployments, lower disk space use, and improved startup
performance in some cases.
This feature is implemented as a runtime package store, which is a directory on disk where packages are stored
(typically at /usr/local/share/dotnet/store on macOS/Linux and C:/Program Files/dotnet/store on Windows). Under
this directory, there are subdirectories for architectures and target frameworks. The file layout is similar to the way
that NuGet assets are laid out on disk:
\dotnet
\store
\x64
\net47
\microsoft.applicationinsights
\microsoft.aspnetcore
...
\netcoreapp2.0
\microsoft.applicationinsights
\microsoft.aspnetcore
...
\x86
\net47
\microsoft.applicationinsights
\microsoft.aspnetcore
...
\netcoreapp2.0
\microsoft.applicationinsights
\microsoft.aspnetcore
...
A target manifest file lists the packages in the runtime package store. Developers can target this manifest when
publishing their app. The target manifest is typically provided by the owner of the targeted production
environment.
<Project Sdk="Microsoft.NET.Sdk">
<ItemGroup>
<PackageReference Include="<NUGET_PACKAGE>" Version="<VERSION>" />
<!-- Include additional packages here -->
</ItemGroup>
</Project>
Example
The following example package store manifest (packages.csproj) is used to add Newtonsoft.Json and Moq to a
runtime package store:
<Project Sdk="Microsoft.NET.Sdk">
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="10.0.3" />
<PackageReference Include="Moq" Version="4.7.63" />
</ItemGroup>
</Project>
Provision the runtime package store by executing dotnet store with the package store manifest, runtime, and
framework:
Example
You can pass multiple target package store manifest paths to a single dotnet store command by repeating the
option and path in the command.
By default, the output of the command is a package store under the .dotnet/store subdirectory of the user's profile.
You can specify a different location using the --output <OUTPUT_DIRECTORY> option. The root directory of the store
contains a target manifest artifact.xml file. This file can be made available for download and be used by app
authors who want to target this store when publishing.
Example
The following artifact.xml file is produced after running the previous example. Note that Castle.Core is a
dependency of Moq , so it's included automatically and appears in the artifacts.xml manifest file.
<StoreArtifacts>
<Package Id="newtonsoft.json" Version="10.0.3" />
<Package Id="castle.core" Version="4.1.0" />
<Package Id="moq" Version="4.7.63" />
</StoreArtifacts>
Example
You deploy the resulting published app to an environment that has the packages described in the target manifest.
Failing to do so results in the app failing to start.
Specify multiple target manifests when publishing an app by repeating the option and path (for example,
--manifest manifest1.xml --manifest manifest2.xml ). When you do so, the app is trimmed for the union of
packages specified in the target manifest files provided to the command.
<PropertyGroup>
<TargetManifestFiles>manifest1.xml;manifest2.xml</TargetManifestFiles>
</PropertyGroup>
Specify the target manifests in the project file only when the target environment for the app is well-known, such as
for .NET Core projects. This isn't the case for open-source projects. The users of an open-source project typically
deploy it to different production environments. These production environments generally have different sets of
packages pre-installed. You can't make assumptions about the target manifest in such environments, so you
should use the --manifest option of dotnet publish .
<PropertyGroup>
<PublishWithAspNetCoreTargetManifest>false</PublishWithAspNetCoreTargetManifest>
</PropertyGroup>
NOTE
For self-contained deployment (SCD) apps, it's assumed that the target system doesn't necessarily contain the required
manifest packages. Therefore, <PublishWithAspNetCoreTargetManifest> cannot be set to true for an SCD app.
If you deploy an application with a manifest dependency that's present in the deployment (the assembly is present
in the bin folder), the runtime package store isn't used on the host for that assembly. The bin folder assembly is
used regardless of its presence in the runtime package store on the host.
The version of the dependency indicated in the manifest must match the version of the dependency in the runtime
package store. If you have a version mismatch between the dependency in the target manifest and the version that
exists in the runtime package store and the app doesn't include the required version of the package in its
deployment, the app fails to start. The exception includes the name of the target manifest that called for the
runtime package store assembly, which helps you troubleshoot the mismatch.
When the deployment is trimmed on publish, only the specific versions of the manifest packages you indicate are
withheld from the published output. The packages at the versions indicated must be present on the host for the
app to start.
See also
dotnet-publish
dotnet-store
Docker and .NET Core
7/29/2017 • 1 min to read • Edit Online
The following tutorials are available for learning about using Docker with .NET Core.
Building Docker Images for .NET Core Applications
Visual Studio Tools for Docker
For tutorials about developing ASP.NET Core web applications, see the ASP.NET Core documentation.
Building Docker Images for .NET Core Applications
8/5/2017 • 9 min to read • Edit Online
In order to get an understanding of how to use .NET Core and Docker together, we must first get to know the
different Docker images that are offered and when is the right use case for them. Here we will walk through the
variations offered, build an ASP.NET Core Web API, use the Yeoman Docker tools to create a debuggable container
as well as peek at how Visual Studio Code can assist in the process.
Alternative images
In addition to the optimized scenarios of development, build and production, we provide additional images:
microsoft/dotnet:<version>-onbuild : that is microsoft/dotnet:1.0.0-preview2-onbuild, contains
ONBUILD triggers. The build will COPY your application, run dotnet restore and create an ENTRYPOINT
dotnet run instruction to run the application when the Docker image is run. While not an optimized image
for production, some may find it useful to simply copy their source code into an image and run it.
microsoft/dotnet:<version>-core-deps : that is microsoft/dotnet:1.0.0-core-deps, if you wish to run self-
contained applications use this image. It contains the operating system with all of the native dependencies
needed by .NET Core. This image can also be used as a base image for your own custom CoreFX or CoreCLR
builds. While the onbuild variant is optimized to simply place your code in an image and run it, this image
is optimized to have only the operating system dependencies required to run .NET Core apps that have the
.NET runtime packaged with the application. This image isn't generally optimized for running multiple .NET
Core containers on the same host, as each image carries the .NET Core runtime within the application, and
you will not benefit from image layering.
Latest versions of each variant:
microsoft/dotnet or microsoft/dotnet:latest (includes SDK)
microsoft/dotnet:onbuild
microsoft/dotnet:core
microsoft/dotnet:core-deps
Here is a list of the images after a docker pull <imagename> on a development machine to show the various sizes.
Notice, the development/build variant, microsoft/dotnet:1.0.0-preview2-sdk is larger as it contains the SDK to
develop and build your application. The production variant, microsoft/dotnet:core is smaller, as it only contains
the .NET Core runtime. The minimal image capable of being used on Linux, core-deps , is quite smaller, however
your application will need to copy a private copy of the .NET runtime with it. Since containers are already private
isolation barriers, you will lose that optimization when running multiple dotnet based containers.
Prerequisites
To build and run, you'll need a few things installed:
.NET Core
Docker to run your Docker containers locally
Node.js
Yeoman generator for ASP.NET for creating the Web API application
Yeoman generator for Docker from Microsoft
Install the Yeoman generators for ASP.NET Core and Docker using npm
npm install -g yo generator-aspnet generator-docker
NOTE
This sample will be using Visual Studio Code for the editor.
yo aspnet
Select Web API Application and type api for the name of the app and tap enter. Once the application is
scaffolded, change to the /api directory and restore the NuGet dependencies using dotnet restore .
cd api
dotnet restore
[
"value1",
"value2"
]
_-----_ ╭ ──────────────────────────╮
| | │ Welcome to the Docker │
|--(o)--| │ generator! │
`---------´ │ Let's add Docker │
( _´U`_ ) │ container magic to your │
/___A___\ /│ app! │
| ~ | ╰ ──────────────────────────╯
__'.___.'__
´ ` |° ´ Y `
When the generator is complete, the following files are added to the project
.vscode/launch.json
Dockerfile.debug
Dockerfile
docker-compose.debug.yml
docker-compose.yml
dockerTask.ps1
dockerTask.sh
.vscode/tasks.json
The generator creates two Dockerfiles.
Dockerfile.debug - this file is based on the microsoft/dotnet:1.0.0-preview2-sdk image which if you note from
the list of image variants, includes the SDK, CLI and .NET Core and will be the image used for development and
debugging (F5). Including all of these components produces a larger image with a size roughly of 540MB.
Dockerfile - this image is the release image based on microsoft/dotnet:1.0.0-core and should be used for
production. This image when built is approximately 253 MB.
Creating the Docker images
Using the dockerTask.sh or dockerTask.ps1 script, we can build or compose the image and container for the api
application for a specific environment. Build the debug image by running the following command.
The image will build the ASP.NET application, run dotnet restore , add the debugger to the image, set an
ENTRYPOINT and finally copy the app to the image. The result is a Docker image named api with a TAG of debug.
See the images on the machine using docker images .
docker images
Another way to generate the image and run the application within the Docker container is to open the application
in Visual Studio Code and use the debugging tools.
Select the debugging icon in the View Bar on the left side of Visual Studio Code.
Then tap the play icon or F5 to generate the image and start the application within the container. The Web API will
be launched using your default web browser at http://localhost:5000.
You may set break points in your application, step through, etc. just as if the application was running locally on
your development machine as opposed to inside the container. The benefit to debugging within the container is
this is the same image that would be deployed to a production environment.
Creating the release or production image requires simply running the command from the terminal passing the
release environment name.
The command creates the image based on the smaller microsoft/dotnet:core base image, EXPOSE port 5000,
sets the ENTRYPOINT for dotnet api.dll and copies it to the /app directory. There is no debugger, SDK or
dotnet restore resulting in a much smaller image. The image is named api with a TAG of latest.
Microsoft Visual Studio 2017 with Docker for Windows supports building, debugging, and running .NET
Framework and .NET Core web and console applications using Windows and Linux containers.
Prerequisites
Microsoft Visual Studio 2017 with .NET Core workload
Docker for Windows
When you add Docker support to your project, you can choose either Windows or Linux containers. (The Docker
host must be running the same container type. If you need change the container type in the running Docker
instance, right click the Docker icon in the System Tray, and choose Switch to Windows containers or Switch to
Linux containers.)
The following files are added to the project.
Dockerfile: the Docker file for ASP.NET Core applications is based on the microsoft/aspnetcore image. This
image includes the ASP.NET Core NuGet packages, which have been pre-jitted improving startup performance.
When building .NET Core Console Applications, the Dockerfile FROM will reference the most recent
microsoft/dotnet image.
docker-compose.yml: base Docker Compose file used to define the collection of images to be built and run
with docker-compose build/run.
docker-compose.dev.debug.yml: additional docker-compose file with for iterative changes when your
configuration is set to debug. Visual Studio will call -f docker-compose.yml -f docker-compose.dev.debug.yml to
merge these together. This compose file is used by Visual Studio development tools.
docker-compose.dev.release.yml: additional Docker Compose file to debug your release definition. It will
volume mount the debugger so it doesn't change the contents of the production image.
The docker-compose.yml file contains the name of the image that is created when project is run.
version '2'
services:
hellodockertools:
image: user/hellodockertools${TAG}
build:
context: .
dockerfile: Dockerfile
ports:
- "80"
In this example, image: user/hellodockertools${TAG} generates the image user/hellodockertools:dev when the
application is run in Debug mode and user/hellodockertools:latest in Release mode respectively.
You will want to change the user to your Docker Hub username if you plan to push the image to the registry. For
example, spboyer/hellodockertools , or change to your private registry url privateregistry.domain.com/ depending
on your configuration.
Debugging
Select Docker from the debug dropdown in the toolbar and use F5 to start debugging the application.
The microsoft/aspnetcore image is acquired (if not already in your cache)
ASPNETCORE_ENVIRONMENT is set to Development within the container
PORT 80 is EXPOSED and mapped to a dynamically assigned port for localhost. The port is determined by the
docker host and can be queried with docker ps.
Your application is copied to the container
Default browser is launched with the debugger attached to the container, using the dynamically assigned port.
The resulting Docker image built is the dev image of your application with the microsoft/aspnetcore images as
the base image. Note: the dev image is empty of your app contents as Debug confgurations use volume mounting
to provide the iterative experience. To push an image, use the Release configuration.
The application is running using the container which you can see by running the docker ps command.
There may be an expectation for the production or release image to be smaller in size by comparison to the dev
image, however through the use of the volume mapping; the debugger and application were actually being run
from your local machine and not within the container. The latest image has packaged the entire application code
needed to run the application on a host machine, therefore the delta is the size of your application code.
Unit Testing in .NET Core
7/29/2017 • 1 min to read • Edit Online
.NET Core has been designed with testability in mind, so that creating unit tests for your applications is easier than
ever before. This article briefly introduces unit tests (and how they differ from other kinds of tests). Linked
resources demonstrates how to add a test project to your solution and then run unit tests using either the
command line or Visual Studio.
NOTE
Developers often struggle with coming up with good names for their test classes and methods. As a starting point, the
ASP.NET product team follows these conventions.
When writing unit tests, be careful you don’t accidentally introduce dependencies on infrastructure. These tend to
make tests slower and more brittle, and thus should be reserved for integration tests. You can avoid these hidden
dependencies in your application code by following the Explicit Dependencies Principle and using Dependency
Injection to request your dependencies from the framework. You can also keep your unit tests in a separate project
from your integration tests, and ensure your unit test project doesn’t have references to or dependencies on
infrastructure packages.
Learn more about unit testing in .NET Core projects:
Try this walkthrough creating unit tests with xUnit and the .NET Core CLI.
The XUnit team has written a tutorial that shows how to use xUnit with .NET Core and Visual Studio.
If you prefer using MSTest, try the walkthrough creating unit tests with MSTest and the .NET Core CLI.
For a additional information and examples on how to use selective unit test filtering, see Running selective unit
tests.
Unit testing in .NET Core using dotnet test and xUnit
8/18/2017 • 4 min to read • Edit Online
This tutorial takes you through an interactive experience building a sample solution step-by-step to learn unit
testing concepts. If you prefer to follow the tutorial using a pre-built solution, view or download the sample code
before you begin. For download instructions, see Samples and Tutorials.
/unit-testing-using-dotnet-test
/PrimeService
Make PrimeService the current directory and run dotnet new classlib to create the source project. Rename
Class1.cs to PrimeService.cs. To use test-driven development (TDD), you'll create a failing implementation of the
PrimeService class:
using System;
namespace Prime.Services
{
public class PrimeService
{
public bool IsPrime(int candidate)
{
throw new NotImplementedException("Please create a test first");
}
}
}
/unit-testing-using-dotnet-test
/PrimeService
Source Files
PrimeService.csproj
/PrimeService.Tests
Make the PrimeService.Tests directory the current directory and create a new project using dotnet new xunit . This
creates a test project that uses xUnit as the test library. The generated template configures the test runner in the
PrimeServiceTests.csproj:
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.0.0" />
<PackageReference Include="xunit" Version="2.2.0" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.2.0" />
</ItemGroup>
The test project requires other packages to create and run unit tests. dotnet new in the previous step added xUnit
and the xUnit runner. Now, add the PrimeService class library as another dependency to the project. Use the
dotnet add reference command:
Another option is to edit the PrimeService.Tests.csproj file. Directly under the first <ItemGroup> node, add another
<ItemGroup> node with a reference to the library project:
<ItemGroup>
<ProjectReference Include="..\PrimeService\PrimeService.csproj" />
</ItemGroup>
You can see the entire file in the samples repository on GitHub.
The final solution layout is shown below:
/unit-testing-using-mstest
/PrimeService
Source Files
PrimeService.csproj
/PrimeService.Tests
PrimeService
PrimeServiceTests.csproj
namespace Prime.UnitTests.Services
{
public class PrimeService_IsPrimeShould
{
private readonly PrimeService _primeService;
public PrimeService_IsPrimeShould()
{
_primeService = new PrimeService();
}
[Fact]
public void ReturnFalseGivenValueOf1()
{
var result = _primeService.IsPrime(1);
The [Fact] attribute denotes a method as a single test. Execute dotnet test to build the tests and the class
library and then run the tests. The xUnit test runner contains the program entry point to run your tests.
dotnet test starts the test runner and provides a command-line argument to the test runner indicating the
assembly that contains your tests.
Your test fails. You haven't created the implementation yet. Write the simplest code in the PrimeService class to
make this test pass:
In the PrimeService.Tests directory, run dotnet test again. The dotnet test command runs a build for the
PrimeService project and then for the PrimeService.Tests project. After building both projects, it runs this single
test. It passes.
Run dotnet test , and two of these tests fail. To make all of the tests pass, change the if clause at the beginning
of the method:
if (candidate < 2)
Continue to iterate by adding more tests, more theories, and more code in the main library. You'll end up with the
finished version of the tests and the complete implementation of the library.
You've built a small library and a set of unit tests for that library. You've structured the solution so that adding new
packages and tests is seamless, and you can concentrate most of your time and effort on solving the goals of the
applicaiton.
Unit testing with MSTest and .NET Core
7/29/2017 • 4 min to read • Edit Online
This tutorial takes you through an interactive experience building a sample solution step-by-step to learn unit
testing concepts. If you prefer to follow the tutorial using a pre-built solution, view or download the sample code
before you begin. For download instructions, see Samples and Tutorials.
Creating the source project
Open a shell window. Create a directory called unit-testing-using-dotnet-test to hold the solution. Inside this new
directory, create a PrimeService directory. The directory structure thus far is shown below:
/unit-testing-using-mstest
/PrimeService
Make PrimeService the current directory and run dotnet new classlib to create the source project. Rename
Class1.cs to PrimeService.cs. To use test-driven development (TDD), you'll create a failing implementation of the
PrimeService class:
using System;
namespace Prime.Services
{
public class PrimeService
{
public bool IsPrime(int candidate)
{
throw new NotImplementedException("Please create a test first");
}
}
}
/unit-testing-using-mstest
/PrimeService
Source Files
PrimeService.csproj
/PrimeService.Tests
Make the PrimeService.Tests directory the current directory and create a new project using dotnet new mstest . This
creates a test project that uses MStest as the test library. The generated template configures the test runner in the
PrimeServiceTests.csproj file:
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.0.0" />
<PackageReference Include="MSTest.TestAdapter" Version="1.1.11" />
<PackageReference Include="MSTest.TestFramework" Version="1.1.11" />
</ItemGroup>
The test project requires other packages to create and run unit tests. dotnet new in the previous step added the
MSTest SDK, the MSTest test framework, and the MSTest runner. Now, add the PrimeService class library as
another dependency to the project. Use the dotnet add reference command:
Another option is to edit the PrimeService.Tests.csproj file. Directly under the first <ItemGroup> node, add another
<ItemGroup> node with a reference to the library project:
<ItemGroup>
<ProjectReference Include="..\PrimeService\PrimeService.csproj" />
</ItemGroup>
You can see the entire file in the samples repository on GitHub.
The final solution layout is shown below:
/unit-testing-using-mstest
/PrimeService
Source Files
PrimeService.csproj
/PrimeService.Tests
PrimeService
PrimeServiceTests.csproj
namespace Prime.UnitTests.Services
{
[TestClass]
public class PrimeService_IsPrimeShould
{
private readonly PrimeService _primeService;
public PrimeService_IsPrimeShould()
{
_primeService = new PrimeService();
}
[TestMethod]
public void ReturnFalseGivenValueOf1()
{
var result = _primeService.IsPrime(1);
The [TestClass] attribute denotes a class that contains unit tests. The [TestMethod] attribute denotes a method as
a single test.
Save this file and execute dotnet test to build the tests and the class library and then run the tests. The MSTest
test runner contains the program entry point to run your tests. dotnet test starts the test runner and provides a
command-line argument to the test runner indicating the assembly that contains your tests.
Your test fails. You haven't created the implementation yet. Write the simplest code in the PrimeService class to
make this test pass:
In the PrimeService.Tests directory, run dotnet test again. The dotnet test command runs a build for the
PrimeService project and then for the PrimeService.Tests project. After building both projects, it runs this single
test. It passes.
Instead of creating new tests, leverage these two attributes to create a single data test method that tests several
values less than two, which is the lowest prime number:
[DataTestMethod]
[DataRow(-1)]
[DataRow(0)]
[DataRow(1)]
public void ReturnFalseGivenValuesLessThan2(int value)
{
var result = _primeService.IsPrime(value);
Run dotnet test , and two of these tests fail. To make all of the tests pass, change the if clause at the beginning
of the method:
if (candidate < 2)
Continue to iterate by adding more tests, more theories, and more code in the main library. You'll end up with the
finished version of the tests and the complete implementation of the library.
You've built a small library and a set of unit tests for that library. You've structured the solution so that adding new
packages and tests is seamless, and you can concentrate most of your time and effort on solving the goals of the
applicaiton.
Running selective unit tests
7/29/2017 • 1 min to read • Edit Online
The following examples use dotnet test . If you're using vstest.console.exe , replace --filter with
--testcasefilter: .
MSTest
namespace MSTestNamespace
{
using Microsoft.VisualStudio.TestTools.UnitTesting;
[TestClass]
public class UnitTestClass1
{
[Priority(2)]
[TestMethod]
public void TestMethod1()
{
}
[TestCategory("CategoryA")]
[Priority(3)]
[TestMethod]
public void TestMethod2()
{
}
}
}
EXPRESSION RESULT
dotnet test --filter Method Runs tests whose FullyQualifiedName contains Method .
Available in vstest 15.1+ .
dotnet test --filter Name~TestMethod1 Runs tests whose name contains TestMethod1 .
dotnet test --filter TestCategory=CategoryA Runs tests which are annotated with
[TestCategory("CategoryA")] .
dotnet test --filter Priority=3 Runs tests which are annotated with [Priority(3)] .
Note: Priority~3 is an invalid value, as it isn't a string.
dotnet test --filter " Runs tests which have either FullyQualifiedName
(FullyQualifiedName~UnitTestClass1&TestCategory=CategoryA)|Priority=1"
containing UnitTestClass1 and TestCategory is
CategoryA or Priority is 1.
xUnit
namespace XUnitNamespace
{
public class TestClass1
{
[Trait("Category", "bvt")]
[Trait("Priority", "1")]
[Fact]
public void foo()
{
}
[Trait("Category", "Nightly")]
[Trait("Priority", "2")]
[Fact]
public void bar()
{
}
}
}
EXPRESSION RESULT
dotnet test --filter DisplayName~TestClass1 Runs tests whose display name contains TestClass1 .
In the code example, the defined traits with keys Category and Priority can be used for filtering.
EXPRESSION RESULT
dotnet test --filter XUnit Runs tests whose FullyQualifiedName contains XUnit .
Available in vstest 15.1+ .
dotnet test --filter Category=bvt Runs tests which have [Trait("Category", "bvt")] .
dotnet test --filter " Runs tests which have either FullyQualifiedName
(FullyQualifiedName~TestClass1&Category=Nightly)|Priority=1"
containing TestClass1 and Category is CategoryA or
Priority is 1.
.NET Core versioning
8/29/2017 • 11 min to read • Edit Online
.NET Core is made of NuGet packages, tools, and frameworks that are distributed as a unit. Each of these platform
layers can be versioned separately, enabling better agility. While there is significant versioning flexibility in that
regard, there's also a desire to version the platform as a unit to make the product easier to understand.
This article aims at clarifying how the .NET Core SDK and runtime are versioned.
There are lots of moving parts that version independently in .NET Core. However, starting with .NET Core 2.0, there
is an easy to understand top-level version number that everybody understands to be the version of ".NET Core" as
a whole. The rest of this document goes into the details of the versioning of all those parts. These details can be
important if you're a package manager, for example.
Versioning details
Starting with .NET Core 2.0, downloads show a single version number in their file name. The following version
numbers were unified:
The shared framework and associated runtime.
The .NET Core SDK and associated .NET Core CLI.
The Microsoft.NETCore.App metapackage.
The use of a single version number makes it easier for users to know what version of the SDK to install on their
dev machines, and what the corresponding version of the shared framework should be when time comes to
provision a production environment. When downloading an SDK or runtime, the version number you see is going
to be the same.
Installers
Starting with .NET Core 2.0, downloads for our daily builds and our releases adhere to a new naming scheme that
is easier to understand. The installer UI in those downloads were also modified to clearly present the names and
versions of the components being installed. In particular, titles now show the same version number that is in the
download's file name.
File name format
[product]-[component]-[major].[minor].[patch]-[previewN]-[optional build #]-[rid].[file ext]
The format is readable and clearly shows what you're downloading, what version it is, and where you can use it.
The runtime package name includes runtime , and the SDK includes SDK .
UI string format
All web site descriptions and UI strings in the installers are kept consistent, accurate, and simple. The following
table shows some examples:
SDK .NET Core 2.0 SDK (x64) .NET Core 2.0.4 SDK .NET Core 2.0.4 Tools + .NET
Installer Core 2.0.4 Runtime
Runtime .NET Core 2.0 Runtime (x64) .NET Core 2.0.4 Runtime .NET Core 2.0.4 Runtime
Installer
SDK .NET Core 2.0 Preview 1 SDK .NET Core 2.0.0 Preview 1 .NET Core 2.0.0 Preview 1
(x64) Installer SDK Tools + .NET Core 2.0.0
Preview 1 Runtime
Runtime .NET Core 2.0 Preview 1 .NET Core 2.0.0 Preview 1 .NET Core 2.0.0 Preview 1
Runtime (x64) Installer Runtime Runtime
It may happen that an SDK release contains more than one version of the runtime. When that happens, the
installer UX looks like the following (only the SDK version is shown and the installed Runtime versions are shown
on a summary page at the end of the installation process on Windows and Mac):
SDK .NET Core 2.1 SDK (x64) .NET Core 2.1.1 SDK .NET Core 2.1.1 Tools + .NET
Installer .NET Core 2.1.1 Runtime Core 2.1.1 Runtime + .NET
.NET Core 2.0.6 Runtime Core 2.0.6 Runtime
It's also possible that .NET Core Tools need to be updated, without runtime changes. In that case, the SDK version
is increased (for example, to 2.1.2) and then the Runtime catches up the next time it ships (for example, both the
Runtime and SDK ship the next time as 2.1.3).
Package managers
.NET Core can be distributed by other entities than Microsoft. In particular, Linux distribution owners and package
maintainers may add .NET Core packages to their package managers. For recommendations on how those
packages should be named and versioned, see .NET Core distribution packaging.
Minimum package set
dotnet-runtime-[major].[minor]: a runtime with the specified version (only the latest patch version for a
given major+minor combination should be available in the package manager). New patch versions update
the package, but new minor or major versions are separate packages.
Dependencies: dotnet-host
dotnet-sdk : the latest SDK. update rolls forward major, minor, and patch versions.
Dependencies: the latest dotnet-sdk-[major].[minor] .
dotnet-sdk-[major].[minor] : the SDK with the specified version. The version specified is the highest
included version of included shared frameworks, so that users can easily relate an SDK to a shared
framework. New patch versions update the package, but new minor or major versions are separate
packages.
Dependencies: dotnet-host , one or more dotnet-runtime-[major].[minor] (one of those is used by the
SDK code itself, the others are here for users to build and run against).
dotnet-host : the latest host.
P r e v i e w v e r si o n s
Package maintainers may decide to include preview versions of the runtime and SDK. Don't include those preview
versions in the unversioned dotnet-sdk package, but you can release them as versioned packages with an
additional preview marker appended to the major and minor version sections of the name. For example, there may
be a dotnet-sdk-2.0-preview1-final package.
Docker
A general Docker tag naming convention is to place the version number before the component name. This
convention may continue to be utilized. The current tags include only the Runtime version as follows.
1.0.8-runtime
1.0.8-sdk
2.0.4-runtime
2.0.4-sdk
2.1.1-runtime
2.1.1-sdk
The SDK tags should be updated to represent the SDK version rather than Runtime.
It's also possible that we need to fix the .NET Core Tools but reship an existing runtime. In that case, the SDK
version is increased (for example, to 2.1.2) and then the Runtime catches up the next time it ships (for example,
both the Runtime and SDK ship the following time as 2.1.3).
Semantic Versioning
.NET Core uses Semantic Versioning (SemVer), adopting the use of MAJOR.MINOR.PATCH versioning, using the
various parts of the version number to describe the degree and type of change.
MAJOR.MINOR.PATCH[-PRERELEASE-BUILDNUMBER]
The optional PRERELEASE and BUILDNUMBER parts will never be part of supported releases, and only exist on nightly
builds, locally built from source targets, and unsupported preview releases.
How version numbers are incremented?
MAJOR is incremented when:
Servicing versions
After a release goes out, the release branches generally stop producing daily builds and instead start producing
servicing builds. Servicing versions have a -servicing-[number] appended to the version. For example,
2.0.1-servicing-006924 .
Versioning in practice
When you download .NET Core, the name of the file you download carries the version, for example,
dotnet-sdk-2.0.4-win10-x64.exe .
There are commits and pull requests on .NET Core repos on GitHub on a daily basis, resulting in new builds of
many libraries. It isn't practical to create new public versions of .NET Core for every change. Instead, changes are
aggregated over an undetermined period of time (for example, weeks or months) before making a new public
stable .NET Core version.
A new version of .NET Core could mean several things:
New versions of packages and metapackages.
New versions of various frameworks, assuming the addition of new APIs.
New version of the .NET Core distribution.
Shipping a patch release
After shipping a major release of .NET Core, such as version 2.0.0, patch-level changes are made to .NET Core
libraries to fix bugs and improve performance and reliability. That means that no new APIs are introduced. The
various metapackages are updated to reference the updated .NET Core library packages. The metapackages are
versioned as patch updates ( MAJOR.MINOR.PATCH ). Target frameworks are never updated as part of patch releases. A
new .NET Core distribution is released with a version number that matches that of the Microsoft.NETCore.App
metapackage.
Shipping a minor release
After shipping a .NET Core version with an incremented MAJOR version number, new APIs are added to .NET Core
libraries to enable new scenarios. The various metapackages are updated to reference the updated .NET Core
library packages. The metapackages are versioned as patch updates with MAJOR and MINOR version numbers
matching the new framework version. New target framework names with the new MAJOR.MINOR version are added
to describe the new APIs (for example, netcoreapp2.1 ). A new .NET Core distribution is released with a matching
version number to the Microsoft.NETCore.App metapackage.
Shipping a major release
Every time a new major version of .NET Core ships, the MAJOR version number gets incremented, and the MINOR
version number gets reset to zero. The new major version contains at least all the APIs that were added by minor
releases after the previous major version. A new major version should enable important new scenarios, and it may
also drop support for an older platform.
The various metapackages are updated to reference the updated .NET Core library packages. The
Microsoft.NETCore.App metapackage and the netcore target framework are versioned as a major update
matching the MAJOR version number of the new release.
See also
Target frameworks
.NET Core distribution packaging
.NET Core Support Lifecycle Fact Sheet
.NET Core 2+ Version Binding
.NET Core Support
7/29/2017 • 1 min to read • Edit Online
Versioning
New LTS releases are marked by an increase in the Major version number. Current releases have the same Major
number as the corresponding LTS train and are marked by an increase in the Minor version number. For example,
1.0.3 would be LTS and 1.1.0 would be Current. Bug fix updates to either train increment the Patch version. For
more information on the versioning scheme, see .NET Core Versioning.
The RID graph is defined in a package called Microsoft.NETCore.Platforms in a file called runtime.json , which
you can see on the CoreFX repo. If you use this file, you will notice that some of the RIDs have an "#import"
statement in them. These statements are compatibility statements. That means that a RID that has an imported
RID in it can be a target for restoring packages for that RID. Slightly confusing, but let's look at an example. Let's
take a look at macOS:
"osx.10.11-x64": {
"#import": [ "osx.10.11", "osx.10.10-x64" ]
}
The above RID specifies that osx.10.11-x64 imports osx.10.10-x64 . This means that when restoring packages,
NuGet will be able to restore packages that specify that they need osx.10.10-x64 on osx.10.11-x64 .
A slightly bigger example RID graph:
win10-arm
win10
win81-arm
win81
win8-arm
win8
win7
win
any
All RIDs eventually map back to the root any RID.
Although they look easy enough to use, there are some special things about RIDs that you have to keep in mind
when working with them:
They are opaque strings and should be treated as black boxes
You should not construct RIDs programmatically
You need to use the RIDs that are already defined for the platform and this document shows that
The RIDs do need to be specific so don't assume anything from the actual RID value; please consult this
document to determine which RID(s) you need for a given platform
Using RIDs
In order to use RIDs, you have to know which RIDs there are. New RIDs are added regularly to the platform. For
the latest version, please check the runtime.json file on CoreFX repo.
NOTE
We are working towards getting this information into a more interactive form. When that happens, this page will be
updated to point to that tool and/or its usage documentation.
Windows RIDs
Windows 7 / Windows Server 2008 R2
win7-x64
win7-x86
Windows 8 / Windows Server 2012
win8-x64
win8-x86
win8-arm
Windows 8.1 / Windows Server 2012 R2
win81-x64
win81-x86
win81-arm
Windows 10 / Windows Server 2016
win10-x64
win10-x86
win10-arm
win10-arm64
Linux RIDs
Red Hat Enterprise Linux
rhel.7-x64
Ubuntu
ubuntu.14.04-x64
ubuntu.14.10-x64
ubuntu.15.04-x64
ubuntu.15.10-x64
ubuntu.16.04-x64
ubuntu.16.10-x64
CentOS
centos.7-x64
Debian
debian.8-x64
Fedora
fedora.23-x64
fedora.24-x64
OpenSUSE
opensuse.13.2-x64
opensuse.42.1-x64
Oracle Linux
ol.7-x64
ol.7.0-x64
ol.7.1-x64
ol.7.2-x64
Currently supported Ubuntu derivatives
linuxmint.17-x64
linuxmint.17.1-x64
linuxmint.17.2-x64
linuxmint.17.3-x64
linuxmint.18-x64
OS X RIDs
osx.10.10-x64
osx.10.11-x64
osx.10.12-x64
.NET Core SDK Overview
7/29/2017 • 1 min to read • Edit Online
Introduction
.NET Core Software Development Kit (SDK) is a set of libraries and tools that allow developers to create .NET Core
applications and libraries. This is the package that developers will most likely acquire.
It contains the following components:
1. The .NET Core Command Line Tools that are used to build applications
2. .NET Core (libraries and runtime) that allow applications to both be built and run
3. The dotnet driver for running the CLI commands as well as running applications
The .NET Core command-line interface (CLI) is a new cross-platform toolchain for developing .NET applications.
The CLI is a foundation upon which higher-level tools, such as Integrated Development Environments (IDEs),
editors, and build orchestrators, can rest.
Installation
Either use the native installers or use the installation shell scripts:
The native installers are primarily used on developer's machines and use each supported platform's native
install mechanism, for instance, DEB packages on Ubuntu or MSI bundles on Windows. These installers install
and configure the environment for immediate use by the developer but require administrative privileges on
the machine. You can view the installation instructions in the .NET Core installation guide.
Shell scripts are primarily used for setting up build servers or when you wish to install the tools without
administrative privileges. Install scripts don't install prerequisites on the machine, which must be installed
manually. For more information, see the install script reference topic. For information on how to set up CLI
on your continuous integration (CI) build server, see Using .NET Core SDK and tools in Continuous
Integration (CI).
By default, the CLI installs in a side-by-side (SxS) manner, so multiple versions of the CLI tools can coexist on a
single machine. Determining which version is used on a machine where multiple versions are installed is
explained in more detail in the Driver section.
CLI commands
The following commands are installed by default:
.NET Core 2.x
.NET Core 1.x
Basic commands
new
restore
build
publish
run
test
vstest
pack
migrate
clean
sln
help
store
Project modification commands
add package
add reference
remove package
remove reference
list reference
Advanced commands
nuget delete
nuget locals
nuget push
msbuild
dotnet install script
The CLI adopts an extensibility model that allows you to specify additional tools for your projects. For more
information, see the .NET Core CLI extensibility model topic.
Command structure
CLI command structure consists of the the driver ("dotnet"), the command (or "verb"), and possibly command
arguments and options. You see this pattern in most CLI operations, such as creating a new console app and
running it from the command line as the following commands show when executed from a directory named
my_app:
.NET Core 2.x
.NET Core 1.x
Driver
The driver is named dotnet and has two responsibilities, either running a framework-dependent app or
executing a command. The only time dotnet is used without a command is when it's used to start an
application.
To run a framework-dependent app, specify the app after the driver, for example, dotnet /path/to/my_app.dll .
When executing the command from the folder where the app's DLL resides, simply execute dotnet my_app.dll .
When you supply a command to the driver, dotnet.exe starts the CLI command execution process. First, the
driver determines the version of the SDK to use. If the version isn't specified in the command options, the driver
uses the latest version available. To specify a version other than the latest installed version, use the
--fx-version <VERSION> option (see the dotnet command reference). Once the SDK version is determined, the
driver executes the command.
Command ("verb")
The command (or "verb") is simply a command that performs an action. For example, dotnet build builds your
code. dotnet publish publishes your code. The commands are implemented as a console application using a
dotnet {verb} convention.
Arguments
The arguments you pass on the command line are the arguments to the command invoked. For example when
you execute dotnet publish my_app.csproj , the my_app.csproj argument indicates the project to publish and is
passed to the publish command.
Options
The options you pass on the command line are the options to the command invoked. For example when you
execute dotnet publish --output /build_output , the --output option and its value are passed to the publish
command.
See also
dotnet/CLI GitHub Repository
.NET Core installation guide
.NET Core CLI Tools telemetry
8/14/2017 • 3 min to read • Edit Online
The .NET Core SDK includes a telemetry feature that collects usage information. It's important that the .NET Team
understands how the tools are used so that we can improve them. For more information, see What we've learned
from .NET Core SDK Telemetry.
The collected data is anonymous and published in an aggregated form for use by both Microsoft and the
community under the Creative Commons Attribution License.
Scope
The dotnet command is used to launch both apps and the .NET Core CLI. The dotnet command itself doesn't
collect telemetry. The .NET Core CLI commands run by the dotnet command collect the telemetry.
Telemetry isn't enabled when using the dotnet command itself, with no command attached:
dotnet
dotnet [path-to-app]
Telemetry is enabled when using the .NET Core CLI commands, such as:
dotnet build
dotnet pack
dotnet restore
dotnet run
Behavior
The .NET Core CLI Tools telemetry feature is enabled by default. Opt-out of the telemetry feature by setting the
DOTNET_CLI_TELEMETRY_OPTOUT environment variable to 1 or true .
Data points
The feature collects the following data:
Timestamp of invocation†
Command invoked (for example, "build")†
Three octet IP address used to determine geographical location†
ExitCode of the command
Test runner (for test projects)
Operating system and version†
Whether runtime IDs are present in the runtimes node
.NET Core SDK version†
†This metric is published.
Starting with .NET Core SDK 2.0, new data points are collected:
dotnet command arguments and options: only known arguments and options are collected (not arbitrary
strings).
Whether the SDK is running in a container.
Target frameworks.
Hashed MAC address: a cryptographically (SHA256) anonymous and unique ID for a machine. This metric is not
published.
Hashed current working directory.
The feature doesn't collect personal data, such as usernames or email addresses. It doesn't scan your code and
doesn't extract sensitive project-level data, such as name, repo, or author. The data is sent securely to Microsoft
servers using Microsoft Azure Application Insights technology, held under restricted access, and published under
strict security controls from secure Azure Storage systems.
We want to know how the tools are used and if they're working well, not what you're building with the tools. If you
suspect that the telemetry is collecting sensitive data or that we're insecurely or inappropriately handling data, file
an issue in the dotnet/cli repo issues for investigation.
Published data
Published data is available quarterly and are listed at .NET Core SDK Usage Data. The columns of a data file are:
Timestamp
Occurrences†
Command
Geography‡
OSFamily
RuntimeID
OSVersion
SDKVersion
†The Occurrences column displays the aggregate count of that command's use for that row's metrics that day.
‡Typically, the Geography column displays the name of a country. In some cases, the continent of Antarctica
appears in this column, either due to researchers using .NET Core in Antarctica or incorrect location data.
Example
OCCURRENC
TIMESTAMP ES COMMAND GEOGRAPHY OSFAMILY RUNTIMEID OSVERSION SDKVERSION
Datasets
2016 - Q3
2016 - Q4
2017 - Q1
2017 - Q2
Additional datasets are posted using a standard URL format. Replace <YEAR> with the year and replace <QUARTER>
with the quarter of the year (use 1 , 2 , 3 , or 4 ). The files are in tab-separated values (TSV) format.
https://dotnetcli.blob.core.windows.net/usagedata/dotnet-cli-usage-<YEAR>-q<QUARTER>.tsv
License
The Microsoft distribution of .NET Core is licensed with the MICROSOFT .NET LIBRARY EULA. This license includes
the "DATA" section to enable telemetry (shown below).
.NET NuGet packages use the same license but don't enable telemetry (see Scope).
2. DATA. The software may collect information about you and your use of the software, and send that to
Microsoft. Microsoft may use this information to improve our products and services. You can learn more
about data collection and use in the help documentation and the privacy statement at
http://go.microsoft.com/fwlink/?LinkId=528096. Your use of the software operates as your consent to these
practices.
Disclosure
The .NET Core CLI Tools display the following text when you first run one of the commands (for example,
dotnet restore ). Text may vary slightly depending on the version of the SDK you're running. This "first run"
experience is how Microsoft notifies you about data collection.
Telemetry
--------------
The .NET Core tools collect usage data in order to improve your experience. The data is anonymous and does not
include command-line arguments. The data is collected by Microsoft and shared with the community.
You can opt out of telemetry by setting a DOTNET_CLI_TELEMETRY_OPTOUT environment variable to 1 using your
favorite shell.
You can read more about .NET Core tools telemetry @ https://aka.ms/dotnet-cli-telemetry.
See also
What we've learned from .NET Core SDK Telemetry
Telemetry reference source (dotnet/cli repo; release/2.0.0 branch)
.NET Core SDK Usage Data
.NET Core CLI tools extensibility model
8/10/2017 • 7 min to read • Edit Online
This document covers the different ways you can extend the .NET Core Command-line Interface (CLI) tools and
explain the scenarios that drive each one of them. You'll see how to consume the tools as well as how to build the
different types of tools.
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp1.1</TargetFramework>
</PropertyGroup>
The <DotNetCliToolReference> element is structured in a similar way as the <PackageReference> element. It needs
the package ID of the package containing the tool and its version to be able to restore.
Building tools
As mentioned, tools are just portable console applications. You build tools as you would build any other console
application. After you build it, you use the dotnet pack command to create a NuGet package (.nupkg file) that
contains your code, information about its dependencies, and so on. You can give any name to the package, but the
application inside, the actual tool binary, has to conform to the convention of dotnet-<command> in order for
dotnet to be able to invoke it.
NOTE
In pre-RC3 versions of the .NET Core command-line tools, the dotnet pack command had a bug that caused the
runtime.config.json to not be packed with the tool. Lacking that file results in errors at runtime. If you encounter this
behavior, be sure to update to the latest tooling and try the dotnet pack again.
Since tools are portable applications, the user consuming the tool must have the version of the .NET Core libraries
that the tool was built against in order to run the tool. Any other dependency that the tool uses and that is not
contained within the .NET Core libraries is restored and placed in the NuGet cache. The entire tool is, therefore, run
using the assemblies from the .NET Core libraries as well as assemblies from the NuGet cache.
These kinds of tools have a dependency graph that is completely separate from the dependency graph of the
project that uses them. The restore process first restores the project's dependencies and then restores each of the
tools and their dependencies.
You can find richer examples and different combinations of this in the .NET Core CLI repo. You can also see the
implementation of tools used in the same repo.
Custom targets
NuGet has the capability to package custom MSBuild targets and props files. With the move of the .NET Core CLI
tools to use MSBuild, the same mechanism of extensibility now applies to .NET Core projects. You would use this
type of extensibility when you want to extend the build process, or when you want to access any of the artifacts in
the build process, such as generated files, or you want to inspect the configuration under which the build is
invoked, etc.
In the following example, you can see the target's project file using the csproj syntax. This instructs the
dotnet pack command what to package, placing the targets files as well as the assemblies into the build folder
inside the package. Notice the <ItemGroup> element that has the Label property set to dotnet pack instructions ,
and the Target defined beneath it.
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<Description>Sample Packer</Description>
<VersionPrefix>0.1.0-preview</VersionPrefix>
<TargetFramework>netstandard1.3</TargetFramework>
<DebugType>portable</DebugType>
<AssemblyName>SampleTargets.PackerTarget</AssemblyName>
</PropertyGroup>
<ItemGroup>
<EmbeddedResource Include="Resources\Pkg\dist-template.xml;compiler\resources\**\*"
Exclude="bin\**;obj\**;**\*.xproj;packages\**" />
<None Include="build\SampleTargets.PackerTarget.targets" />
</ItemGroup>
<ItemGroup Label="dotnet pack instructions">
<Content Include="build\*.targets">
<Pack>true</Pack>
<PackagePath>build\</PackagePath>
</Content>
</ItemGroup>
<Target Name="CollectRuntimeOutputs" BeforeTargets="_GetPackageFiles">
<!-- Collect these items inside a target that runs after build but before packaging. -->
<ItemGroup>
<Content Include="$(OutputPath)\*.dll;$(OutputPath)\*.json">
<Pack>true</Pack>
<PackagePath>build\</PackagePath>
</Content>
</ItemGroup>
</Target>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.DependencyModel" Version="1.0.1-beta-000933"/>
<PackageReference Include="Microsoft.Build.Framework" Version="0.1.0-preview-00028-160627" />
<PackageReference Include="Microsoft.Build.Utilities.Core" Version="0.1.0-preview-00028-160627" />
<PackageReference Include="Newtonsoft.Json" Version="9.0.1" />
</ItemGroup>
<ItemGroup />
<PropertyGroup Label="Globals">
<ProjectGuid>463c66f0-921d-4d34-8bde-7c9d0bffaf7b</ProjectGuid>
</PropertyGroup>
<PropertyGroup Condition=" '$(TargetFramework)' == 'netstandard1.3' ">
<DefineConstants>$(DefineConstants);NETSTANDARD1_3</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
<DefineConstants>$(DefineConstants);RELEASE</DefineConstants>
</PropertyGroup>
</Project>
Consuming custom targets is done by providing a <PackageReference> that points to the package and its version
inside the project that is being extended. Unlike the tools, the custom targets package does get included into the
consuming project's dependency closure.
Using the custom target depends solely on how you configure it. Since it's an MSBuild target, it can depend on a
given target, run after another target and can also be manually invoked using the dotnet msbuild /t:<target-name>
command.
However, if you want to provide a better user experience to your users, you can combine per-project tools and
custom targets. In this scenario, the per-project tool would essentially just accept whatever needed parameters and
would translate that into the required dotnet msbuild invocation that would execute the target. You can see a
sample of this kind of synergy on the MVP Summit 2016 Hackathon samples repo in the dotnet-packer project.
PATH -based extensibility
PATH-based extensibility is usually used for development machines where you need a tool that conceptually covers
more than a single project. The main drawback of this extension mechanism is that it's tied to the machine where
the tool exists. If you need it on another machine, you would have to deploy it.
This pattern of CLI toolset extensibility is very simple. As covered in the .NET Core CLI overview, dotnet driver can
run any command that is named after the dotnet-<command> convention. The default resolution logic first probes
several locations and finally falls back to the system PATH. If the requested command exists in the system PATH
and is a binary that can be invoked, dotnet driver will invoke it.
The file must be executable. On Unix systems, this means anything that has the execute bit set via chmod +x . On
Windows, you can use cmd files.
Let's take a look at the very simple implementation of a "Hello World" tool. We will use both bash and cmd on
Windows. The following command will simply echo "Hello World" to the console.
#!/bin/bash
On macOS, we can save this script as dotnet-hello and set its executable bit with chmod +x dotnet-hello . We can
then create a symbolic link to it in /usr/local/bin using the command
ln -s <full_path>/dotnet-hello /usr/local/bin/ . This will make it possible to invoke the command using the
dotnet hello syntax.
On Windows, we can save this script as dotnet-hello.cmd and put it in a location that is in a system path (or you
can add it to a folder that is already in the path). After this, you can just use dotnet hello to run this example.
Using .NET Core SDK and tools in Continuous
Integration (CI)
7/29/2017 • 8 min to read • Edit Online
Overview
This document outlines using the .NET Core SDK and its tools on a build server. The .NET Core toolset works both
interactively, where a developer types commands at a command prompt, and automatically, where a Continuous
Integration (CI) server runs a build script. The commands, options, inputs, and outputs are the same, and the only
things you supply are a way to acquire the tooling and a system to build your app. This document focuses on
scenarios of tool acquisition for CI with recommendations on how to design and structure your build scripts.
NOTE
When using the installer script, native dependencies aren't installed automatically. You must install the native dependencies if
the operating system doesn't have them. See the list of prerequisites in the .NET Core native prerequisites topic.
CI setup examples
This section describes a manual setup using a PowerShell or bash script, along with a description of several
software as a service (SaaS) CI solutions. The SaaS CI solutions covered are Travis CI, AppVeyor, and Visual Studio
Team Services Build.
Manual setup
Each SaaS service has its own methods for creating and configuring a build process. If you use different SaaS
solution than those listed or require customization beyond the pre-packaged support, you must perform at least
some manual configuration.
In general, a manual setup requires you to acquire a version of the tools (or the latest nightly builds of the tools)
and run your build script. You can use a PowerShell or bash script to orchestrate the .NET Core commands or use a
project file that outlines the build process. The orchestration section provides more detail on these options.
After you create a script that performs a manual CI build server setup, use it on your dev machine to build your
code locally for testing purposes. Once you confirm that the script is running well locally, deploy it to your CI build
server. A relatively simple PowerShell script demonstrates how to obtain the .NET Core SDK and install it on a
Windows build server:
$ErrorActionPreference="Stop"
$ProgressPreference="SilentlyContinue"
# Run the build process now. Implement your build script here.
You provide the implementation for your build process at the end of the script. The script acquires the tools and
then executes your build process. For UNIX machines, the following bash script performs the actions described in
the PowerShell script in a similar manner:
#!/bin/bash
# Do not use an INSTALLDIR path containing spaces:
# https://github.com/dotnet/cli/issues/5281
INSTALLDIR="cli-tools"
CLI_VERSION=1.0.1
DOWNLOADER=$(which curl)
if [ -d "$INSTALLDIR" ]
then
rm -rf "$INSTALLDIR"
fi
mkdir -p "$INSTALLDIR"
echo Downloading the CLI installer.
$DOWNLOADER https://raw.githubusercontent.com/dotnet/cli/rel/1.0.1/scripts/obtain/dotnet-install.sh >
"$INSTALLDIR/dotnet-install.sh"
chmod +x "$INSTALLDIR/dotnet-install.sh"
echo Installing the CLI requested version $CLI_VERSION. Please wait, installation may take a few minutes.
"$INSTALLDIR/dotnet-install.sh" --install-dir "$INSTALLDIR" --version $CLI_VERSION
if [ $? -ne 0 ]
then
echo Download of $CLI_VERSION version of the CLI failed. Exiting now.
exit 0
fi
echo The CLI has been installed.
LOCALDOTNET="$INSTALLDIR/dotnet"
# Run the build process now. Implement your build script here.
Travis CI
You can configure Travis CI to install the .NET Core SDK using the csharp language and the dotnet key. See the
official Travis CI docs on Building a C#, F#, or Visual Basic Project for more information. Note as you access the
Travis CI information that the community-maintained language: csharp language identifier works for all .NET
languages, including F#, and Mono.
Travis CI runs both macOS (OS X 10.11, OS X 10.12) and Linux (Ubuntu 14.04) jobs in a build matrix, where you
specify a combination of runtime, environment, and exclusions/inclusions to cover your build combinations for
your app. See the .travis.yml example file and Customizing the Build in the Travis CI docs for more information. The
MSBuild-based tools include the LTS (1.0.x) and Current (1.1.x) runtimes in the package; so by installing the SDK,
you receive everything you need to build.
AppVeyor
AppVeyor installs the .NET Core 1.0.1 SDK with the Visual Studio 2017 build worker image. Other build images
with different versions of the .NET Core SDK are available; see the appveyor.yml example and the Build worker
images topic in the AppVeyor docs for more information.
The .NET Core SDK binaries are downloaded and unzipped in a subdirectory using the install script, and then
they're added to the PATH environment variable. Add a build matrix to run integration tests with multiple versions
of the .NET Core SDK:
environment:
matrix:
- CLI_VERSION: 1.0.1
- CLI_VERSION: Latest
install:
# See appveyor.yml example for install script
2. After configuring the repository to build, you're directed to the build definitions. Select Add build step:
3. You're presented with the Task catalog. The catalog contains tasks that you use in the build. Since you have
a script, select the Add button for PowerShell: Run a PowerShell script.
4. Configure the build step. Add the script from the repository that you're building:
See also
Ubuntu acquisition steps
Custom templates for dotnet new
8/14/2017 • 6 min to read • Edit Online
The .NET Core SDK comes with many templates pre-installed to use with the dotnet new command. Starting with
.NET Core 2.0, you can create your own custom templates for any type of project, such as an app, service, tool, or
class library. You can even create a template that outputs one or more independent files, such as a configuration
file.
You can install custom templates from a NuGet package on any NuGet feed, by referencing a NuGet nupkg file
directly, or by specifying a file system directory that contains the template. The template engine offers features that
allow you to replace values, include and exclude files and regions of files, and execute custom processing
operations when your template is used.
The template engine is open source, and the online code repository is at dotnet/templating on GitHub. Visit the
dotnet/dotnet-template-samples repo for samples of templates. More templates, including templates from third
parties, are found at Available templates for dotnet new on GitHub. For more information about creating and using
custom templates, see How to create your own templates for dotnet new and the dotnet/templating GitHub repo
Wiki.
To follow a walkthrough and create a template, see the Create a custom template for dotnet new tutorial.
Configuration
A template is composed of the following components:
Source files and folders
A configuration file (template.json)
Source files and folders
The source files and folders include whatever files and folders you want the template engine to use when the
dotnet new <TEMPLATE> command is executed. The template engine is designed to use runnable projects as source
code to produce projects. This has several benefits:
The template engine doesn't require you to inject special tokens into your project's source code.
The code files aren't special files or modified in any way to work with the template engine. So, the tools you
normally use when working with projects also work with template content.
You build, run, and debug your template projects just like you do for any of your other projects.
You can quickly create a template from an existing project just by adding a template.json configuration file to
the project.
Files and folders stored in the template aren't limited to formal .NET project types, such as .NET Core or .NET
Framework solutions. Source files and folders may consist of any content that you wish to create when the
template is used, even if the template engine produces just one file for its output, such as a configuration file or a
solution file. For example, you can create a template that contains a web.config source file and creates a modified
web.config file for projects where the template is used. The modifications to source files are based on logic and
settings you've provided in the template.json configuration file along with values provided by the user passed as
options to the dotnet new <TEMPLATE> command.
template.json
The template.json file is placed in a .template.config folder in the root directory of the template. The file provides
configuration information to the template engine. The minimum configuration requires the members shown in the
following table, which is sufficient to create a functional template.
Example:
{
"$schema": "http://json.schemastore.org/template",
"author": "Catalina Garcia",
"classifications": [ "Common", "Console" ],
"identity": "GarciaSoftware.ConsoleTemplate.CSharp",
"name": "Garcia Software Console Application",
"shortName": "garciaconsole"
}
The full schema for the template.json file is found at the JSON Schema Store.
dotnet new -l
Packing a template into a NuGet package (nupkg file)
Currently, a custom template is packed on Windows with nuget.exe (not dotnet pack). For cross-platform
packaging, consider using NuGetizer 3000.
The contents of the project folder, together with its .template.config/template.json file, are placed into a folder
named content. Next to the content folder, add a nuspec file, which is an XML manifest file that describes a
package's contents and drives the process of creating the NuGet package. Inside of a <packageTypes> element in
the nuspec file, include a <packageType> element with a name attribute value of Template . Both the content
folder and the nuspec file should reside in the same directory. The table shows the minimum nuspec file elements
required to produce a template as a NuGet package.
See the .nuspec reference for the complete nuspec file schema. An example nuspec file for a template appears in
the Create a custom template for dotnet new tutorial.
Create a package using the nuget pack <PATH_TO_NUSPEC_FILE> command.
Installing a template
Install a custom template from a NuGet package on any NuGet feed by referencing a nupkg file directly or by
specifying a file system directory that contains a templating configuration. Use the -i|--install option with the
dotnet new command.
To install a template from a NuGet package stored at nuget.org
dotnet new -i <NUGET_PACKAGE_ID>
Uninstalling a template
Uninstall a custom template by referencing a NuGet package by its id or by specifying a file system directory that
contains a templating configuration. Use the -u|--uninstall install option with the dotnet new command.
To uninstall a template from a NuGet package stored at nuget.org
See also
Create a custom template for dotnet new (tutorial)
dotnet/templating GitHub repo Wiki
dotnet/dotnet-template-samples GitHub repo
How to create your own templates for dotnet new
template.json schema at the JSON Schema Store
dotnet command
8/18/2017 • 4 min to read • Edit Online
This topic applies to: ✓ .NET Core 1.x ✓ .NET Core 2.x
Name
dotnet - General driver for running the command-line commands.
Synopsis
.NET Core 2.x
.NET Core 1.x
Description
dotnet is a generic driver for the Command Line Interface (CLI) toolchain. Invoked on its own, it provides brief
usage instructions.
Each specific feature is implemented as a command. In order to use the feature, the command is specified after
dotnet , such as dotnet build . All of the arguments following the command are its own arguments.
The only time dotnet is used as a command on its own is to run framework-dependent apps. Specify an
application DLL after the dotnet verb to execute the application (for example, dotnet myapp.dll ).
Options
.NET Core 2.x
.NET Core 1.x
--additionaldeps <PATH>
Version of the installed .NET Core runtime to use to run the application.
-h|--help
Prints out a short help for the command. If using with dotnet , it also prints a list of the available commands.
--info
Prints out detailed information about the CLI tooling and the environment, such as the current operating system,
commit SHA for the version, and other information.
--roll-forward-on-no-candidate-fx
dotnet commands
General
.NET Core 2.x
.NET Core 1.x
COMMAND FUNCTION
dotnet help Shows more detailed documentation online for the command.
dotnet migrate Migrates a valid Preview 2 project to a .NET Core SDK 1.0
project.
dotnet sln Options to add, remove, and list projects in a solution file.
Project references
COMMAND FUNCTION
NuGet packages
COMMAND FUNCTION
NuGet commands
COMMAND FUNCTION
dotnet nuget locals Clears or lists local NuGet resources such as http-request
cache, temporary cache, or machine-wide global packages
folder.
dotnet nuget push Pushes a package to the server and publishes it.
Examples
Initialize a sample .NET Core console application that can be compiled and run:
dotnet new console
Environment variables
DOTNET_PACKAGES
The primary package cache. If not set, it defaults to $HOME/.nuget/packages on Unix or %HOME%\NuGet\Packages on
Windows.
DOTNET_SERVICING
Specifies the location of the servicing index to use by the shared host when loading the runtime.
DOTNET_CLI_TELEMETRY_OPTOUT
Specifies whether data about the .NET Core tools usage is collected and sent to Microsoft. Set to true to opt-out
of the telemetry feature (values true , 1 , or yes accepted); otherwise, set to false to opt-in to the telemetry
features (values false , 0 , or no accepted). If not set, the defaults is false , and the telemetry feature is active.
dotnet-build
8/15/2017 • 4 min to read • Edit Online
This topic applies to: ✓ .NET Core 1.x ✓ .NET Core 2.x
Name
dotnet build - Builds a project and all of its dependencies.
Synopsis
.NET Core 2.x
.NET Core 1.x
Description
The dotnet build command builds the project and its dependencies into a set of binaries. The binaries include
the project's code in Intermediate Language (IL) files with a .dll extension and symbol files used for debugging
with a .pdb extension. A dependencies JSON file (\.deps.json) is produced that lists the dependencies of the
application. A *\.runtimeconfig.json* file is produced, which specifies the shared runtime and its version for the
application.
If the project has third-party dependencies, such as libraries from NuGet, they're resolved from the NuGet cache
and aren't available with the project's built output. With that in mind, the product of dotnet build isn't ready to
be transferred to another machine to run. This is in contrast to the behavior of the .NET Framework in which
building an executable project (an application) produces output that's runnable on any machine where the .NET
Framework is installed. To have a similar experience with .NET Core, you need to use the dotnet publish
command. For more information, see .NET Core Application Deployment.
Building requires the project.assets.json file, which lists the dependencies of your application. The file is created
when dotnet restore is executed. Without the assets file in place, the tooling cannot resolve reference
assemblies, which results in errors. With .NET Core 1.x SDK, you needed to explicitily run the dotnet restore
before running dotnet build . Starting with .NET Core 2.0 SDK, dotnet restore runs implicitily when you run
dotnet build . If you want to disable implicit restore when running the build command, you can pass the
--no-restore option.
dotnet build uses MSBuild to build the project; thus, it supports both parallel and incremental builds. Refer to
Incremental Builds for more information.
In addition to its options, the dotnet build command accepts MSBuild options, such as /p for setting
properties or /l to define a logger. Learn more about these options in the MSBuild Command-Line Reference.
Whether the project is executable or not is determined by the <OutputType> property in the project file. The
following example shows a project that will produce executable code:
<PropertyGroup>
<OutputType>Exe</OutputType>
</PropertyGroup>
In order to produce a library, omit the <OutputType> property. The main difference in built output is that the IL
DLL for a library doesn't contain entry points and can't be executed.
Arguments
PROJECT
The project file to build. If a project file is not specified, MSBuild searches the current working directory for a file
that has a file extension that ends in proj and uses that file.
Options
.NET Core 2.x
.NET Core 1.x
-c|--configuration {Debug|Release}
Compiles for a specific framework. The framework must be defined in the project file.
--force
Forces all dependencies to be resolved even if the last restore was successful. This is equivalent to deleting the
project.assets.json file.
-h|--help
Ignores project-to-project (P2P) references and only builds the root project specified to build.
--no-incremental
Marks the build as unsafe for incremental build. This turns off incremental compilation and forces a clean
rebuild of the project's dependency graph.
--no-restore
Directory in which to place the built binaries. You also need to define --framework when you specify this option.
-r|--runtime <RUNTIME_IDENTIFIER>
Specifies the target runtime. For a list of Runtime Identifiers (RIDs), see the RID catalog.
-v|--verbosity <LEVEL>
Sets the verbosity level of the command. Allowed values are q[uiet] , m[inimal] , n[ormal] , d[etailed] , and
diag[nostic] .
--version-suffix <VERSION_SUFFIX>
Defines the version suffix for an asterisk ( * ) in the version field of the project file. The format follows NuGet's
version guidelines.
Examples
Build a project and its dependencies:
dotnet build
Build a project and its dependencies for a specific runtime (in this example, Ubuntu 16.04):
dotnet build --runtime ubuntu.16.04-x64
dotnet-clean
8/15/2017 • 2 min to read • Edit Online
This topic applies to: ✓ .NET Core 1.x ✓ .NET Core 2.x
Name
dotnet clean - Cleans the output of a project.
Synopsis
.NET Core 2.x
.NET Core 1.x
Description
The dotnet clean command cleans the output of the previous build. It's implemented as an MSBuild target, so the
project is evaluated when the command is run. Only the outputs created during the build are cleaned. Both
intermediate (obj) and final output (bin) folders are cleaned.
Arguments
PROJECT
The MSBuild project to clean. If a project file is not specified, MSBuild searches the current working directory for a
file that has a file extension that ends in proj and uses that file.
Options
.NET Core 2.x
.NET Core 1.x
-c|--configuration {Debug|Release}
Defines the build configuration. The default value is Debug . This option is only required when cleaning if you
specified it during build time.
-f|--framework <FRAMEWORK>
The framework that was specified at build time. The framework must be defined in the project file. If you specified
the framework at build time, you must specify the framework when cleaning.
-h|--help
Directory in which the build outputs are placed. Specify the -f|--framework <FRAMEWORK> switch with the output
directory switch if you specified the framework when the project was built.
-r|--runtime <RUNTIME_IDENTIFIER>
Cleans the output folder of the specified runtime. This is used when a self-contained deployment was created.
-v|--verbosity <LEVEL>
Sets the verbosity level of the command. Allowed levels are q[uiet], m[inimal], n[ormal], d[etailed], and
diag[nostic].
Examples
Clean a default build of the project:
dotnet clean
Name
dotnet help - Shows more detailed documentation online for the specified command.
Synopsis
dotnet help <COMMAND_NAME> [-h|--help]
Description
The dotnet help command opens up the reference page for more detailed information about the specified
command at docs.microsoft.com.
Arguments
COMMAND_NAME
Name of the .NET Core CLI command. For a list of the valid CLI commands, see CLI commands.
Options
-h|--help
Examples
Opens the documentation page for the dotnet new command:
dotnet help new
dotnet-install scripts reference
7/29/2017 • 6 min to read • Edit Online
Name
dotnet-install.ps1 | dotnet-install.sh - Script used to install the .NET Core Command-line Interface (CLI) tools
and the shared runtime.
Synopsis
Windows:
dotnet-install.ps1 [-Channel] [-Version] [-InstallDir] [-Architecture] [-SharedRuntime] [-DebugSymbols] [-
DryRun] [-NoPath] [-AzureFeed] [-ProxyAddress]
macOS/Linux:
dotnet-install.sh [--channel] [--version] [--install-dir] [--architecture] [--shared-runtime] [--debug-
symbols] [--dry-run] [--no-path] [--verbose] [--azure-feed] [--help]
Description
The dotnet-install scripts are used to perform a non-admin install of the CLI toolchain and the shared runtime.
You can download the scripts from the CLI GitHub repo.
The main usefulness of these scripts is in automation scenarios and non-admin installations. There are two scripts:
One is a PowerShell script that works on Windows. The other script is a bash script that works on Linux/OS X.
Both scripts have the same behavior. The bash script also reads PowerShell switches, so you can use PowerShell
switches with the script on Linux/OS X systems.
The installation scripts download the ZIP/tarball file from the CLI build drops and proceed to install it in either the
default location or in a location specified by -InstallDir|--install-dir . By default, the installation scripts
download the SDK and install it. If you wish to only obtain the shared runtime, specify the --shared-runtime
argument.
By default, the script adds the install location to the $PATH for the current session. Override this default behavior
by specifying the --no-path argument.
Before running the script, install the required dependencies.
You can install a specific version using the --version argument. The version must be specified as a 3-part version
(for example, 1.0.0-13232). If omitted, it defaults to the first global.json file found in the hierarchy above the folder
where the script is invoked that contains the version property. If that isn't present, it will use the latest version.
You can also use this script to obtain the SDK or shared runtime debug binaries with debug symbols by using the
--debug argument. If you fail to do this on first install and realize later that you need the debug symbols, you can
re-run the script with the --debug argument and the SDK version you installed to obtain the debug symbols.
Options
Note: Options are different between script implementations.
PowerShell (Windows)
-Channel <CHANNEL>
Specifies the source channel for the installation. The possible values are:
Current - Current release
LTS - Long-Term Support channel (current supported release)
Two-part version in X.Y format representing a specific release (for example, 2.0 or 1.0 )
Branch name [for example, release/2.0.0 , release/2.0.0-preview2 , or master for the latest from the master
branch ("bleeding edge" nightly releases)]
The default value is LTS . For more information on .NET support channels, see the .NET Core Support Lifecycle
topic.
-Version <VERSION>
Represents a build version on the source channel (see the -Channel option). The possible values are:
latest - Latest build on the channel
coherent - Latest coherent build on the channel; uses the latest stable package combination
Three-part version in X.Y.Z format representing a specific build version (for example, 1.0.x with x
representing the patch version; or a specific build, such as 2.0.0-preview2-006120 )
If omitted, -Version defaults to the first global.json that contains the version member. If that isn't present,
-Version defaults to latest .
-InstallDir <DIRECTORY>
Specifies the installation path. The directory is created if it doesn't exist. The default value is
%LocalAppData%.dotnet. Note that binaries are placed directly in the directory.
-Architecture <ARCHITECTURE>
Architecture of the .NET Core binaries to install. Possible values are auto , x64 , and x86 . The default value is
auto , which represents the currently running OS architecture.
-SharedRuntime
If set, this switch limits installation to the shared runtime. The entire SDK isn't installed.
-DebugSymbols (see NOTE)
If set, the installer includes debugging symbols in the installation.
NOTE
The -DebugSymbols switch is not currently avaiable but planned for a future release.
-DryRun
If set, the script won't perform the installation; but instead, it displays what command line to use to consistently
install the currently requested version of the .NET Core CLI. For example if you specify version latest , it displays
a link with the specific version so that this command can be used deterministically in a build script. It also displays
the binary's location if you prefer to install or download it yourself.
-NoPath
If set, the prefix/installdir are not exported to the path for the current session. By default, the script will modify the
PATH, which makes the CLI tools available immediately after install.
-AzureFeed
Specifies the URL for the Azure feed to the installer. It isn't recommended that you change this value. The default
is https://dotnetcli.azureedge.net/dotnet .
-ProxyAddress
If set, the installer uses the proxy when making web requests.
Bash (macOS/Linux)
dotnet-install.sh [--channel] [--version] [--install-dir] [--architecture] [--shared-runtime] [--debug-
symbols] [--dry-run] [--no-path] [--verbose] [--azure-feed] [--help]
-Channel <CHANNEL>
Specifies the source channel for the installation. The possible values are:
Current - Current release
LTS - Long-Term Support channel (current supported release)
Two-part version in X.Y format representing a specific release (for example, 2.0 or 1.0 )
Branch name [for example, release/2.0.0 , release/2.0.0-preview2 , or master for the latest from the master
branch ("bleeding edge" nightly releases)]
The default value is LTS . For more information on .NET support channels, see the .NET Core Support Lifecycle
topic.
-Version <VERSION>
Represents a build version on the source channel (see the -Channel option). The possible values are:
latest - Latest build on the channel
coherent - Latest coherent build on the channel; uses the latest stable package combination
Three-part version in X.Y.Z format representing a specific build version (for example, 1.0.x with x
representing the patch version; or a specific build, such as 2.0.0-preview2-006120 )
If omitted, -Version defaults to the first global.json that contains the version member. If that isn't present,
-Version defaults to latest .
--install-dir <DIRECTORY>
Specifies the installation path. The directory is created if it doesn't exist. The default value is $HOME/.dotnet .
--architecture <ARCHITECTURE>
Architecture of the .NET Core binaries to install. Possible values are auto , x64 and amd64 . The default value is
auto , which represents the currently running OS architecture.
--shared-runtime
If set, this switch limits installation to the shared runtime. The entire SDK isn't installed.
--debug-symbols
NOTE
This switch is not currently avaiable but planned for a future release.
--dry-run
If set, the script won't perform the installation; but instead, it displays what command line to use to consistently
install the currently requested version of the .NET Core CLI. For example if you specify version latest , it displays
a link with the specific version so that this command can be used deterministically in a build script. It also displays
the binary's location if you prefer to install or download it yourself.
--no-path
If set, the prefix/installdir are not exported to the path for the current session. By default, the script will modify the
PATH, which makes the CLI tools available immediately after install.
--verbose
Specifies the URL for the Azure feed to the installer. It isn't recommended that you change this value. The default
is https://dotnetcli.azureedge.net/dotnet .
--help
Examples
Install the latest development version to the default location:
Windows:
./dotnet-install.ps1 -Channel Future
macOS/Linux:
./dotnet-install.sh --channel Future
macOS/Linux:
./dotnet-install.sh --channel preview --install-dir ~/cli
See also
.NET Core releases
.NET Core Runtime and SDK download archive
dotnet migrate
8/15/2017 • 2 min to read • Edit Online
This topic applies to: ✓ .NET Core 1.x ✓ .NET Core 2.x
Name
dotnet migrate - Migrates a Preview 2 .NET Core project to a .NET Core SDK 1.0 project.
Synopsis
dotnet migrate [<SOLUTION_FILE|PROJECT_DIR>] [-t|--template-file] [-v|--sdk-package-version] [-x|--xproj-file]
[-s|--skip-project-references] [-r|--report-file] [--format-report-file-json] [--skip-backup] [-h|--help]
Description
The dotnet migrate command migrates a valid Preview 2 project.json-based project to a valid .NET Core SDK 1.0
csproj project.
By default, the command migrates the root project and any project references that the root project contains. This
behavior is disabled using the --skip-project-references option at runtime.
Migration is performed on the following:
A single project by specifying the project.json file to migrate.
All of the directories specified in the global.json file by passing in a path to the global.json file.
A solution.sln file, where it migrates the projects referenced in the solution.
On all sub-directories of the given directory recursively.
The dotnet migrate command keeps the migrated project.json file inside a backup directory, which it creates if
the directory doesn't exist. This behavior is overriden using the --skip-backup option.
By default, the migration operation outputs the state of the migration process to standard output (STDOUT). If
you use the --report-file <REPORT_FILE> option, the output is saved to the file specify.
The dotnet migrate command only supports valid Preview 2 project.json-based projects. This means that you
cannot use it to migrate DNX or Preview 1 project.json-based projects directly to MSBuild/csproj projects. You
first need to manually migrate the project to a Preview 2 project.json-based project and then use the
dotnet migrate command to migrate the project.
Arguments
PROJECT_JSON/GLOBAL_JSON/SOLUTION_FILE/PROJECT_DIR
Template csproj file to use for migration. By default, the same template as the one dropped by
dotnet new console is used.
-v|--sdk-package-version <VERSION>
The version of the sdk package that's referenced in the migrated app. The default is the version of the SDK in
dotnet new .
-x|--xproj-file <FILE>
The path to the xproj file to use. Required when there is more than one xproj in a project directory.
-s|--skip-project-references [Debug|Release]
Skip migrating project references. By default, project references are migrated recursively.
-r|--report-file <REPORT_FILE>
Skip moving project.json, global.json, and \.xproj* to a backup directory after successful migration.
Examples
Migrate a project in the current directory and all of its project-to-project dependencies:
dotnet migrate
Migrate only the current project and no project-to-project (P2P) dependencies. Also, use a specific SDK version:
dotnet migrate -s -v 1.0.0-preview4
dotnet msbuild
8/15/2017 • 1 min to read • Edit Online
This topic applies to: ✓ .NET Core 1.x ✓ .NET Core 2.x
Name
dotnet msbuild - Builds a project and all of its dependencies.
Synopsis
dotnet msbuild <msbuild_arguments> [-h]
Description
The dotnet msbuild command allows access to a fully functional MSBuild.
The command has the exact same capabilities as existing MSBuild command-line client. The options are all the
same. Use the MSBuild Command-Line Reference to obtain information on the available options.
Examples
Build a project and its dependencies:
dotnet msbuild
Run the publish target and publish for the osx.10.11-x64 RID:
dotnet msbuild /t:Publish /p:RuntimeIdentifiers=osx.10.11-x64
See the whole project with all targets included by the SDK:
dotnet msbuild /pp
dotnet new
8/15/2017 • 8 min to read • Edit Online
This topic applies to: ✓ .NET Core 1.x ✓ .NET Core 2.x
Name
dotnet new - Creates a new project, configuration file, or solution based on the specified template.
Synopsis
.NET Core 2.x
.NET Core 1.x
Description
The dotnet new command provides a convenient way to initialize a valid .NET Core project.
The command calls the template engine to create the artifacts on disk based on the specified template and
options.
Arguments
TEMPLATE
The template to instantiate when the command is invoked. Each template might have specific options you can
pass. For more information, see Template options.
.NET Core 2.x
.NET Core 1.x
The command contains a default list of templates. Use dotnet new -l to obtain a list of the available
templates. The following table shows the templates that come pre-installed with the .NET Core 2.0 SDK. The
default language for the template is shown inside the brackets.
MVC/ViewImports viewimports
Options
.NET Core 2.x
.NET Core 1.x
--force
Forces content to be generated even if it would change existing files. This is required when the output directory
already contains a project.
-h|--help
Prints out help for the command. It can be invoked for the dotnet new command itself or for any template,
such as dotnet new mvc --help .
-i|--install <PATH|NUGET_ID>
Installs a source or template pack from the PATH or NUGET_ID provided. For information on creating custom
templates, see Custom templates for dotnet new.
-l|--list
Lists templates containing the specified name. If invoked for the dotnet new command, it lists the possible
templates available for the given directory. For example if the directory already contains a project, it doesn't list
all project templates.
-lang|--language {C#|F#|VB}
The language of the template to create. The language accepted varies by the template (see defaults in the
arguments section). Not valid for some templates.
-n|--name <OUTPUT_NAME>
The name for the created output. If no name is specified, the name of the current directory is used.
-o|--output <OUTPUT_DIRECTORY>
Location to place the generated output. The default is the current directory.
--type
Filters templates based on available types. Predefined values are "project", "item" or "other".
-u|--uninstall <PATH|NUGET_ID>
Template options
Each project template may have additional options available. The core templates have the following additional
options:
.NET Core 2.x
.NET Core 1.x
console, angular, react, reactredux
--no-restore - Doesn't perform an implicit restore during project creation.
classlib
-f|--framework <FRAMEWORK> - Specifies the framework to target. Values: netcoreapp2.0 to create a .NET Core
Class Library or netstandard2.0 to create a .NET Standard Class Library. The default value is netstandard2.0 .
--no-restore - Doesn't perform an implicit restore during project creation.
mstest, xunit
-p|--enable-pack - Enables packaging for the project using dotnet pack.
--no-restore - Doesn't perform an implicit restore during project creation.
globaljson
--sdk-version <VERSION_NUMBER> - Specifies the version of the .NET Core SDK to use in the global.json file.
web
--use-launch-settings - Includes launchSettings.json in the generated template output.
--no-restore - Doesn't perform an implicit restore during project creation.
webapi
-au|--auth <AUTHENTICATION_TYPE> - The type of authentication to use. The possible values are:
None - No authentication (Default).
IndividualB2C - Individual authentication with Azure AD B2C.
SingleOrg - Organizational authentication for a single tenant.
Windows - Windows authentication.
--aad-b2c-instance <INSTANCE> - The Azure Active Directory B2C instance to connect to. Use with
IndividualB2C authentication. The default value is https://login.microsoftonline.com/tfp/ .
-ssp|--susi-policy-id <ID> - The sign-in and sign-up policy ID for this project. Use with IndividualB2C
authentication.
--aad-instance <INSTANCE> - The Azure Active Directory instance to connect to. Use with SingleOrg
authentication. The default value is https://login.microsoftonline.com/ .
--client-id <ID> - The Client ID for this project. Use with IndividualB2C or SingleOrg authentication. The
default value is 11111111-1111-1111-11111111111111111 .
--domain <DOMAIN> - The domain for the directory tenant. Use with SingleOrg or IndividualB2C
authentication. The default value is qualified.domain.name .
--tenant-id <ID> - The TenantId ID of the directory to connect to. Use with SingleOrg authentication. The
default value is 22222222-2222-2222-2222-222222222222 .
-r|--org-read-access - Allows this application read-access to the directory. Only applies to SingleOrg or
MultiOrg authentication.
--use-launch-settings - Includes launchSettings.json in the generated template output.
-uld|--use-local-db - Specifies LocalDB should be used instead of SQLite. Only applies to Individual or
IndividualB2C authentication.
--no-restore - Doesn't perform an implicit restore during project creation.
mvc, razor
-au|--auth <AUTHENTICATION_TYPE> - The type of authentication to use. The possible values are:
None - No authentication (Default).
Individual - Individual authentication.
IndividualB2C - Individual authentication with Azure AD B2C.
SingleOrg - Organizational authentication for a single tenant.
MultiOrg - Organizational authentication for multiple tenants.
Windows - Windows authentication.
--aad-b2c-instance <INSTANCE> - The Azure Active Directory B2C instance to connect to. Use with
IndividualB2C authentication. The default value is https://login.microsoftonline.com/tfp/ .
-ssp|--susi-policy-id <ID> - The sign-in and sign-up policy ID for this project. Use with IndividualB2C
authentication.
-rp|--reset-password-policy-id <ID> - The reset password policy ID for this project. Use with IndividualB2C
authentication.
-ep|--edit-profile-policy-id <ID> - The edit profile policy ID for this project. Use with IndividualB2C
authentication.
--aad-instance <INSTANCE> - The Azure Active Directory instance to connect to. Use with SingleOrg or
MultiOrg authentication. The default value is https://login.microsoftonline.com/ .
--client-id <ID> - The Client ID for this project. Use with IndividualB2C , SingleOrg , or MultiOrg
authentication. The default value is 11111111-1111-1111-11111111111111111 .
--domain <DOMAIN> - The domain for the directory tenant. Use with SingleOrg or IndividualB2C
authentication.. The default value is qualified.domain.name .
--tenant-id <ID> - The TenantId ID of the directory to connect to. Use with SingleOrg authentication.. The
default value is 22222222-2222-2222-2222-222222222222 .
--callback-path <PATH> - The request path within the application's base path of the redirect URI. Use with
SingleOrg or IndividualB2C authentication.. The default value is /signin-oidc .
-r|--org-read-access - Allows this application read-access to the directory. Only applies to SingleOrg or
MultiOrg authentication.
--use-launch-settings - Includes launchSettings.json in the generated template output.
--use-browserlink - Includes BrowserLink in the project.
-uld|--use-local-db - Specifies LocalDB should be used instead of SQLite. Only applies to Individual or
IndividualB2C authentication.
--no-restore - Doesn't perform an implicit restore during project creation.
page
-na|--namespace <NAMESPACE_NAME> - Namespace for the generated code. The default value is MyApp.Namespace .
-np|--no-pagemodel - Creates the page without a PageModel.
viewimports
-na|--namespace <NAMESPACE_NAME> - Namespace for the generated code. The default value is MyApp.Namespace .
Examples
Create an F# console application project in the current directory:
dotnet new console -lang f#
Create a .NET Standard class library project in the specified directory (available only with .NET Core 2.0 SDK or
later versions):
dotnet new classlib -lang VB -o MyLibrary
Create a new ASP.NET Core C# MVC application project in the current directory with no authentication
targeting .NET Core 2.0:
dotnet new mvc -au None -f netcoreapp2.0
See also
Custom templates for dotnet new
Create a custom template for dotnet new
dotnet/dotnet-template-samples GitHub repo
Available templates for dotnet new
dotnet nuget delete
8/15/2017 • 1 min to read • Edit Online
This topic applies to: ✓ .NET Core 1.x ✓ .NET Core 2.x
Name
dotnet nuget delete - Deletes or unlists a package from the server.
Synopsis
dotnet nuget delete [<PACKAGE_NAME> <PACKAGE_VERSION>] [-s|--source] [--non-interactive] [-k|--api-key] [--
force-english-output] [-h|--help]
Description
The dotnet nuget delete command deletes or unlists a package from the server. For nuget.org, the action is to
unlist the package.
Arguments
PACKAGE_NAME
Package to delete.
PACKAGE_VERSION
Options
-h|--help
Specifies the server URL. Supported URLs for nuget.org include http://www.nuget.org ,
http://www.nuget.org/api/v3 , and http://www.nuget.org/api/v2/package . For private feeds, substitute the host
name (for example, %hostname%/api/v3 ).
--non-interactive
Examples
Deletes version 1.0 of package Microsoft.AspNetCore.Mvc :
dotnet nuget delete Microsoft.AspNetCore.Mvc 1.0
Deletes version 1.0 of package Microsoft.AspNetCore.Mvc , not prompting user for credentials or other input:
dotnet nuget delete Microsoft.AspNetCore.Mvc 1.0 --non-interactive
dotnet nuget locals
8/15/2017 • 1 min to read • Edit Online
This topic applies to: ✓ .NET Core 1.x ✓ .NET Core 2.x
Name
dotnet nuget locals - Clears or lists local NuGet resources.
Synopsis
dotnet nuget locals <CACHE_LOCATION> [(-c|--clear)|(-l|--list)] [--force-english-output] [-h|--help]
Description
The dotnet nuget locals command clears or lists local NuGet resources in the http-request cache, temporary
cache, or machine-wide global packages folder.
Arguments
CACHE_LOCATION
Options
-h|--help
The clear option performs a clear operation on the specified cache type. The contents of the cache directories are
deleted recursively. The executing user/group must have permission to the files in the cache directories. If not, an
error is displayed indicating the files/folders which were not cleared.
-l|--list
The list option is used to display the location of the specified cache type.
--force-english-output
Clears all files from all local cache directories (http-cache directory, global-packages cache directory, and
temporary cache directory):
dotnet nuget locals --clear all
Troubleshooting
For information on common problems and errors while using the dotnet nuget locals command, see Managing
the NuGet cache.
dotnet nuget push
8/15/2017 • 1 min to read • Edit Online
This topic applies to: ✓ .NET Core 1.x ✓ .NET Core 2.x
Name
dotnet nuget push - Pushes a package to the server and publishes it.
Synopsis
dotnet nuget push [<ROOT>] [-s|--source] [-ss|--symbol-source] [-t|--timeout] [-k|--api-key] [-sk|--symbol-api-
key] [-d|--disable-buffering] [-n|--no-symbols] [--force-english-output] [-h|--help]
Description
The dotnet nuget push command pushes a package to the server and publishes it. The push command uses server
and credential details found in the system's NuGet config file or chain of config files. For more information on
config files, see Configuring NuGet Behavior. NuGet's default configuration is obtained by loading
%AppData%\NuGet\NuGet.config (Windows) or $HOME/.local/share (Linux/macOS), then loading any
nuget.config or .nuget\nuget.config starting from the root of drive and ending in the current directory.
Arguments
ROOT
Specify the path to the package and your API key to push the package to the server.
Options
-h|--help
Specifies the server URL. This option is required unless DefaultPushSource config value is set in the NuGet config
file.
--symbols-source <SOURCE>
Specifies the timeout for pushing to a server in seconds. Defaults to 300 seconds (5 minutes). Specifying 0 (zero
seconds) applies the default value.
-k|--api-key <API_KEY>
Examples
Pushes foo.nupkg to the default push source, providing an API key:
dotnet nuget push foo.nupkg -k 4003d786-cc37-4004-bfdf-c4f3e8ef9b3a
Push foo.nupkg to the custom push source http://customsource , providing an API key:
dotnet nuget push foo.nupkg -k 4003d786-cc37-4004-bfdf-c4f3e8ef9b3a -s http://customsource/
Pushes foo.nupkg to the default push source, specifying a 360 second timeout:
dotnet nuget push foo.nupkg --timeout 360
Pushes all .nupkg files in the current directory to the default push source:
dotnet nuget push *.nupkg
Pushes all .nupkg files in the current directory to the default push source, specifying a custom config file
./config/My.Config:
dotnet nuget push *.nupkg --config-file ./config/My.Config
Push all .nupkg files in the current directory to the default push source with maximum verbosity:
dotnet nuget push *.nupkg --verbosity detailed
dotnet pack
8/15/2017 • 3 min to read • Edit Online
This topic applies to: ✓ .NET Core 1.x ✓ .NET Core 2.x
Name
dotnet pack - Packs the code into a NuGet package.
Synopsis
.NET Core 2.x
.NET Core 1.x
Description
The dotnet pack command builds the project and creates NuGet packages. The result of this command is a
NuGet package. If the --include-symbols option is present, another package containing the debug symbols is
created.
NuGet dependencies of the packed project are added to the .nuspec file, so they're properly resolved when the
package is installed. Project-to-project references aren't packaged inside the project. Currently, you must have a
package per project if you have project-to-project dependencies.
By default, dotnet pack builds the project first. If you wish to avoid this behavior, pass the --no-build option.
This is often useful in Continuous Integration (CI) build scenarios where you know the code was previously built.
You can provide MSBuild properties to the dotnet pack command for the packing process. For more
information, see NuGet metadata properties and the MSBuild Command-Line Reference.
Arguments
PROJECT
The project to pack. It's either a path to a csproj file or to a directory. If omitted, it defaults to the current directory.
Options
.NET Core 2.x
.NET Core 1.x
-c|--configuration {Debug|Release}
Includes the source files in the NuGet package. The sources files are included in the src folder within the nupkg .
--include-symbols
Specifies the target runtime to restore packages for. For a list of Runtime Identifiers (RIDs), see the RID catalog.
-s|--serviceable
Sets the serviceable flag in the package. For more information, see .NET Blog: .NET 4.5.1 Supports Microsoft
Security Updates for .NET NuGet Libraries.
--version-suffix <VERSION_SUFFIX>
Defines the value for the $(VersionSuffix) MSBuild property in the project.
-v|--verbosity <LEVEL>
Sets the verbosity level of the command. Allowed values are q[uiet] , m[inimal] , n[ormal] , d[etailed] , and
diag[nostic] .
Examples
Pack the project in the current directory:
dotnet pack
Pack the project in the current directory and place the resulting packages into the nupkgs folder:
dotnet pack --output nupkgs
Pack the project in the current directory into the nupkgs folder and skip the build step:
dotnet pack --no-build --output nupkgs
With the project's version suffix configured as <VersionSuffix>$(VersionSuffix)</VersionSuffix> in the .csproj file,
pack the current project and update the resulting package version with the given suffix:
dotnet pack --version-suffix "ci-1234"
Set the package version to 2.1.0 with the PackageVersion MSBuild property:
dotnet pack /p:PackageVersion=2.1.0
dotnet publish
8/15/2017 • 4 min to read • Edit Online
This topic applies to: ✓ .NET Core 1.x ✓ .NET Core 2.x
Name
dotnet publish - Packs the application and its dependencies into a folder for deployment to a hosting system.
Synopsis
.NET Core 2.x
.NET Core 1.x
Description
dotnet publish compiles the application, reads through its dependencies specified in the project file, and
publishes the resulting set of files to a directory. The output will contain the following:
Intermediate Language (IL) code in an assembly with a dll extension.
.deps.json file that contains all of the dependencies of the project.
.runtime.config.json file that specifies the shared runtime that the application expects, as well as other
configuration options for the runtime (for example, garbage collection type).
The application's dependencies. These are copied from the NuGet cache into the output folder.
The dotnet publish command's output is ready for deployment to a hosting system (for example, a server, PC,
Mac, laptop) for execution and is the only officially supported way to prepare the application for deployment.
Depending on the type of deployment that the project specifies, the hosting system may or may not have the
.NET Core shared runtime installed on it. For more information, see .NET Core Application Deployment. For the
directory structure of a published application, see Directory structure.
Arguments
PROJECT
The project to publish, which defaults to the current directory if not specified.
Options
.NET Core 2.x
.NET Core 1.x
-c|--configuration {Debug|Release}
Publishes the application for the specified target framework. You must specify the target framework in the
project file.
--force
Forces all dependencies to be resolved even if the last restore was successful. This is equivalent to deleting the
project.assets.json file.
-h|--help
Specifies one or several target manifests to use to trim the set of packages published with the app. The manifest
file is part of the output of the dotnet store command. To specify multiple manifests, add a --manifest option
for each manifest. This option is available starting with .NET Core 2.0 SDK.
--no-dependencies
Specifies the path for the output directory. If not specified, it defaults to ./bin/[configuration]/[framework]/ for a
framework-dependent deployment or ./bin/[configuration]/[framework]/[runtime] for a self-contained
deployment.
--self-contained
Publishes the .NET Core runtime with your application so the runtime doesn't need to be installed on the target
machine. If a runtime identifier is specified, its default value is true . For more infomation about the different
deployment types, see .NET Core application deployment.
-r|--runtime <RUNTIME_IDENTIFIER>
Publishes the application for a given runtime. This is used when creating a self-contained deployment (SCD). For
a list of Runtime Identifiers (RIDs), see the RID catalog. Default is to publish a framework-dependent deployment
(FDD).
-v|--verbosity <LEVEL>
Sets the verbosity level of the command. Allowed values are q[uiet] , m[inimal] , n[ormal] , d[etailed] , and
diag[nostic] .
--version-suffix <VERSION_SUFFIX>
Defines the version suffix to replace the asterisk ( * ) in the version field of the project file.
Examples
Publish the project in the current directory:
dotnet publish
Publish the project in the current directory using the netcoreapp1.1 framework:
dotnet publish --framework netcoreapp1.1
Publish the current application using the netcoreapp1.1 framework and the runtime for OS X 10.10 (you must
list this RID in the project file).
dotnet publish --framework netcoreapp1.1 --runtime osx.10.11-x64
See also
Target frameworks
Runtime IDentifier (RID) catalog
dotnet restore
8/29/2017 • 3 min to read • Edit Online
This topic applies to: ✓ .NET Core 1.x ✓ .NET Core 2.x
Name
dotnet restore - Restores the dependencies and tools of a project.
Synopsis
.NET Core 2.x
.NET Core 1.x
Description
The dotnet restore command uses NuGet to restore dependencies as well as project-specific tools that are
specified in the project file. By default, the restoration of dependencies and tools are performed in parallel.
In order to restore the dependencies, NuGet needs the feeds where the packages are located. Feeds are usually
provided via the NuGet.config configuration file. A default configuration file is provided when the CLI tools are
installed. You specify additional feeds by creating your own NuGet.config file in the project directory. You also
specify additional feeds per invocation at a command prompt.
For dependencies, you specify where the restored packages are placed during the restore operation using the
--packages argument. If not specified, the default NuGet package cache is used, which is found in the
.nuget/packages directory in the user's home directory on all operating systems (for example, /home/user1 on
Linux or C:\Users\user1 on Windows).
For project-specific tooling, dotnet restore first restores the package in which the tool is packed, and then
proceeds to restore the tool's dependencies as specified in its project file.
The behavior of the dotnet restore command is affected by some of the settings in the Nuget.Config file, if
present. For example, setting the globalPackagesFolder in NuGet.Config places the restored NuGet packages in
the specified folder. This is an alternative to specifying the --packages option on the dotnet restore
command. For more information, see the NuGet.Config reference.
Arguments
ROOT
Options
.NET Core 2.x
.NET Core 1.x
--configfile <FILE>
The NuGet configuration file (NuGet.config) to use for the restore operation.
--disable-parallel
Forces all dependencies to be resolved even if the last restore was successful. This is equivalent to deleting the
project.assets.json file.
-h|--help
Only warn about failed sources if there are packages meeting the version requirement.
--no-cache
When restoring a project with project-to-project (P2P) references, restores the root project and not the
references.
--packages <PACKAGES_DIRECTORY>
Specifies a runtime for the package restore. This is used to restore packages for runtimes not explicitly listed in
the <RuntimeIdentifiers> tag in the .csproj file. For a list of Runtime Identifiers (RIDs), see the RID catalog.
Provide multiple RIDs by specifying this option multiple times.
-s|--source <SOURCE>
Specifies a NuGet package source to use during the restore operation. This overrides all of the sources specified
in the NuGet.config file(s). Multiple sources can be provided by specifying this option multiple times.
--verbosity <LEVEL>
Sets the verbosity level of the command. Allowed values are q[uiet] , m[inimal] , n[ormal] , d[etailed] , and
diag[nostic] .
dotnet run
8/15/2017 • 3 min to read • Edit Online
This topic applies to: ✓ .NET Core 1.x ✓ .NET Core 2.x
Name
dotnet run - Runs source code without any explicit compile or launch commands.
Synopsis
.NET Core 2.x
.NET Core 1.x
Description
The dotnet run command provides a convenient option to run your application from the source code with one
command. It's useful for fast iterative development from the command line. The command depends on the
dotnet build command to build the code. Any requirements for the build, such as that the project must be
restored first, apply to dotnet run as well.
Output files are written into the default location, which is bin/<configuration>/<target> . For example if you have
a netcoreapp1.0 application and you run dotnet run , the output is placed in bin/Debug/netcoreapp1.0 . Files are
overwritten as needed. Temporary files are placed in the obj directory.
If the project specifies multiple frameworks, executing dotnet run results in an error unless the
-f|--framework <FRAMEWORK> option is used to specify the framework.
The dotnet run command is used in the context of projects, not built assemblies. If you're trying to run a
framework-dependent application DLL instead, you must use dotnet without a command. For example, to run
myapp.dll , use:
dotnet myapp.dll
For more information on the dotnet driver, see the .NET Core Command Line Tools (CLI) topic.
In order to run the application, the dotnet run command resolves the dependencies of the application that are
outside of the shared runtime from the NuGet cache. Because it uses cached dependencies, it's not recommended
to use dotnet run to run applications in production. Instead, create a deployment using the dotnet publish
command and deploy the published output.
Options
.NET Core 2.x
.NET Core 1.x
--
Delimits arguments to dotnet run from arguments for the application being run. All arguments after this one
are passed to the application run.
-c|--configuration {Debug|Release}
Builds and runs the app using the specified framework. The framework must be specified in the project file.
-h|--help
The name of the launch profile (if any) to use when launching the application. Launch profiles are defined in the
launchSettings.json file and are typically called Development , Staging and Production . For more information, see
Working with multiple environments.
--no-build
Specifies the path of the project file to run (folder name or full path). It defaults to the current directory if not
specified.
--runtime <RUNTIME_IDENTIFIER>
Specifies the target runtime to restore packages for. For a list of Runtime Identifiers (RIDs), see the RID catalog.
Examples
Run the project in the current directory:
dotnet run
Run the project in the current directory (the --help argument in this example is passed to the application, since
the -- argument is used):
dotnet run --configuration Release -- --help
dotnet sln
8/15/2017 • 1 min to read • Edit Online
This topic applies to: ✓ .NET Core 1.x ✓ .NET Core 2.x
Name
dotnet-sln - Modifies a .NET Core solution file.
Synopsis
dotnet sln [<SOLUTION_NAME>] add <PROJECT> <PROJECT> ...
dotnet sln [<SOLUTION_NAME>] add <GLOBBING_PATTERN>
dotnet sln [<SOLUTION_NAME>] remove <PROJECT> <PROJECT> ...
dotnet sln [<SOLUTION_NAME>] remove <GLOBBING_PATTERN>
dotnet sln [<SOLUTION_NAME>] list
dotnet sln [-h|--help]
Description
The dotnet sln command provides a convenient way to add, remove, and list projects in a solution file.
Commands
add <PROJECT> ...
add <GLOBBING_PATTERN>
Adds a project or multiple projects to the solution file. Globbing patterns are supported on Unix/Linux based
terminals.
remove <PROJECT> ...
remove <GLOBBING_PATTERN>
Removes a project or multiple projects from the solution file. Globbing patterns are supported on Unix/Linux
based terminals.
list
Arguments
SOLUTION_NAME
Solution file to use. If not specified, the command searches the current directory for one. If there are multiple
solution files in the directory, one must be specified.
Options
-h|--help
Prints out a short help for the command.
Examples
Add a C# project to a solution:
dotnet sln todo.sln add todo-app/todo-app.csproj
Name
dotnet store - Stores the specified assemblies in the runtime package store.
Synopsis
dotnet store -m|--manifest -f|--framework -r|--runtime [--framework-version] [-h|--help] [--output] [--skip-
optimization] [--skip-symbols] [-v|--verbosity] [--working-dir]
Description
dotnet store stores the specified assemblies in the runtime package store. By default, assemblies are optimized
for the target runtime and framework. For more information, see the runtime package store topic.
Required options
-f|--framework <FRAMEWORK>
The package store manifest file is an XML file that contains the list of packages to store. The format of the
manifest file is compatible with the csproj format. So, a csproj project file that references the desired packages can
be used with the -m|--manifest option to store assemblies in the runtime package store. To specify multiple
manifest files, repeat the option and path for each file: --manifest packages1.csproj --manifest packages2.csproj .
-r|--runtime <RUNTIME_IDENTIFIER>
Optional options
--framework-version <FRAMEWORK_VERSION>
Specifies the .NET Core SDK version. This option enables you to select a specific framework version beyond the
framework specified by the -f|--framework option.
-h|--help
Specifies the path to the runtime package store. If not specified, it defaults to the store subdirectory of the user
profile .NET Core installation directory.
--skip-optimization
Skips symbol generation. Currently, you can only generate symbols on Windows and Linux.
-v|--verbosity <LEVEL>
Sets the verbosity level of the command. Allowed values are q[uiet] , m[inimal] , n[ormal] , d[etailed] , and
diag[nostic] .
-w|--working-dir <INTERMEDIATE_WORKING_DIRECTORY>
The working directory used by the command. If not specified, it uses the obj subdirectory of the current directory.
Examples
Store the packages specified in the packages.csproj project file for .NET Core 2.0.0:
dotnet store --manifest packages.csproj --framework-version 2.0.0
See also
Runtime package store
dotnet test
8/15/2017 • 3 min to read • Edit Online
This topic applies to: ✓ .NET Core 1.x ✓ .NET Core 2.x
Name
dotnet test - .NET test driver used to execute unit tests.
Synopsis
.NET Core 2.x
.NET Core 1.x
Description
The dotnet test command is used to execute unit tests in a given project. Unit tests are console application
projects that have dependencies on the unit test framework (for example, MSTest, NUnit, or xUnit) and the dotnet
test runner for the unit testing framework. These are packaged as NuGet packages and are restored as ordinary
dependencies for the project.
Test projects also must specify the test runner. This is specified using an ordinary <PackageReference> element, as
seen in the following sample project file:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp1.1</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.0.0" />
<PackageReference Include="xunit" Version="2.2.0" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.2.0" />
</ItemGroup>
</Project>
Arguments
PROJECT
Options
.NET Core 2.x
.NET Core 1.x
-a|--test-adapter-path <PATH_TO_ADAPTER>
Use the custom test adapters from the specified path in the test run.
-c|--configuration {Debug|Release}
Defines the build configuration. The default value is Debug , but your project's configuration could override this
default SDK setting.
--collect <DATA_COLLECTOR_FRIENDLY_NAME>
Enables data collector for the test run. For more information, see Monitor and analyze test run.
-d|--diag <PATH_TO_DIAGNOSTICS_FILE>
Enables diagnostic mode for the test platform and write diagnostic messages to the specified file.
-f|--framework <FRAMEWORK>
Filters out tests in the current project using the given expression. For more information, see the Filter option
details section. For additional information and examples on how to use selective unit test filtering, see Running
selective unit tests.
-h|--help
The directory where the test results are going to be placed. The specified directory will be created if it doesn't
exist.
-s|--settings <SETTINGS_FILE>
Examples
Run the tests in the project in the current directory:
dotnet test
MSTest FullyQualifiedName
Name
ClassName
Priority
TestCategory
Xunit FullyQualifiedName
DisplayName
Traits
The <operator> describes the relationship between the property and the value:
OPERATOR FUNCTION
= Exact match
~ Contains
OPERATOR FUNCTION
| OR
OPERATOR FUNCTION
& AND
You can enclose expressions in paranthesis when using conditional operators (for example,
(Name~TestMethod1) | (Name~TestMethod2) ).
For additional information and examples on how to use selective unit test filtering, see Running selective unit
tests.
See also
Frameworks and Targets
.NET Core Runtime IDentifier (RID) catalog
dotnet vstest
8/15/2017 • 2 min to read • Edit Online
This topic applies to: ✓ .NET Core 1.x ✓ .NET Core 2.x
Name
dotnet-vstest - Runs tests from the specified files.
Synopsis
dotnet vstest [<TEST_FILE_NAMES>] [--Settings|/Settings] [--Tests|/Tests] [--TestAdapterPath|/TestAdapterPath]
[--Platform|/Platform] [--Framework|/Framework] [--Parallel|/Parallel] [--TestCaseFilter|/TestCaseFilter] [--
logger|/logger] [-lt|--ListTests|/lt|/ListTests] [--ParentProcessId|/ParentProcessId] [--Port|/Port] [--
Diag|/Diag] [[--] <args>...]] [-?|--Help|/?|/Help]
Description
The dotnet-vstest command runs the VSTest.Console command-line application to run automated unit and
coded UI application tests.
Arguments
TEST_FILE_NAMES
Run tests from the specified assemblies. Separate multiple test assembly names with spaces.
Options
--Settings|/Settings:<Settings File>
Run tests with names that match the provided values. Separate multiple values with commas.
--TestAdapterPath|/TestAdapterPath
Use custom test adapters from a given path (if any) in the test run.
--Platform|/Platform:<Platform type>
Target platform architecture used for test execution. Valid values are x86 , x64 , and ARM .
--Framework|/Framework:<Framework Version>
Target .NET Framework version used for test execution. Examples of valid values are .NETFramework,Version=v4.6 ,
.NETCoreApp,Version=v1.0 , etc. Other supported values are Framework35 , Framework40 , Framework45 , and
FrameworkCore10 .
--Parallel|/Parallel
Execute tests in parallel. By default, all available cores on the machine are available for use. Set an explicit number
of cores with a settings file.
--TestCaseFilter|/TestCaseFilter:<Expression>
Run tests that match the given expression. <Expression> is of the format
<property>Operator<value>[|&<Expression>] , where Operator is one of = , != , or ~ . Operator ~ has 'contains'
semantics and is applicable for string properties like DisplayName . Parenthesis () are used to group sub-
expressions.
-?|--Help|/?|/Help
/logger:TfsPublisher;
Collection=<team project collection url>;
BuildName=<build name>;
TeamProject=<team project name>
[;Platform=<Defaults to "Any CPU">]
[;Flavor=<Defaults to "Debug">]
[;RunTitle=<title>]
To log results to a Visual Studio Test Results File (TRX), use the trx logger provider. This switch creates a
file in the test results directory with given log file name. If LogFileName isn't provided, a unique file name is
created to hold the test results.
-lt|--ListTests|/lt|/ListTests:<File Name>
Process Id of the parent process responsible for launching the current process.
--Port|/Port:<Port>
Specifies the port for the socket connection and receiving the event messages.
--Diag|/Diag:<Path to log file>
Enables verbose logs for the test platform. Logs are written to the provided file.
args
Specifies extra arguments to pass to the adapter. Arguments are specified as name-value pairs of the form
<n>=<v> , where <n> is the argument name and <v> is the argument value. Use a space to separate multiple
arguments.
Examples
Run tests in mytestproject.dll :
dotnet vstest mytestproject.dll
Run tests in mytestproject.dll and myothertestproject.exe :
dotnet vstest mytestproject.dll myothertestproject.exe
This topic applies to: ✓ .NET Core 1.x ✓ .NET Core 2.x
Name
dotnet add reference - Adds project-to-project (P2P) references.
Synopsis
dotnet add [<PROJECT>] reference [-f|--framework] <PROJECT_REFERENCES> [-h|--help]
Description
The dotnet add reference command provides a convenient option to add project references to a project. After
running the command, the <ProjectReference> elements are added to the project file.
<ItemGroup>
<ProjectReference Include="app.csproj" />
<ProjectReference Include="..\lib2\lib2.csproj" />
<ProjectReference Include="..\lib1\lib1.csproj" />
</ItemGroup>
Arguments
PROJECT
Specifies the project file. If not specified, the command will search the current directory for one.
PROJECT_REFERENCES
Project-to-project (P2P) references to add. Specify one or more projects. Glob patterns are supported on
Unix/Linux-based systems.
Options
-h|--help
Examples
Add a project reference:
dotnet add app/app.csproj reference lib/lib.csproj
This topic applies to: ✓ .NET Core 1.x ✓ .NET Core 2.x
Name
dotnet list reference - Lists project to project references.
Synopsis
dotnet list [<PROJECT>] reference [-h|--help]
Description
The dotnet list reference command provides a convenient option to list project references for a given project.
Arguments
PROJECT
Specifies the project file to use for listing references. If not specified, the command will search the current directory
for a project file.
Options
-h|--help
Examples
List the project references for the specified project:
dotnet list app/app.csproj reference
List the project references for the project in the current directory:
dotnet list reference
dotnet remove reference
8/15/2017 • 1 min to read • Edit Online
This topic applies to: ✓ .NET Core 1.x ✓ .NET Core 2.x
Name
dotnet remove reference - Removes project-to-project references.
Synopsis
dotnet remove [<PROJECT>] reference [-f|--framework] <PROJECT_REFERENCES> [-h|--help]
Description
The dotnet remove reference command provides a convenient option to remove project references from a project.
Arguments
PROJECT
Target project file. If not specified, the command searches the current directory for one.
PROJECT_REFERENCES
Project to project (P2P references to remove. You can specify one or multiple projects. Glob patterns are supported
on Unix/Linux based terminals.
Options
-h|--help
Examples
Remove a project reference from the specified project:
dotnet remove app/app.csproj reference lib/lib.csproj
Remove multiple project references from the project in the current directory:
dotnet remove reference lib1/lib1.csproj lib2/lib2.csproj
This topic applies to: ✓ .NET Core 1.x ✓ .NET Core 2.x
Name
dotnet add package - Adds a package reference to a project file.
Synopsis
dotnet add [<PROJECT>] package <PACKAGE_NAME> [-h|--help] [-v|--version] [-f|--framework] [-n|--no-restore] [-
s|--source] [--package-directory]
Description
The dotnet add package command provides a convenient option to add a package reference to a project file. After
running the command, there's a compatibility check to ensure the package is compatible with the frameworks in
the project. If the check passes, a <PackageReference> element is added to the project file and dotnet restore is run.
For example, adding Newtonsoft.Json to ToDo.csproj produces output similar to the following example:
Writing C:\Users\mairaw\AppData\Local\Temp\tmp95A8.tmp
info : Adding PackageReference for package 'Newtonsoft.Json' into project 'C:\projects\ToDo\ToDo.csproj'.
log : Restoring packages for C:\projects\ToDo\ToDo.csproj...
info : GET https://api.nuget.org/v3-flatcontainer/newtonsoft.json/index.json
info : OK https://api.nuget.org/v3-flatcontainer/newtonsoft.json/index.json 235ms
info : Package 'Newtonsoft.Json' is compatible with all the specified frameworks in project
'C:\projects\ToDo\ToDo.csproj'.
info : PackageReference for package 'Newtonsoft.Json' version '10.0.3' added to file
'C:\projects\ToDo\ToDo.csproj'.
The ToDo.csproj file now contains a <PackageReference> element for the referenced package.
Arguments
PROJECT
Specifies the project file. If not specified, the command searches the current directory for one.
PACKAGE_NAME
Options
-h|--help
Adds a package reference without performing a restore preview and compatibility check.
-s|--source <SOURCE>
Examples
Add Newtonsoft.Json NuGet package to a project:
dotnet add package Newtonsoft.Json
This topic applies to: ✓ .NET Core 1.x ✓ .NET Core 2.x
Name
dotnet remove package - Removes package reference from a project file.
Synopsis
dotnet remove [<PROJECT>] package <PACKAGE_NAME> [-h|--help]
Description
The dotnet remove package command provides a convenient option to remove a NuGet package reference from a
project.
Arguments
PROJECT
Specifies the project file. If not specified, the command will search the current directory for one.
PACKAGE_NAME
Options
-h|--help
Examples
Removes Newtonsoft.Json NuGet package from a project in the current directory:
dotnet remove package Newtonsoft.Json
global.json reference
7/29/2017 • 1 min to read • Edit Online
The global.json file allows selection of the .NET Core tools version being used through the sdk property.
.NET Core CLI tools look for this file in the current working directory (which isn't necessarily the same as the
project directory) or one of its parent directories.
sdk
Type: Object
Specifies information about the SDK.
version
Type: String
The version of the SDK to use.
For example:
{
"sdk": {
"version": "1.0.0-preview2-003121"
}
}
Porting to .NET Core from .NET Framework
8/5/2017 • 1 min to read • Edit Online
If you've got code running on the .NET Framework, you may be interested in running your code on .NET Core 1.0.
This article covers an overview of the porting process and a list of the tools you may find helpful when porting to
.NET Core.
Tools to help
Here's a short list of the tools you'll find helpful:
NuGet - Nuget Client or NuGet Package Explorer, Microsoft's package manager for .NET implementations.
Api Portability Analyzer - command line tool or Visual Studio Extension, a toolchain that can generate a report
of how portable your code is between .NET Framework and .NET Core, with an assembly-by-assembly
breakdown of issues. See Tooling to help you on the process for more information.
Reverse Package Search - A useful web service that allows you to search for a type and find packages
containing that type.
Next steps
Analyzing your third-party dependencies.
Organizing your project to support .NET Framework
and .NET Core
7/29/2017 • 2 min to read • Edit Online
This article helps project owners who want to compile their solution against .NET Framework and .NET Core side-
by-side. It provides several options to organize projects to help developers achieve this goal. The following list
provides some typical scenarios to consider when you're deciding how to setup your project layout with .NET Core.
The list may not cover everything you want; prioritize based on your project's needs.
Combine existing projects and .NET Core projects into single projects
What this is good for:
Simplifying your build process by compiling a single project rather than compiling multiple projects, each
targeting a different .NET Framework version or platform.
Simplifying source file management for multi-targeted projects because you must manage a single
project file. When adding/removing source files, the alternatives require you to manually sync these with
your other projects.
Easily generating a NuGet package for consumption.
Allows you to write code for a specific .NET Framework version in your libraries through the use of
compiler directives.
Unsupported scenarios:
Requires developers to use Visual Studio 2017 to open existing projects. To support older versions of
Visual Studio, keeping your project files in different folders is a better option.
Keep existing projects and new .NET Core projects separate
What this is good for:
Continuing to support development on existing projects without having to upgrade for
developers/contributors who may not have Visual Studio 2017.
Decreasing the possibility of creating new bugs in existing projects because no code churn is required in
those projects.
Example
Consider the repository below:
Source Code
The following describes several ways to add support for .NET Core for this repository depending on the constraints
and complexity of the existing projects.
Source Code
Changes to note are:
Replacement of packages.config and \.csproj* with a new .NET Core \.csproj*. NuGet packages are specified with
<PackageReference> ItemGroup .
See Also
Please see the .NET Core porting documentation for more guidance on migrating to .NET Core.
Porting to .NET Core - Analyzing your Third-Party
Party Dependencies
7/29/2017 • 3 min to read • Edit Online
The first step in the porting process is to understand your third party dependencies. You need to figure out which
of them, if any, don't yet run on .NET Core, and develop a contingency plan for those which don't run on .NET Core.
Prerequisites
This article will assume you are using Windows and Visual Studio, and that you have code which runs on the .NET
Framework today.
netstandard1.0
netstandard1.1
netstandard1.2
netstandard1.3
netstandard1.4
netstandard1.5
netstandard1.6
netcoreapp1.0
portable-net45-win8
portable-win8-wpa8
portable-net451-win81
portable-net45-win8-wpa8-wpa81
These are the Target Framework Monikers (TFM) which map to versions of the .NET Standard and traditional
Portable Class Library (PCL) profiles which are compatible with .NET Core. Note that netcoreapp1.0 , while
compatible, is for applications and not libraries. Although there's nothing wrong with using a library which is
netcoreapp1.0 -based, that library may not be intended for anything other than consumption by other
netcoreapp1.0 applications.
There are also some legacy TFMs used in pre-release versions of .NET Core that may also be compatible:
dnxcore50
dotnet5.0
dotnet5.1
dotnet5.2
dotnet5.3
dotnet5.4
dotnet5.5
While these will likely work with your code, there is no guarantee of compatibility. Packages with these
TFMs were built with pre-release .NET Core packages. Take note of when (or if) packages like this are updated to be
netstandard -based.
NOTE
To use a package targeting a traditional PCL or pre-release .NET Core target, you must use the imports directive in your
project.json file.
What to do when your NuGet package dependency doesn't run on .NET Core
There are a few things you can do if a NuGet package you depend on won't run on .NET Core.
1. If the project is open source and hosted somewhere like GitHub, you can engage the developer(s) directly.
2. You can contact the author directly on nuget.org by searching for the package and clicking "Contact Owners" on
the left hand side of the package's page.
3. You can look for another package that runs on .NET Core which accomplishes the same task as the package you
were using.
4. You can attempt to write the code the package was doing yourself.
5. You could eliminate the dependency on the package by changing the functionality of your app, at least until a
compatible version of the package becomes available.
Please remember that open source project maintainers and NuGet package publishers are often volunteers who
contribute because they care about a given domain, do it for free, and often have a different daytime job. If you do
reach out, you might start with a positive statement about the library before asking about .NET Core support.
If you're unable to resolve your issue with any of the above, you may have to port to .NET Core at a later date.
The .NET Team would like to know which libraries are the most important to support next with .NET Core. You can
also send us mail at [email protected] about the libraries you'd like to use.
Next steps
If you're porting a library, check out Porting your Libraries.
Porting to .NET Core - Libraries
8/5/2017 • 10 min to read • Edit Online
This article discusses porting library code to .NET Core so that it runs cross-platform.
Prerequisites
This article assumes that you:
Are using Visual Studio 2017 or later. .NET Core isn't supported on earlier versions of Visual Studio.
Understand the recommended porting process.
Have resolved any issues with third-party dependencies.
You should also become familiar with the content of the following topics:
.NET Standard
This topic describes the formal specification of .NET APIs that are intended to be available on all .NET
implementations.
Packages, Metapackages and Frameworks
This article discusses how .NET Core defines and uses packages and how packages support code running on
multiple .NET implementations.
Developing Libraries with Cross Platform Tools
This topic explains how to write libraries for .NET using cross-platform CLI tools.
Additions to the csproj format for .NET Core
This article outlines the changes that were added to the project file as part of the move to csproj and MSBuild.
Porting to .NET Core - Analyzing your Third-Party Party Dependencies
This topic discusses the portability of third-party dependencies and what to do when a NuGet package dependency
doesn't run on .NET Core.
{
"sdk": {
"version": "2.1.0-preview1-006491"
}
}
The ability to build .NET Core from its source code is important in multiple ways: it makes it easier to port .NET Core
to new platforms, it enables contributions and fixes to the product, and it enables the creation of custom versions of
.NET. This article gives guidance to developers who want to build and distribute their own versions of .NET Core.
Installing the components differ depending on the operating system (OS). See the build instructions for your
specific OS:
Windows
Linux
macOS
FreeBSD
NetBSD
There is no cross-building across OS (only for ARM, which is built on X64).
You have to be on the particular platform to build that platform.
The build has two main buildTypes :
Debug (default)- Compiles the runtime with minimal optimizations and additional runtime checks (asserts). This
reduction in optimization level and the additional checks slow runtime execution but are valuable for debugging.
This is the recommended setting for development and testing environments.
Release - Compiles the runtime with full optimizations and without the additional runtime checks. This will yield
much faster run time performance but it can take a bit longer to build and can be difficult to debug. Pass
release to the build script to select this build type.
In addition, by default the build not only creates the runtime executables, but it also builds all the tests. There are
quite a few tests, taking a significant amount of time that isn't necessary if you just want to experiment with
changes. You can skip the tests builds by adding the skiptests argument to the build script, like in the following
example (replace .\build with ./build.sh on Unix machines):
.\build skiptests
The previous example showed how to build the Debug flavor, which has development time checks (asserts)
enabled and optimizations disabled. To build the release (full speed) flavor, do the following:
.\build release skiptests
You can find more build options with build by using the -? or -help qualifier.
Using Your Build
The build places all of its generated files under the bin directory at the base of the repository. There is a bin\Log
directory that contains log files generated during the build (Most useful when the build fails). The actual output is
placed in a bin\Product[platform].[CPU architecture].[build type] directory, such as
bin\Product\Windows_NT.x64.Release.
While the 'raw' output of the build is sometimes useful, normally you're only interested in the NuGet packages,
which are placed in the .nuget\pkg subdirectory of the previous output directory.
There are two basic techniques for using your new runtime:
1. Use dotnet.exe and NuGet to compose an application. See Using Your Build for instructions on creating
a program that uses your new runtime by using the NuGet packages you just created and the 'dotnet'
command-line interface (CLI). This technique is the expected way non-runtime developers are likely to
consume your new runtime.
2. Use corerun.exe to run an application using unpackaged DLLs. This repository also defines a simple
host called corerun.exe that does NOT take any dependency on NuGet. You need to tell the host where to get
the required DLLs you actually use, and you have to manually gather them together. This technique is used
by all the tests in the CoreCLR repo, and is useful for quick local 'edit-compile-debug' loop such as
preliminary unit testing. See Executing .NET Core Apps with CoreRun.exe for details on using this technique.
See also
.NET Core Common Language Runtime (CoreCLR)
.NET Core CLI Developer Guide
.NET Core distribution packaging
.NET Core distribution packaging
7/12/2017 • 3 min to read • Edit Online
As .NET Core becomes available on more and more platforms, it's useful to learn how to package, name, and
version it. This way, package maintainers can help ensure a consistent experience no matter where users choose to
run .NET.
Preview versions
Package maintainers may decide to include preview versions of the shared framework and SDK. Those should
never be included in the unversioned dotnet-sdk package, but may be released as versioned packages with an
additional preview marker appended to the major and minor version sections of the name. For example, there may
be a dotnet-sdk-2.0-preview-final package.
Optional additional packages
Some maintainers may choose to provide additional packages such as:
dotnet-lts : the latest Long-Term Support (LTS) version of the shared framework. LTS and Current release
trains correspond to different cadences at which .NET Core gets released. Users have a choice of adopting one
or the other train, based on how often they are willing to update. This is a concept that is also tied to support
levels, so it may or may not make sense depending on the distro being considered.
Disk layout
When installing .NET Core packages, the relative placement of their target destinations on disk matter. The
dotnet.exe host should be placed next to sdk and shared folders that contain the versioned contents of the
dotnet-sdk SDK packages, and dotnet-runtime shared framework packages.
The disk layout of files and directories inside the packages is versioned. This means that updating to the latest
dotnet-runtime installs the new version side by side with previous versions, reducing the possibility of breaking
existing applications by updating the package. Package updates should not remove previous versions.
Update policies
When an update is performed, the behavior of each package is as follows:
dotnet-runtime-[major].[minor] : new patch versions update the package, but new minor or major versions are
separate packages.
dotnet-sdk : update rolls forward major, minor, and patch versions.
dotnet-sdk-[major].[minor] : new patch versions update the package, but new minor or major versions are
separate packages.
dotnet-lts : update rolls forward major, minor, and patch versions.
This topic has presented our recommendations for packaging .NET Core, however each distro is free to choose
what versions to offer and when. For example, a distro that values stability more than being up-to-date may
choose to release only versions that snap with the LTS release train.
project.json and Visual Studio 2015 with .NET Core
7/29/2017 • 1 min to read • Edit Online
On March 7, 2017, the .NET Core and ASP.NET Core documentation was updated for the release of Visual Studio
2017. The previous version of the documentation used Visual Studio 2015 and pre-release tooling based on the
project.json file.
The documentation version from before the March 7 update is available in a PDF file and in a branch in the
documentation repository.
PDF files
The best source of the earlier documentation is PDF files:
.NET Core - PDF for project.json and Visual Studio 2015
ASP.NET Core - PDF for project.json and Visual Studio 2015
NOTE
This .NET Framework content set includes information for .NET Framework versions 4.5, 4.5.1, 4.5.2, 4.6, 4.6.1, 4.6.2, and
4.7. To download the .NET Framework, see Installing the .NET Framework. For a list of new features and changes in the NET
Framework 4.5, the .NET Framework 4.6, their point releases, and the .NET Framework 4.7, see What's New in the .NET
Framework. For a list of supported platforms, see .NET Framework System Requirements.
The .NET Framework is a development platform for building apps for web, Windows, Windows Phone, Windows
Server, and Microsoft Azure. It consists of the common language runtime (CLR) and the .NET Framework class
library, which includes a broad range of functionality and support for many industry standards.
The .NET Framework provides many services, including memory management, type and memory safety, security,
networking, and application deployment. It provides easy-to-use data structures and APIs that abstract the lower-
level Windows operating system. You can use a variety of programming languages with the .NET Framework,
including C#, F#, and Visual Basic.
For a general introduction to the .NET Framework for both users and developers, see Getting Started. For an
introduction to the architecture and key features of the .NET Framework, see the overview.
The .NET Framework can be used with Docker and with Windows Containers. See Deploying .NET Framework
applications with Docker to learn how to run your applications in Docker containers.
Installation
The .NET Framework comes with Windows, enabling you to run .NET Framework applications. You may need a
later version of the .NET Framework than comes with your Windows version. For more information, see Install the
.NET Framework on Windows.
See Repair the .NET Framework to learn how to repair your .NET Framework installation if you are experiencing
errors when installing the .NET Framework.
For more detailed information on downloading the .NET Framework, see Install the .NET Framework for
developers.
In This Section
What's New
Describes key new features and changes in the latest versions of the .NET Framework. Includes lists of obsolete
types and members, and provides a guide for migrating your applications from the previous version of the .NET
Framework.
Getting Started
Provides a comprehensive overview of the .NET Framework and links to additional resources.
Migration Guide
Provides resources and a list of changes you need to consider if you're migrating your application to a new
version of the .NET Framework.
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.
Tools
Describes the tools that help you develop, configure, and deploy applications by using .NET Framework
technologies.
.NET Framework Class Library
Supplies syntax, code examples, and related information for each class contained in the .NET Framework
namespaces.
Additional Class Libraries and APIs
Provides documentation for classes contained in out of band (OOB) releases, as well as for classes that target
specific platforms or implementations of the .NET Framework.
What's new in the .NET Framework
8/5/2017 • 65 min to read • Edit Online
This article summarizes key new features and improvements in the following versions of the .NET Framework:
.NET Framework 4.7
.NET Framework 4.6.2
.NET Framework 4.6.1
.NET 2015 and .NET Framework 4.6
.NET Framework 4.5.2
.NET Framework 4.5.1
.NET Framework 4.5
This article does not provide comprehensive information about each new feature and is subject to change. For general information about the .NET
Framework, see Getting Started. For supported platforms, see System Requirements. For download links and installation instructions, see Installation
Guide.
NOTE
The .NET Framework team also releases features out of band with NuGet to expand platform support and to introduce new functionality, such as immutable collections
and SIMD-enabled vector types. For more information, see Additional Class Libraries and APIs and The .NET Framework and Out-of-Band Releases. See a complete list
of NuGet packages for the .NET Framework, or subscribe to our feed.
<runtime>
<AppContextSwitchOverrides
value="Switch.System.ServiceModel.DisableUsingServicePointManagerSecurityProtocols=false;Switch.System.Net.DontEnableSchUseStrongCrypto=false" />
</runtime>
You can then create a resource file, DataAnnotation.Localization.fr.resx, whose key is the error message string and whose value is the localized error
message. The file must be found in the App.LocalResources folder. For example, the following is the key and its value in a localized French (fr) language
error message:
NAME VALUE
The rating must be between 1 and 10. La note doit être comprise entre 1 et 10.
In addition, the SessionStateUtility class includes two new methods, IsSessionStateReadOnly and IsSessionStateRequired, that can be used to support
asynchronous operations.
Async support for output-cache providers Starting with the .NET Framework 4.6.2, task-returning methods can be used with output-cache providers
to provide the scalability benefits of async. Providers that implement these methods reduce thread-blocking on a web server and improve the scalability
of an ASP.NET service.
The following APIs have been added to support asynchronous output-cache providers:
The System.Web.Caching.OutputCacheProviderAsync class, which inherits from System.Web.Caching.OutputCacheProvider and allows
developers to implement an asynchronous output-cache provider.
The OutputCacheUtility class, which provides helper methods for configuring the output cache.
18 new methods in the System.Web.HttpCachePolicyclass. These include GetCacheability, GetCacheExtensions, GetETag,
GetETagFromFileDependencies, GetMaxAge, GetMaxAge, GetNoStore, GetNoTransforms, GetOmitVaryStar, GetProxyMaxAge, GetRevalidation,
GetUtcLastModified, GetVaryByCustom, HasSlidingExpiration, and IsValidUntilExpires.
2 new methods in the System.Web.HttpCacheVaryByContentEncodings class: GetContentEncodings and SetContentEncodings.
2 new methods in the System.Web.HttpCacheVaryByHeaders class: GetHeaders and SetHeaders.
2 new methods in the System.Web.HttpCacheVaryByParams class: GetParams and SetParams.
In the System.Web.Caching.AggregateCacheDependency class, the GetFileDependencies method.
In the CacheDependency, the GetFileDependencies method.
Character categories
Characters in the .NET Framework 4.6.2 are classified based on the Unicode Standard, Version 8.0.0. In .NET Framework 4.6 and .NET Framework 4.6.1,
characters were classified based on Unicode 6.3 character categories.
Support for Unicode 8.0 is limited to the classification of characters by the CharUnicodeInfo class and to types and methods that rely on it. These include
the StringInfo class, the overloaded System.Char.GetUnicodeCategory method, and the character classes recognized by the .NET Framework regular
expression engine. Character and string comparison and sorting is unaffected by this change and continues to rely on the underlying operating system
or, on Windows 7 systems, on character data provided by the .NET Framework.
For changes in character categories from Unicode 6.0 to Unicode 7.0, see The Unicode Standard, Version 7.0.0 at The Unicode Consortium website. For
changes from Unicode 7.0 to Unicode 8.0, see The Unicode Standard, Version 8.0.0 at The Unicode Consortium website.
Cryptography
Support for X509 certificates containing FIPS 186-3 DSA The .NET Framework 4.6.2 adds support for DSA (Digital Signature Algorithm) X509
certificates whose keys exceed the FIPS 186-2 1024-bit limit.
In addition to supporting the larger key sizes of FIPS 186-3, the .NET Framework 4.6.2 allows computing signatures with the SHA-2 family of hash
algorithms (SHA256, SHA384, and SHA512). FIPS 186-3 support is provided by the new System.Security.Cryptography.DSACng class.
In keeping with recent changes to the RSA class in the .NET Framework 4.6 and the ECDsa class in the .NET Framework 4.6.1, the DSA abstract base class
in .NET Framework 4.6.2 has additional methods to allow callers to use this functionality without casting. You can call the
System.Security.Cryptography.X509Certificates.DSACertificateExtensions.GetDSAPrivateKey extension method to sign data, as the following example
shows.
Public Shared Function VerifyDataDsaSha384(data As Byte(), signature As Byte(), cert As X509Certificate2) As Boolean
Using dsa As DSA = cert.GetDSAPublicKey()
Return dsa.VerifyData(data, signature, HashAlgorithmName.SHA384)
End Using
End Function
Increased clarity for inputs to ECDiffieHellman key derivation routines The .NET Framework 3.5 added support for Ellipic Curve Diffie-Hellman
Key Agreement with three different Key Derivation Function (KDF) routines. The inputs to the routines, and the routines themselves, were configured via
properties on the ECDiffieHellmanCng object. But since not every routine read every input property, there was ample room for confusion on the past of
the developer.
To address this in the .NET Framework 4.6.2, the following three methods have been added to the ECDiffieHellman base class to more clearly represent
these KDF routines and their inputs:
DeriveKeyFromHash(ECDiffieHellmanPublicKey, HashAlgorithmName, Byte[], Byte[]) Derives key material using the formula
HASH(secretPrepend || x || secretAppend)
DeriveKeyFromHmac(ECDiffieHellmanPublicKey, HashAlgorithmName, Byte[], Byte[], Derives key material using the formula
Byte[])
HMAC(hmacKey, secretPrepend || x || secretAppend)
DeriveKeyTls(ECDiffieHellmanPublicKey, Byte[], Byte[]) Derives key material using the TLS pseudo-random function (PRF) derivation
algorithm.
Support for persisted-key symmetric encryption The Windows cryptography library (CNG) added support for storing persisted symmetric keys and
using hardware-stored symmetric keys, and the .NET Framework 4.6.2 mades it possible for developers to make use of this feature. Since the notion of
key names and key providers is implementation-specific, using this feature requires utilizing the constructor of the concrete implementation types
instead of the preferred factory approach (such as calling Aes.Create ).
Persisted-key symmetric encryption support exists for the AES (AesCng) and 3DES (TripleDESCng) algorithms. For example:
// Using the zero-argument overload is required to make use of the persisted key
using (ICryptoTransform encryptor = aes.CreateEncryptor())
{
if (!encryptor.CanTransformMultipleBlocks)
{
throw new InvalidOperationException("This is a sample, this case wasn’t handled...");
}
' Using the zero-argument overload Is required to make use of the persisted key
Using encryptor As ICryptoTransform = Aes.CreateEncryptor()
If Not encryptor.CanTransformMultipleBlocks Then
Throw New InvalidOperationException("This is a sample, this case wasn’t handled...")
End If
Return encryptor.TransformFinalBlock(data, 0, data.Length)
End Using
End Using
End Function
SignedXml support for SHA-2 hashing The .NET Framework 4.6.2 adds support to the SignedXml class for RSA-SHA256, RSA-SHA384, and RSA-
SHA512 PKCS#1 signature methods, and SHA256, SHA384, and SHA512 reference digest algorithms.
The URI constants are all exposed on SignedXml:
XmlDsigSHA256Url "http://www.w3.org/2001/04/xmlenc#sha256"
XmlDsigRSASHA256Url "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"
XmlDsigSHA384Url "http://www.w3.org/2001/04/xmldsig-more#sha384"
XmlDsigRSASHA384Url "http://www.w3.org/2001/04/xmldsig-more#rsa-sha384"
XmlDsigSHA512Url "http://www.w3.org/2001/04/xmlenc#sha512"
XmlDsigRSASHA512Url "http://www.w3.org/2001/04/xmldsig-more#rsa-sha512"
Any programs that have registered a custom SignatureDescription handler into CryptoConfig to add support for these algorithms will continue to
function as they did in the past, but since there are now platform defaults, the CryptoConfig registration is no longer necessary.
SqlClient
.NET Framework Data Provider for SQL Server (System.Data.SqlClient) includes the following new features in the .NET Framework 4.6.2:
Connection pooling and timeouts with Azure SQL databases When connection pooling is enabled and a timeout or other login error occurs, an
exception is cached, and the cached exception is thrown on any subsequent connection attempt for the next 5 seconds to 1 minute. For more details, see
SQL Server Connection Pooling (ADO.NET).
This behavior is not desirable when connecting to Azure SQL Databases, since connection attempts can fail with transient errors that are typically
recovered quickly. To better optimize the connection retry experience, the connection pool blocking period behavior is removed when connections to
Azure SQL Databases fail.
The addition of the new PoolBlockingPeriod keyword lets you to select the blocking period best suited for your app. Values include:
Auto The connection pool blocking period for an application that connects to an Azure SQL Database is disabled, and the connection pool blocking
period for an application that connects to any other SQL Server instance is enabled. This is the default value. If the Server endpoint name ends with any
of the following, they are considered Azure SQL Databases:
.database.windows.net
.database.chinacloudapi.cn
.database.usgovcloudapi.net
.database.cloudapi.de
AlwaysBlock The connection pool blocking period is always enabled.
NeverBlock The connection pool blocking period is always disabled.
Enhancements for Always Encrypted SQLClient introduces two enhancements for Always Encrypted:
To improve performance of parameterized queries against encrypted database columns, encryption metadata for query parameters is now
cached. With the System.Data.SqlClient.SqlConnection.ColumnEncryptionQueryMetadataCacheEnabled property set to true (which is the default
value), if the same query is called multiple times, the client retrieves parameter metadata from the server only once.
Column encryption key entries in the key cache are now evicted after a configurable time interval, set using the
System.Data.SqlClient.SqlConnection.ColumnEncryptionKeyCacheTtl property.
Windows Communication Foundation
In the .NET Framework 4.6.2, Windows Communication Foundation has been enhanced in the following areas:
WCF transport security support for certificates stored using CNG WCF transport security supports certificates stored using the Windows
cryptography library (CNG). In the .NET Framework 4.6.2, this support is limited to using certificates with a public key that has an exponent no more than
32 bits in length. When an application targets the .NET Framework 4.6.2, this feature is on by default.
For applications that target the .NET Framework 4.6.1 and earlier but are running on the .NET Framework 4.6.2, this feature can be enabled by adding
the following line to the <runtime> section of the app.config or web.config file.
<AppContextSwitchOverrides
value="Switch.System.ServiceModel.DisableCngCertificates=false"
/>
This can also be done programmatically with code like the following:
Better support for multiple daylight saving time adjustment rules by the DataContractJsonSerializer class Customers can use an application
configuration setting to determine whether the DataContractJsonSerializer class supports multiple adjustment rules for a single time zone. This is an
opt-in feature. To enable it, add the following setting to your app.config file:
<runtime>
<AppContextSwitchOverrides value="Switch.System.Runtime.Serialization.DoNotUseTimeZoneInfo=false" />
</runtime>
When this feature is enabled, a DataContractJsonSerializer object uses the TimeZoneInfo type instead of the TimeZone type to deserialize date and time
data. TimeZoneInfo supports multiple adjustment rules, which makes it possible to work with historic time zone data; TimeZone does not.
For more information on the TimeZoneInfo structure and time zone adjustments, see Time Zone Overview.
Support for preserving a UTC time when serializing and deserializing with the XMLSerializer class Ordinarily, when the XmlSerializer class is
used to serialize a UTC DateTime value, it creates a serialized time string that preserves the date and time but assumes the time is local. For example, if
you instantiate a UTC date and time by calling the following code:
The result is the serialized time string "03:00:00.0000000-08:00" for a system eight hours behind UTC. And serialized values are always deserialized as
local date and time values.
You can use an application configuration setting to determine whether the XmlSerializer preserves UTC time zone information when serializing and
deserializing DateTime values:
<runtime>
<AppContextSwitchOverrides
value="Switch.System.Runtime.Serialization.DisableSerializeUTCDateTimeToTimeAndDeserializeUTCTimeToUTCDateTime=false" />
</runtime>
When this feature is enabled, a DataContractJsonSerializer object uses the TimeZoneInfo type instead of the TimeZone type to deserialize date and time
data. TimeZoneInfo supports multiple adjustment rules, which makes it possible to work with historic time zone data; TimeZone does not.
For more information on the TimeZoneInfo structure and time zone adjustments, see Time Zone Overview.
NetNamedPipeBinding best match WCF has a new app setting that can be set on client applications to ensure they always connect to the service
listening on the URI that best matches the one that they request. With this app setting set to false (the default), it is possible for clients using
NetNamedPipeBinding to attempt to connect to a service listening on a URI that is a substring of the requested URI.
For example, a client tries to connect to a service listening at net.pipe://localhost/Service1 , but a different service on that machine running with
administrator privilege is listening at net.pipe://localhost . With this app setting set to false , the client would attempt to connect to the wrong service.
After setting the app setting to true , the client will always connect to the best matching service.
NOTE
Clients using NetNamedPipeBinding find services based on the service's base address (if it exists) rather than the full endpoint address. To ensure this setting always
works the service should use a unique base address.
To enable this change, add the following app setting to your client application's App.config or Web.config file:
<configuration>
<appSettings>
<add key="wcf:useBestMatchNamedPipeUri" value="true" />
</appSettings>
</configuration>
SSL 3.0 is not a default protocol When using NetTcp with transport security and a credential type of certificate, SSL 3.0 is no longer a default protocol
used for negotiating a secure connection. In most cases, there should be no impact to existing apps, because TLS 1.0 is included in the protocol list for
NetTcp. All existing clients should be able to negotiate a connection using at least TLS 1.0. If Ssl3 is required, use one of the following configuration
mechanisms to add it to the list of negotiated protocols.
The System.ServiceModel.Channels.SslStreamSecurityBindingElement.SslProtocols property
The System.ServiceModel.TcpTransportSecurity.SslProtocols property
The <transport> section of the <netTcpBinding> section
The <sslStreamSecurity> section of the <customBinding> section
Windows Presentation Foundation (WPF)
In the .NET Framework 4.6.2, Windows Presentation Foundation has been enhanced in the following areas:
Group sorting An application that uses a CollectionView object to group data can now explicitly declare how to sort the groups. Explicit sorting
addresses the problem of non-intuitive ordering that occurs when an app dynamically adds or removes groups, or when it changes the value of item
properties involved in grouping. It can also improve the performance of the group creation process by moving comparisons of the grouping properties
from the sort of the full collection to the sort of the groups.
To support group sorting, the new System.ComponentModel.GroupDescription.SortDescriptions and
System.ComponentModel.GroupDescription.CustomSort properties describe how to sort the collection of groups produced by the GroupDescription
object. This is analogous to the way the identically named ListCollectionView properties describe how to sort the data items.
Two new static properties of the PropertyGroupDescription class, CompareNameAscending and CompareNameDescending, can be used for the most
common cases.
For example, the following XAML groups data by age, sort the age groups in ascending order, and group the items within each age group by last name.
<GroupDescriptions>
<PropertyGroupDescription
PropertyName="Age"
CustomSort=
"{x:Static PropertyGroupDescription.CompareNamesAscending}"/>
</PropertyGroupDescription>
</GroupDescriptions>
<SortDescriptions>
<SortDescription PropertyName="LastName"/>
</SortDescriptions>
Soft keyboard support Soft Keyboard support enables focus tracking in a WPF applications by automatically invoking and dismissing the new Soft
Keyboard in Windows 10 when the touch input is received by a control that can take textual input.
In previous versions of the .NET Framework, WPF applications cannot opt into the focus tracking without disabling WPF pen/touch gesture support. As a
result, WPF applications must choose between full WPF touch support or rely on Windows mouse promotion.
Per-monitor DPI To support the recent proliferation of high-DPI and hybrid-DPI environments for WPF apps, WPF in the .NET Framework 4.6.2 enables
per-monitor awareness. See the samples and developer guide on GitHub for more information about how to enable your WPF app to become per-
monitor DPI aware.
In previous versions of the .NET Framework, WPF apps are system-DPI aware. In other words, the application's UI is scaled by the OS as appropriate,
depending on the DPI of the monitor on which the app is rendered. ,
For apps running under the .NET Framework 4.6.2, you can disable per-monitor DPI changes in WPF apps by adding a configuration statement to the
<runtime> section of your application configuration file, as follows:
<runtime>
<AppContextSwitchOverrides value="Switch.System.Windows.DoNotScaleForDpiChanges=false"/>
</runtime>
If this scenario is not enabled, running the application continues to generate an exception with the message, "This implementation is not part of the
Windows Platform FIPS validated cryptographic algorithms."
Workflow Improvements when using Dynamic Update with Visual Studio Workflow Designer The Workflow Designer, FlowChart Activity
Designer, and other Workflow Activity Designers now successfully load and display workflows that have been saved after calling the
System.Activities.DynamicUpdate.DynamicUpdateServices.PrepareForUpdate method. In versions of the .NET Framework before the .NET Framework
4.6.2, loading a XAML file in Visual Studio for a workflow that has been saved after calling
System.Activities.DynamicUpdate.DynamicUpdateServices.PrepareForUpdate can result in the following issues:
The Workflow Designer can't load the XAML file correctly (when the System.Activities.Presentation.ViewState.ViewStateData.Id is at the end of the
line).
Flowchart Activity Designer or other Workflow Activity Designers may display all objects in their default locations as opposed to attached
property values.
ClickOnce
ClickOnce has been updated to support TLS 1.1 and TLS 1.2 in addition to the 1.0 protocol, which it already supports. ClickOnce automatically detects
which protocol is required; no extra steps within the ClickOnce application are required to enable TLS 1.1 and 1.2 support.
Converting Windows Forms and WPF apps to UWP apps
Windows now offers capabilities to bring existing Windows desktop apps, including WPF and Windows Forms apps, to the Universal Windows Platform
(UWP). This technology acts as a bridge by enabling you to gradually migrate your existing code base to UWP, thereby bringing your app to all Windows
10 devices.
Converted desktop apps gain an app identity similar to the app identity of UWP apps, which makes UWP APIs accessible to enable features such as Live
Tiles and notifications. The app continues to behave as before and runs as a full trust app. Once the app is converted, an app container process can be
added to the existing full trust process to add an adaptive user interface. When all functionality is moved to the app container process, the full trust
process can be removed and the new UWP app can be made available to all Windows 10 devices.
Debugging improvements
The unmanaged debugging API has been enhanced in the .NET Framework 4.6.2 to perform additional analysis when a NullReferenceException is
thrown so that it is possible to determine which variable in a single line of source code is null . To support this scenario, the following APIs have been
added to the unmanaged debugging API.
The ICorDebugCode4, ICorDebugVariableHome, and ICorDebugVariableHomeEnum interfaces, which expose the native homes of managed
variables. This enables debuggers to do some code flow analysis when a NullReferenceException occurs and to work backwards to determine the
managed variable that corresponds to the native location that was null .
The ICorDebugType2::GetTypeID method provides a mapping for ICorDebugType to COR_TYPEID, which allows the debugger to obtain a
COR_TYPEID without an instance of the ICorDebugType. Existing APIs on COR_TYPEID can then be used to determine the class layout of the type.
using System;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
Imports System
Imports System.Security.Cryptography
Imports System.Security.Cryptography.X509Certificates
This offers a marked contrast to the code needed to generate a signature in the .NET Framework 4.6.
using System;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
ADO.NET
The following have been added to ADO.NET:
Always Encrypted support for hardware protected keys ADO.NET now supports storing Always Encrypted column master keys natively in Hardware
Security Modules (HSMs). With this support, customers can leverage asymmetric keys stored in HSMs without having to write custom column master
key store providers and registering them in applications.
Customers need to install the HSM vendor-provided CSP provider or CNG key store providers on the app servers or client computers in order to access
Always Encrypted data protected with column master keys stored in a HSM.
Improve MultiSubnetFailover connection behavior for AlwaysOn SqlClient now automatically provides faster connection to an AlwaysOn Availability
Group (AG). It transparently detects whether your application is connecting to an AlwaysOn availability group (AG) on a different subnet and quickly
discovers the current active server and provides a connection to the server. Prior to this release, an application had to set the connection string to
include "MultisubnetFailover=true" to indicate that it was connecting to an AlwaysOn Availability Group. Without setting the connection keyword to
true , an application might experience a timeout while connecting to an AlwaysOn Availability Group. With this release, an application does not need to
set MultiSubnetFailover to true anymore. For more information about SqlClient support for Always On Availability Groups, see SqlClient Support for
High Availability, Disaster Recovery.
Windows Presentation Foundation (WPF)
Windows Presentation Foundation includes a number of improvements and changes.
Improved performance The delay in firing touch events has been fixed in the .NET Framework 4.6.1. In addition, typing in a RichTextBox control no
longer ties up the render thread during fast input.
Spell checking improvements The spell checker in WPF has been updated on Windows 8.1 and later versions to leverage operating system support for
spell-checking additional languages. There is no change in functionality on Windows versions prior to Windows 8.1.
As in previous versions of the .NET Framework, the language for a TextBox control ora RichTextBox block is detected by looking for information in the
following order:
xml:lang , if it is present.
Current input language.
Current thread culture.
For additional information on language support in WPF, see the WPF blog post on .NET Framework 4.6.1 features.
Additional support for per-user custom dictionaries In .NET Framework 4.6.1, WPF recognizes custom dictionaries that are registered globally. This
capability is available in addition to the ability to register them per-control.
In previous versions of WPF, custom dictionaries did not recognize Excluded Words and AutoCorrect lists. They are supported on Windows 8.1 and
Windows 10 through the use of files that can be placed under the %AppData%\Microsoft\Spelling\<language tag> directory. The following rules apply to
these files:
The files should have extensions of .dic (for added words), .exc (for excluded words), or .acl (for AutoCorrect).
The files should be UTF-16 LE plaintext that starts with the Byte Order Mark (BOM).
Each line should consist of a word (in the added and excluded word lists), or an autocorrect pair with the words separated by a vertical bar ("|") (in
the AutoCorrect word list).
These files are considered read-only and are not modified by the system.
NOTE
These new file-formats are not directly supported by the WPF spell checking API’s, and the custom dictionaries supplied to WPF in applications should continue to use
.lex files.
Samples There are a number of WPF Samples on MSDN. More than 200 of the most popular samples (based on their usage) will be moved into an
Open Source GitHub repository. Help us improve our samples by sending us a pull-request or opening a GitHub issue.
DirectX extensions WPF includes a NuGet package that provides new implementations of D3DImage that make it easy for you to interoperate with DX10
and Dx11 content. The code for this package has been open sourced and is available on GitHub.
Windows Workflow Foundation: Transactions
The System.Transactions.Transaction.EnlistPromotableSinglePhase method can now use a distributed transaction manager other than MSDTC to
promote the transaction. You do this by specifying a GUID transaction promoter identifier to the new
System.Transactions.Transaction.EnlistPromotableSinglePhase(IPromotableSinglePhaseNotification, Guid) overload . If this operation is successful, there
are limitations placed on the capabilities of the transaction. Once a non-MSDTC transaction promoter is enlisted, the following methods throw a
TransactionPromotionException because these methods require promotion to MSDTC:
System.Transactions.Transaction.EnlistDurable
System.Transactions.TransactionInterop.GetDtcTransaction
System.Transactions.TransactionInterop.GetExportCookie
System.Transactions.TransactionInterop.GetTransmitterPropagationToken
Once a non-MSDTC transaction promoter is enlisted, it must be used for future durable enlistments by using protocols that it defines. The Guid of the
transaction promoter can be obtained by using the PromoterType property. When the transaction promotes, the transaction promoter provides a Byte
array that represents the promoted token. An application can obtain the promoted token for a non-MSDTC promoted transaction with the
GetPromotedToken method.
Users of the new System.Transactions.Transaction.EnlistPromotableSinglePhase(IPromotableSinglePhaseNotification, Guid) overload must follow a
specific call sequence in order for the promotion operation to complete successfully. These rules are documented in the method's documentation.
Profiling
The unmanaged profiling API has been enhanced follows:
Better support for accessing PDBs in the ICorProfilerInfo7 interface In ASP.Net 5, it is becoming much more common for assemblies to be compiled in-
memory by Roslyn. For developers making profiling tools, this means that PDBs that historically were serialized on disk may no longer be present.
Profiler tools often use PDBs to map code back to source lines for tasks such as code coverage or line-by-line performance analysis. The
ICorProfilerInfo7 interface now includes two new methods, ICorProfilerInfo7::GetInMemorySymbolsLength and
ICorProfilerInfo7::ReadInMemorySymbols, to provide these profiler tools with access to the in-memory PDB data, By using the new APIs, a profiler can
obtain the contents of an in-memory PDB as a byte array and then process it or serialize it to disk.
Better instrumentation with the ICorProfiler interface Profilers that are using the ICorProfiler API’s ReJit functionality for dynamic instrumentation can
now modify some metadata. Previously such tools could instrument IL at any time, but metadata could only be modified at module load time. Because IL
refers to metadata, this limited the kinds of instrumentation that could be done. We have lifted some of those limits by adding the
ICorProfilerInfo7::ApplyMetaData method to support a subset of metadata edits after the module loads, in particular by adding new AssemblyRef ,
TypeRef , TypeSpec , MemberRef , MemberSpec , and UserString records. This change makes a much broader range of on-the-fly instrumentation possible.
In the .NET Framework 4.5, ASP.NET added the Model Binding feature that enabled an extensible, code-focused approach to CRUD-based
data operations in Web Forms pages and user controls. The Model Binding system now supports Task-returning model binding methods.
This feature allows Web Forms developers to get the scalability benefits of async with the ease of the data-binding system when using
newer versions of ORMs, including the Entity Framework.
Async model binding is controlled by the aspnet:EnableAsyncModelBinding configuration setting.
<appSettings>
<add key=" aspnet:EnableAsyncModelBinding" value="true|false" />
</appSettings>
On apps the target the .NET Framework 4.6, it defaults to true . On apps running on the .NET Framework 4.6 that target an earlier version
of the .NET Framework, it is false by default. It can be enabled by setting the configuration setting to true .
HTTP/2 Support (Windows 10)
HTTP/2 is a new version of the HTTP protocol that provides much better connection utilization (fewer round-trips between client and
server), resulting in lower latency web page loading for users. Web pages (as opposed to services) benefit the most from HTTP/2, since the
protocol optimizes for multiple artifacts being requested as part of a single experience. HTTP/2 support has been added to ASP.NET in the
.NET Framework 4.6. Because networking functionality exists at multiple layers, new features were required in Windows, in IIS, and in
ASP.NET to enable HTTP/2. You must be running on Windows 10 to use HTTP/2 with ASP.NET.
HTTP/2 is also supported and on by default for Windows 10 Universal Windows Platform (UWP) apps that use the
System.Net.Http.HttpClient API.
In order to provide a way to use the PUSH_PROMISE feature in ASP.NET applications, a new method with two overloads,
PushPromise(String) and PushPromise(String, String, NameValueCollection), has been added to the HttpResponse class.
NOTE
While ASP.NET 5 supports HTTP/2, support for the PUSH PROMISE feature has not yet been added.
The browser and the web server (IIS on Windows) do all the work. You don't have to do any heavy-lifting for your users.
Most of the major browsers support HTTP/2, so it's likely that your users will benefit from HTTP/2 support if your server supports it.
Support for the Token Binding Protocol
Microsoft and Google have been collaborating on a new approach to authentication, called the Token Binding Protocol. The premise is that
authentication tokens (in your browser cache) can be stolen and used by criminals to access otherwise secure resources (e.g. your bank
account) without requiring your password or any other privileged knowledge. The new protocol aims to mitigate this problem.
The Token Binding Protocol will be implemented in Windows 10 as a browser feature. ASP.NET apps will participate in the protocol, so that
authentication tokens are validated to be legitimate. The client and the server implementations establish the end-to-end protection
specified by the protocol.
Randomized string hash algorithms
The .NET Framework 4.5 introduced a randomized string hash algorithm. However, it was not supported by ASP.NET because of some
ASP.NET features depended on a stable hash code. In .NET Framework 4.6, randomized string hash algorithms are now supported. To
enable this feature, use the aspnet:UseRandomizedStringHashAlgorithm config setting.
<appSettings>
<add key="aspnet:UseRandomizedStringHashAlgorithm" value="true|false" />
</appSettings>
ADO.NET
ADO .NET now supports the Always Encrypted feature available in SQL Server 2016 Community Technology Preview 2 (CTP2). With Always
Encrypted, SQL Server can perform operations on encrypted data, and best of all the encryption key resides with the application inside the
customer’s trusted environment and not on the server. Always Encrypted secures customer data so DBAs do not have access to plain text data.
Encryption and decryption of data happens transparently at the driver level, minimizing changes that have to be made to existing applications.
For details, see Always Encrypted (Database Engine) and Always Encrypted (client development).
64-bit JIT Compiler for managed code
The .NET Framework 4.6 features a new version of the 64-bit JIT compiler (originally code-named RyuJIT). The new 64-bit compiler provides
significant performance improvements over the older 64-bit JIT compiler. The new 64-bit compiler is enabled for 64-bit processes running on top
of the .NET Framework 4.6. Your app will run in a 64-bit process if it is compiled as 64-bit or AnyCPU and is running on a 64-bit operating
system. While care has been taken to make the transition to the new compiler as transparent as possible, changes in behavior are possible. We
would like to hear directly about any issues encountered when using the new JIT compiler. Please contact us through Microsoft Connect if you
encounter an issue that may be related to the new 64-bit JIT compiler.
The new 64-bit JIT compiler also includes hardware SIMD acceleration features when coupled with SIMD-enabled types in the System.Numerics
namespace, which can yield good performance improvements.
Assembly loader improvements
The assembly loader now uses memory more efficiently by unloading IL assemblies after a corresponding NGEN image is loaded. This change
decreases virtual memory, which is particularly beneficial for large 32-bit apps (such as Visual Studio), and also saves physical memory.
Base class library changes
Many new APIs have been added around to .NET Framework 4.6 to enable key scenarios. These include the following changes and additions:
IReadOnlyCollection<T> implementations
Additional collections implement IReadOnlyCollection<T> such as Queue<T> and Stack<T>.
CultureInfo.CurrentCulture and CultureInfo.CurrentUICulture
The System.Globalization.CultureInfo.CurrentCulture and System.Globalization.CultureInfo.CurrentUICulture properties are now read-write
rather than read-only. If you assign a new CultureInfo object to these properties, the current thread culture defined by the
Thread.CurrentThread.CurrentCulture property and the current UI thread culture defined by the Thread.CurrentThread.CurrentUICulture
properties also change.
Enhancements to garbage collection (GC)
The GC class now includes TryStartNoGCRegion and EndNoGCRegion methods that allow you to disallow garbage collection during the
execution of a critical path.
A new overload of the System.GC.Collect(Int32, GCCollectionMode, Boolean, Boolean) method allows you to control whether both the
small object heap and the large object heap are swept and compacted or swept only.
SIMD-enabled types
The System.Numerics namespace now includes a number of SIMD-enabled types, such as Matrix3x2, Matrix4x4, Plane, Quaternion,
Vector2, Vector3, and Vector4.
Because the new 64-bit JIT compiler also includes hardware SIMD acceleration features, there are especially significant performance
improvements when using the SIMD-enabled types with the new 64-bit JIT compiler.
Cryptography updates
The System.Security.Cryptography API is being updated to support the Windows CNG cryptography APIs. Previous versions of the .NET
Framework have relied entirely on an earlier version of the Windows Cryptography APIs as the basis for the System.Security.Cryptography
implementation. We have had requests to support the CNG API, since it supports modern cryptography algorithms, which are important
for certain categories of apps.
The .NET Framework 4.6 includes the following new enhancements to support the Windows CNG cryptography APIs:
A set of extension methods for X509 Certificates,
System.Security.Cryptography.X509Certificates.RSACertificateExtensions.GetRSAPublicKey(System.Security.Cryptography.X509Certificates.X509Certificate2)
and
System.Security.Cryptography.X509Certificates.RSACertificateExtensions.GetRSAPrivateKey(System.Security.Cryptography.X509Certificates.X509Certificate2)
, that return a CNG-based implementation rather than a CAPI-based implementation when possible. (Some smartcards, etc., still
require CAPI, and the APIs handle the fallback).
The System.Security.Cryptography.RSACng class, which provides a CNG implementation of the RSA algorithm.
Enhancements to the RSA API so that common actions no longer require casting. For example, encrypting data using an
X509Certificate2 object requires code like the following in previous versions of the .NET Framework.
Code that uses the new cryptography APIs in the .NET Framework 4.6 can be rewritten as follows to avoid the cast.
AppContext.SetSwitch("Switch.AmazingLib.ThrowOnException", true);
The library must check if a consumer has declared the value of the switch and then appropriately act on it.
// The library can use the value of shouldThrow to throw exceptions or not.
if (shouldThrow)
{
// old code
}
else {
// new code
}
}
It's beneficial to use a consistent format for switches, since they are a formal contract exposed by a library. The following are two obvious
formats.
Switch.namespace.switchname
Switch.library.switchname
Changes to the task-based asynchronous pattern (TAP)
For apps that target the .NET Framework 4.6, Task and Task<TResult> objects inherit the culture and UI culture of the calling thread. The
behavior of apps that target previous versions of the .NET Framework, or that do not target a specific version of the .NET Framework, is
unaffected. For more information, see the "Culture and task-based asynchronous operations" section of the CultureInfo class topic.
The System.Threading.AsyncLocal<T> class allows you to represent ambient data that is local to a given asynchronous control flow, such
as an async method. It can be used to persist data across threads. You can also define a callback method that is notified whenever the
ambient data changes either because the System.Threading.AsyncLocal<T>.Value property was explicitly changed, or because the thread
encountered a context transition.
Three convenience methods, System.Threading.Tasks.Task.CompletedTask, System.Threading.Tasks.Task.FromCanceled, and
System.Threading.Tasks.Task.FromException, have been added to the task-based asynchronous pattern (TAP) to return completed tasks in
a particular state.
The NamedPipeClientStream class now supports asynchronous communication with its new ConnectAsync. method.
EventSource now supports writing to the Event log
You now can use the EventSource class to log administrative or operational messages to the event log, in addition to any existing ETW
sessions created on the machine. In the past, you had to use the Microsoft.Diagnostics.Tracing.EventSource NuGet package for this
functionality. This functionality is now built-into the .NET Framework 4.6.
Both the NuGet package and the .NET Framework 4.6 have been updated with the following features:
Dynamic events
Allows events defined "on the fly" without creating event methods.
Rich payloads
Allows specially attributed classes and arrays as well as primitive types to be passed as a payload
Activity tracking
Causes Start and Stop events to tag events between them with an ID that represents all currently active activities.
To support these features, the overloaded Write method has been added to the EventSource class.
Windows Presentation Foundation (WPF)
HDPI improvements
HDPI support in WPF is now better in the .NET Framework 4.6. Changes have been made to layout rounding to reduce instances of
clipping in controls with borders. By default, this feature is enabled only if your TargetFrameworkAttribute is set to .NET 4.6. Applications
that target earlier versions of the framework but are running on the .NET Framework 4.6 can opt in to the new behavior by adding the
following line to the <runtime> section of the app.config file:
<AppContextSwitchOverrides
value="Switch.MS.Internal.DoNotApplyLayoutRoundingToMarginsAndBorderThickness=false"
/>
WPF windows straddling multiple monitors with different DPI settings (Multi-DPI setup) are now completely rendered without blacked-out
regions. You can opt out of this behavior by adding the following line to the <appSettings> section of the app.config file to disable this
new behavior:
Support for automatically loading the right cursor based on DPI setting has been added to System.Windows.Input.Cursor.
Touch is better
Customer reports on Connect that touch produces unpredictable behavior have been addressed in the .NET Framework 4.6. The double tap
threshold for Windows Store applications and WPF applications is now the same in Windows 8.1 and above.
Transparent child window support
WPF in the .NET Framework 4.6 supports transparent child windows in Windows 8.1 and above. This allows you to create non-rectangular
and transparent child windows in your top-level windows. You can enable this feature by setting the
System.Windows.Interop.HwndSourceParameters.UsesPerPixelTransparency property to true .
Windows Communication Foundation (WCF)
SSL support
WCF now supports SSL version TLS 1.1 and TLS 1.2, in addition to SSL 3.0 and TLS 1.0, when using NetTcp with transport security and
client authentication. It is now possible to select which protocol to use, or to disable old lesser secure protocols. This can be done either by
setting the SslProtocols property or by adding the following to a configuration file.
<netTcpBinding>
<binding>
<security mode= "None|Transport|Message|TransportWithMessageCredential" >
<transport clientCredentialType="None|Windows|Certificate"
protectionLevel="None|Sign|EncryptAndSign"
sslProtocols="Ssl3|Tls1|Tls11|Tls12">
</transport>
</security>
</binding>
</netTcpBinding>
<appSettings>
<add key="wcf:httpTransportBinding:useUniqueConnectionPoolPerFactory" value="true" />
</appSettings>
The default value is 60 seconds. If value is set to 0, out-of-order requests are immediately rejected with a fault with text that looks like this:
This is the same message that you receive if an out-of-order operation message is received and there are no non-protocol bookmarks.
If the value of the FilterResumeTimeoutInSeconds element is non-zero, there are non-protocol bookmarks, and the timeout interval expires, the
operation fails with a timeout message.
Transactions
You can now include the distributed transaction identifier for the transaction that has caused an exception derived from TransactionException to
be thrown. You do this by adding the following key to the appSettings section of your app.config file:
<appSettings>
<add key="EnableWindowsFormsHighDpiAutoResizing" value="true" />
</appSettings>
New workflow feature. A resource manager that's using the EnlistPromotableSinglePhase method (and therefore implementing the
IPromotableSinglePhaseNotification interface) can use the new System.Transactions.Transaction.PromoteAndEnlistDurable method to request the
following:
Promote the transaction to a Microsoft Distributed Transaction Coordinator (MSDTC) transaction.
Replace IPromotableSinglePhaseNotification with an ISinglePhaseNotification, which is a durable enlistment that supports single phase
commits.
This can be done within the same app domain, and doesn't require any extra unmanaged code to interact with MSDTC to perform the promotion.
The new method can be called only when there's an outstanding call from System.Transactions to the IPromotableSinglePhaseNotification
Promote method that's implemented by the promotable enlistment.
Profiling improvements. The following new unmanaged profiling APIs provide more robust profiling:
COR_PRF_ASSEMBLY_REFERENCE_INFO Structure COR_PRF_HIGH_MONITOR Enumeration GetAssemblyReferences Method GetEventMask2
Method SetEventMask2 Method AddAssemblyReference Method
Previous ICorProfiler implementations supported lazy loading of dependent assemblies. The new profiling APIs require dependent assemblies
that are injected by the profiler to be loadable immediately, instead of being loaded after the app is fully initialized. This change doesn't affect
users of the existing ICorProfiler APIs.
Debugging improvements. The following new unmanaged debugging APIs provide better integration with a profiler. You can now access
metadata inserted by the profiler as well as local variables and code produced by compiler ReJIT requests when dump debugging.
SetWriteableMetadataUpdateMode Method EnumerateLocalVariablesEx Method GetLocalVariableEx Method GetCodeEx Method
GetActiveReJitRequestILCode Method GetInstrumentedILMap Method
Event tracing changes. The .NET Framework 4.5.2 enables out-of-process, Event Tracing for Windows (ETW)-based activity tracing for a larger
surface area. This enables Advanced Power Management (APM) vendors to provide lightweight tools that accurately track the costs of individual
requests and activities that cross threads. These events are raised only when ETW controllers enable them; therefore, the changes don't affect
previously written ETW code or code that runs with ETW disabled.
Promoting a transaction and converting it to a durable enlistment
System.Transactions.Transaction.PromoteAndEnlistDurable is a new API added to the .NET Framework 4.5.2 and 4.6:
The method may be used by an enlistment that was previously created by System.Transactions.Transaction.EnlistPromotableSinglePhase in
response to the System.Transactions.ITransactionPromoter.Promote method. It asks System.Transactions to promote the transaction to an
MSDTC transaction and to "convert" the promotable enlistment to a durable enlistment. After this method completes successfully, the
IPromotableSinglePhaseNotification interface will no longer be referenced by System.Transactions , and any future notifications will arrive on the
provided ISinglePhaseNotification interface. The enlistment in question must act as a durable enlistment, supporting transaction logging and
recovery. Refer to System.Transactions.Transaction.EnlistDurable for details. In addition, the enlistment must support ISinglePhaseNotification.
This method can only be called while processing an System.Transactions.ITransactionPromoter.Promote call. If that is not the case, a
TransactionException exception is thrown.
Back to top
<appSettings>
<add key="EnableWindowsFormsHighDpiAutoResizing" value="true" />
</appSettings>
Improvements when debugging your .NET Framework apps in Visual Studio 2013 include:
Return values in the Visual Studio debugger. When you debug a managed app in Visual Studio 2013, the Autos window displays return types and
values for methods. This information is available for desktop, Windows Store, and Windows Phone apps. For more information, see Examine
return values of method calls in the MSDN Library.
Edit and Continue for 64-bit apps. Visual Studio 2013 supports the Edit and Continue feature for 64-bit managed apps for desktop, Windows
Store, and Windows Phone. The existing limitations remain in effect for both 32-bit and 64-bit apps (see the last section of the Supported Code
Changes (C#) article).
Async-aware debugging. To make it easier to debug asynchronous apps in Visual Studio 2013, the call stack hides the infrastructure code
provided by compilers to support asynchronous programming, and also chains in logical parent frames so you can follow logical program
execution more clearly. A Tasks window replaces the Parallel Tasks window and displays tasks that relate to a particular breakpoint, and also
displays any other tasks that are currently active or scheduled in the app. You can read about this feature in the "Async-aware debugging" section
of the .NET Framework 4.5.1 announcement.
Better exception support for Windows Runtime components. In Windows 8.1, exceptions that arise from Windows Store apps preserve
information about the error that caused the exception, even across language boundaries. You can read about this feature in the "Windows Store
app development" section of the .NET Framework 4.5.1 announcement.
Starting with Visual Studio 2013, you can use the Managed Profile Guided Optimization Tool (Mpgo.exe) to optimize Windows 8.x Store apps as well as
desktop apps.
For new features in ASP.NET 4.5.1, see ASP.NET 4.5.1 and Visual Studio 2013 on the ASP.NET site.
Back to top
See Also
The .NET Framework and Out-of-Band Releases
What's New in Visual Studio 2017
ASP.NET
What’s New in Visual C++
Get started with the .NET Framework
8/5/2017 • 5 min to read • Edit Online
The .NET Framework is a runtime execution environment that manages apps that target the .NET Framework. It
consists of the common language runtime, which provides memory management and other system services, and
an extensive class library, which enables programmers to take advantage of robust, reliable code for all major
areas of app development.
Related topics
TITLE DESCRIPTION
The .NET Framework and Out-of-Band Releases Describes the .NET Framework out of band releases and how
to use them in your app.
System Requirements Lists the hardware and software requirements for running the
.NET Framework.
.NET Core and Open-Source Describes .NET Core in relation to the .NET Framework and
how to access the open-source .NET Core projects.
.NET Core documentation Provides the conceptual and API reference documentation for
.NET Core.
See also
.NET Framework Guide
What's New
.NET API Browser
Development Guide
Installation guide
8/5/2017 • 1 min to read • Edit Online
See also
.NET Framework Development Guide
Migration Guide to the .NET Framework 4.7, 4.6, and
4.5
7/29/2017 • 1 min to read • Edit Online
If you created your app using an earlier version of the .NET Framework, you can generally upgrade it to the .NET
Framework 4.5 and its point releases (4.5.1 and 4.5.2), the .NET Framework 4.6 and its point releases (4.6.1 and
4.6.2), or the .NET Framework 4.7 easily. Open your project in Visual Studio. If your project was created in an earlier
version, the Project Compatibility dialog box automatically opens. For more information about upgrading a
project in Visual Studio, see Port, Migrate, and Upgrade Visual Studio Projects and Visual Studio 2017 Platform
Targeting and Compatibility.
However, some changes in the .NET Framework require changes to your code. You may also want to take
advantage of functionality that is new in the .NET Framework 4.5 and its point releases, in the .NET Framework 4.6
and its point releases, or in the .NET Framework 4.7. Making these types of changes to your app for a new version
of the .NET Framework is typically referred to as migration. If your app doesn't have to be migrated, you can run it
in the .NET Framework 4.5 or later versions without recompiling it.
Migration resources
Review the following documents before you migrate your app from earlier versions of the .NET Framework to
version 4.5, 4.5.1, 4.5.2, 4.6, 4.6.1, 4.6.2, or 4.7:
See Versions and Dependencies to understand the CLR version underlying each version of the .NET
Framework and to review guidelines for targeting your apps successfully.
Review Application Compatibility to find out about runtime and retargeting changes that might affect your
app and how to handle them.
Review What's Obsolete in the Class Library to determine any types or members in your code that have
been made obsolete, and the recommended alternatives.
See What's New for descriptions of new features that you may want to add to your app.
See Also
Application Compatibility
Migrating from the .NET Framework 1.1
Version Compatibility
Versions and Dependencies
How to: Configure an App to Support .NET Framework 4 or 4.5
What's New
What's Obsolete in the Class Library
.NET Framework Version and Assembly Information
Microsoft .NET Framework Support Lifecycle Policy .NET Framework 4 migration issues
Deploying .NET Framework applications with Docker
7/29/2017 • 1 min to read • Edit Online
You can deploy .NET Framework applicaton with Docker, using Windows Containers. You can learn the
requirements for using Windows Containers and how to Get Started with Docker for Windows.
You can begin by running a console application with Docker. For running web applications in Docker, you can read
ASP.NET MVC applications in Docker.
Running console applications in Windows containers
7/29/2017 • 5 min to read • Edit Online
Console applications are used for many purposes; from simple querying of a status to long running document
image processing tasks. In any case, the ability to start up and scale these applications are met with limitations of
hardware acquisitions, startup times or running multiple instances.
Moving your console applications to use Docker and Windows Server containers allows for starting these
applications from a clean state, enabling them to perform the operation and then shutdown cleanly. This topic will
show the steps needed to move a console application to a Windows based container and start it using a
PowerShell script.
The sample console application is a simple example which takes an argument, a question in this case, and returns a
random answer. This could take a customer_id and process their taxes, or create a thumbnail for an image_url
argument.
In addition to the answer, the Environment.MachineName has been added to the response to show the difference
between running the application locally and in a Windows container. When running the application locally, your
local machine name should be returned and when running in a Windows Container; the container session id is
returned.
The complete example is available in the dotnet/docs repository on GitHub. For download instructions, see
Samples and Tutorials.
You need to be familiar with some Docker terms before you begin working on moving your application to a
container.
A Docker image is a read-only template that defines the environment for a running container, including the
operating system (OS), system components, and application(s).
One important feature of Docker images is that images are composed from a base image. Each new image adds a
small set of features to an existing image.
You scale an application by running the same image in many containers. Conceptually, this is similar to running the
same application in multiple hosts.
You can learn more about the Docker architecture by reading the Docker Overview on the Docker site.
Moving your console application is a matter of a few steps.
1. Build the application
2. Creating a Dockerfile for the image
3. Process to build and run the Docker container
Prerequisites
Windows containers are supported on Windows 10 Anniversary Update or Windows Server 2016.
NOTE
If you are using Windows Server 2016, you must enable containers manually since the Docker for Windows installer will not
enable the feature. Make sure all updates have run for the OS and then follow the instructions from the Container Host
Deployment article to install the containers and Docker features.
You need to have Docker for Windows, version 1.12 Beta 26 or higher to support Windows containers. By default,
Docker enables Linux based containers; switch to Windows containers by right clicking the Docker icon in the
system tray and select Switch to Windows containers. Docker will run the process to change and a restart may
be required.
FROM microsoft/windowsservercore
ADD publish/ /
ENTRYPOINT ConsoleRandomAnswerGenerator.exe
The first line in the Dockerfile designates the base image using the FROM instruction. Next, ADD in the file copies
the application assets from the publish folder to root folder of the container and last; setting the ENTRYPOINT of
the image states that this is the command or application that will run when the container starts.
$ImageName="console-random-answer-generator"
Run the script using .\build.ps1 from the PowerShell command prompt.
When the build is complete, using the docker images command from a command line or PowerShell prompt;
you'll see that the image is created and ready to be run.
The output is
The answer to your question: 'Are you a square container?' is Concentrate and ask again on (70C3D48F4343)
If you run the docker ps -a command from PowerShell, you can see that the container still exists.
The STATUS column shows at "About a minute ago", the application was complete and could be shut down. If the
command was run a hundred times, there would be a hundred containers left static with no work to do. In the
beginning scenario the ideal operation was to do the work and shutdown or cleanup. To accomplish that workflow,
adding the --rm option to the docker run command will remove the container as soon as the Exited signal is
received.
Summary
Just by adding a Dockerfile and publishing the application, you can containerize your .NET Framework console
applications and now take the advantage of running multiple instances, clean start and stop and more Windows
Server 2016 capabilities without making any changes to the application code at all.
.NET Framework Development Guide
7/29/2017 • 2 min to read • Edit Online
This section explains how to create, configure, debug, secure, and deploy your .NET Framework apps. The section
also provides information about technology areas such as dynamic programming, interoperability, extensibility,
memory management, and threading.
In This Section
Application Essentials
Provides information about basic app development tasks, such as programming with app domains and
assemblies, using attributes, formatting and parsing base types, using collections, handling events and exceptions,
using files and data streams, and using generics.
Data and Modeling
Provides information about how to access data using ADO.NET, Language Integrated Query (LINQ), WCF Data
Services, and XML.
Client Applications
Explains how to create Windows-based apps by using Windows Presentation Foundation (WPF) or Windows
Forms.
Web Applications with ASP.NET
Provides links to information about using ASP.NET to build enterprise-class web apps with a minimum of coding.
Service-Oriented Applications with WCF
Describes how to use Windows Communication Foundation (WCF) to build service-oriented apps that are secure
and reliable.
Building workflows with Windows Workflow Foundation
Provides information about the programming model, samples, and tools for using Windows Workflow Foundation
(WF).
Windows Service Applications
Explains how you can use Visual Studio and the .NET Framework to create an app that is installed as a service, and
start, stop, and otherwise control its behavior.
Parallel Processing and Concurrency
Provides information about managed threading, parallel programming, and asynchronous programming design
patterns.
Network Programming in the .NET Framework
Describes the layered, extensible, and managed implementation of Internet services that you can quickly and easily
integrate into your apps.
Configuring .NET Framework Apps
Explains how you can use configuration files to change settings without having to recompile your .NET Framework
apps.
Compiling Apps with .NET Native
Explains how you can use the .NET Native precompilation technology to build and deploy Windows Store apps.
.NET Native compiles apps that are written in managed code (C#) and that target the .NET Framework to native
code.
Security
Provides information about the classes and services in the .NET Framework that facilitate secure app development.
Debugging, Tracing, and Profiling
Explains how to test, optimize, and profile .NET Framework apps and the app environment. This section includes
information for administrators as well as developers.
Developing for Multiple Platforms
Provides information about how you can use the .NET Framework to build assemblies that can be shared across
multiple platforms and multiple devices such as phones, desktop, and web.
Deployment
Explains how to package and distribute your .NET Framework app, and includes deployment guides for both
developers and administrators.
Performance
Provides information about caching, lazy initialization, reliability, and ETW events.
Reference
.NET Framework Class Library
Supplies syntax, code examples, and usage information for each class that is contained in the .NET Framework
namespaces.
Related Sections
Getting Started
Provides a comprehensive overview of the .NET Framework and links to additional resources.
What's New
Describes key new features and changes in the latest version of the .NET Framework. Includes lists of new and
obsolete types and members, and provides a guide for migrating your apps from the previous version of the .NET
Framework.
Tools
Describes the tools that help you develop, configure, and deploy apps by using .NET Framework technologies.
.NET Framework Samples
Provides links to the MSDN Code Samples Gallery for sample apps that demonstrate .NET Framework
technologies.
Programming with Application Domains and
Assemblies
7/29/2017 • 1 min to read • Edit Online
Hosts such as Microsoft Internet Explorer, ASP.NET, and the Windows shell load the common language runtime
into a process, create an application domain in that process, and then load and execute user code in that application
domain when running a .NET Framework application. In most cases, you do not have to worry about creating
application domains and loading assemblies into them because the runtime host performs those tasks.
However, if you are creating an application that will host the common language runtime, creating tools or code you
want to unload programmatically, or creating pluggable components that can be unloaded and reloaded on the fly,
you will be creating your own application domains. Even if you are not creating a runtime host, this section
provides important information on how to work with application domains and assemblies loaded in these
application domains.
In This Section
Application Domains and Assemblies How-to Topics
Provides links to all How-to topics found in the conceptual documentation for programming with application
domains and assemblies.
Using Application Domains
Provides examples of creating, configuring, and using application domains.
Programming with Assemblies
Describes how to create, sign, and set attributes on assemblies.
Related Sections
Emitting Dynamic Methods and Assemblies
Describes how to create dynamic assemblies.
Assemblies in the Common Language Runtime
Provides a conceptual overview of assemblies.
Application Domains
Provides a conceptual overview of application domains.
Reflection Overview
Describes how to use the Reflection class to obtain information about an assembly.
Resources in Desktop Apps
7/29/2017 • 4 min to read • Edit Online
Nearly every production-quality app has to use resources. A resource is any nonexecutable data that is logically
deployed with an app. A resource might be displayed in an app as error messages or as part of the user interface.
Resources can contain data in a number of forms, including strings, images, and persisted objects. (To write
persisted objects to a resource file, the objects must be serializable.) Storing your data in a resource file enables
you to change the data without recompiling your entire app. It also enables you to store data in a single location,
and eliminates the need to rely on hard-coded data that is stored in multiple locations.
The .NET Framework provides comprehensive support for the creation and localization of resources in desktop
apps. In addition, the .NET Framework supports a simple model for packaging and deploying these localized
resources in desktop apps.
For information about resources in ASP.NET, see ASP.NET Web Page Resources Overview in the Internet Explorer
Developer Center.
Windows 8.x Store apps use a different resource model from desktop apps and store their resources in a single
package resource index (PRI) file. For information about resources in Windows 8.x Store apps, see Creating and
retrieving resources in Windows Store apps in the Windows Dev Center.
Retrieving Resources
At run time, an app loads the appropriate localized resources on a per-thread basis, based on the culture specified
by the System.Globalization.CultureInfo.CurrentUICulture property. This property value is derived as follows:
By directly assigning a CultureInfo object that represents the localized culture to the
System.Threading.Thread.CurrentUICulture property.
If a culture is not explicitly assigned, by retrieving the default thread UI culture from the
System.Globalization.CultureInfo.DefaultThreadCurrentUICulture property.
If a default thread UI culture is not explicitly assigned, by retrieving the culture for the current user on the
local computer by calling the Windows GetUserDefaultUILanguage function.
For more information about how the current UI culture is set, see the CultureInfo and
System.Globalization.CultureInfo.CurrentUICulture reference pages.
You can then retrieve resources for the current UI culture or for a specific culture by using the
System.Resources.ResourceManager class. Although the ResourceManager class is most commonly used for
retrieving resources in desktop apps, the System.Resources namespace contains additional types that you can use
to retrieve resources. These include:
The ResourceReader class, which enables you to enumerate resources embedded in an assembly or stored
in a standalone binary .resources file. It is useful when you don't know the precise names of the resources
that are available at run time.
The ResXResourceReader class, which enables you to retrieve resources from an XML (.resx) file.
The ResourceSet class, which enables you to retrieve the resources of a specific culture without observing
fallback rules. The resources can be stored in an assembly or a standalone binary .resources file. You can
also develop an IResourceReader implementation that enables you to use the ResourceSet class to retrieve
resources from some other source.
The ResXResourceSet class, which enables you to retrieve all the items in an XML resource file into memory.
See Also
CultureInfo
System.Globalization.CultureInfo.CurrentUICulture
Application Essentials
Creating Resource Files
Packaging and Deploying Resources
Creating Satellite Assemblies
Retrieving Resources
Accessibility
7/29/2017 • 1 min to read • Edit Online
NOTE
This documentation is intended for .NET Framework developers who want to use the managed UI Automation classes defined
in the System.Windows.Automation namespace. For the latest information about UI Automation, see Windows Automation
API: UI Automation.
Microsoft UI Automation is the new accessibility framework for Microsoft Windows. It addresses the needs of
assistive technology products and automated test frameworks by providing programmatic access to information
about the user interface (UI). In addition, UI Automation enables control and application developers to make their
products accessible.
This documentation describes the UI Automation API for managed code. For information on programming for UI
Automation in C++, see UI Automation for Win32 Applications.
In This Section
Accessibility Best Practices
UI Automation Fundamentals
UI Automation Providers for Managed Code
UI Automation Clients for Managed Code
UI Automation Control Patterns
UI Automation Text Pattern
UI Automation Control Types
UI Automation Specification and Community Promise
Related Sections
Accessibility Samples
Data and Modeling in the .NET Framework
7/29/2017 • 1 min to read • Edit Online
This section provides information on how to access data using ADO.NET, Language Integrated Query (LINQ), WCF
Data Services, and XML.
In This Section
ADO.NET
Describes the ADO.NET architecture and how to use the ADO.NET classes to manage application data and interact
with data sources, including Microsoft SQL Server, OLE DB data sources, and XML.
LINQ Portal
Provides links to relevant documentation for Language Integrated Query (LINQ).
Transaction Processing
Discusses the .NET Framework support for transactions.
WCF Data Services 4.5
Provides information about how to use WCF Data Services to deploy data services on the Web or an intranet.
XML Documents and Data
Provides an overview to a comprehensive and integrated set of classes that work with XML documents and data in
the .NET Framework.
XML Standards Reference
Provides reference information on XML standards that Microsoft supports.
Related Sections
Microsoft SQL Server Modeling Technologies
Describes a set of technologies that enable rapid and customized data-based application design and development.
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 links to more information on the classes and services in the common language runtime and the .NET
Framework that facilitate secure application development.
Developing Client Applications with the .NET
Framework
7/29/2017 • 1 min to read • Edit Online
There are multiple ways to develop Windows-based applications with the .NET framework that run locally on users'
computers or devices. This section contains topics that describe how to create Windows-based applications by
using Windows Presentation Foundation (WPF) or by using Windows Forms. However, you also create client
applications using the .NET Framework and make them available to your users through the Windows Store and
Windows Phone store for computers or devices, web applications that can be viewed in a browser.
In This Section
Windows Presentation Foundation
Provides information about developing applications by using WPF.
Windows Forms
Provides information about developing applications by using Windows Forms.
Common Client Technologies
Provides information about additional technologies that can be used when developing client applications.
Related Sections
Windows Store apps
Describes how to create apps that you can make available to users through the Windows Store
.NET for Store apps
Describes the .NET Framework support for Store apps, which can be deployed to Windows computers and devices.
.NET API for Windows Phone Silverlight
List the .NET Framework APIs you can use for building apps with Windows Phone Silverlight
Developing for Multiple Platforms
Describes the different methods you can use the .NET Framework to target multiple client app types.
Get Started with ASP.NET Web Sites
Describes the ways you can develop web apps using ASP.NET.
See Also
Portable Class Library
Overview
Development Guide
How to: Create a Windows Desktop Application
Windows Service Applications
Common Client Technologies in the .NET Framework
7/29/2017 • 1 min to read • Edit Online
This section describes different technologies that you can use in your client applications.
In This Section
Manipulations and Inertia
Describes how to use manipulations and inertia processor classes in different UI frameworks, such as Microsoft
Windows Presentation Foundation (WPF) or Microsoft XNA.
Client Application Services
Describes how to use use the Microsoft Ajax login, roles, and profile application services included in the Microsoft
ASP.NET 2.0 AJAX Extensions in your Windows-based applications.
Windows Presentation Foundation
7/29/2017 • 1 min to read • Edit Online
Windows Presentation Foundation (WPF) in Visual Studio 2015 provides developers with a unified programming
model for building modern line-of-business desktop applications on Windows.
NOTE
The Mozilla Firefox browser disables the Microsoft Framework Assistant extension. See How to remove the .NET Framework
Assistant for Firefox for information on how to remove the extension from Firefox.
As forms are the base unit of your application, it is essential that you give some thought to their function and
design. A form is ultimately a blank slate that you, as a developer, enhance with controls to create a user interface
and with code to manipulate data. To that end, Visual Studio provides you with an integrated development
environment (IDE) to aid in writing code, as well as a rich control set written with the .NET Framework. By
complementing the functionality of these controls with your code, you can easily and quickly develop the solutions
you need.
In This Section
Getting Started with Windows Forms
Provides links to topics about how to harness the power of Windows Forms to display data, handle user input, and
deploy your applications easily and with more robust security.
Enhancing Windows Forms Applications
Provides links to topics about how to enhance your Windows Forms with a variety of features.
Related Sections
Windows Forms Controls
Contains links to topics that describe Windows Forms controls and show how to implement them.
Windows Forms Data Binding
Contains links to topics that describe the Windows Forms data-binding architecture.
Graphics Overview
Discusses how to create graphics, draw text, and manipulate graphical images as objects using the advanced
implementation of the Windows graphics design interface.
ClickOnce Security and Deployment
Discusses the principles of ClickOnce deployment.
Windows Forms/MFC Programming Differences
Discusses the differences between MFC applications and Windows Forms.
Accessing data in Visual Studio
Discusses incorporating data access functionality into your applications.
Windows Forms Applications
Discusses the process of debugging applications created with the Windows Application project template, as well as
how to change the Debug and Release configurations.
Deploying Applications, Services, and Components
Describes the process by which you distribute a finished application or component to be installed on other
computers.
Building Console Applications
Describes the basics of creating a console application using the Console class.
Developing Service-Oriented Applications with WCF
8/24/2017 • 1 min to read • Edit Online
This section of the documentation provides information about Windows Communication Foundation (WCF), which
is a unified programming model for building service-oriented applications. It enables developers to build secure,
reliable, transacted solutions that integrate across platforms and interoperate with existing investments.
In this section
What's New in Windows Communication Foundation 4.5
Discusses features new to Windows Communication Foundation.
WCF Simplification Features
Discusses new features that make writing WCF applications simpler.
Guide to the Documentation
A description of the WCF documentation
Conceptual Overview
Summarizes information about the Windows Communication Foundation (WCF) messaging system and the
classes that support its use.
Getting Started Tutorial
A step by step tutorial to create a WCF service and client
Basic WCF Programming
Describes the fundamentals for creating Windows Communication Foundation applications.
WCF Feature Details
Shows topics that let you choose which WCF feature or features you need to employ.
Extending WCF
Describes how to modify and extend WCF runtime components
Guidelines and Best Practices
Provides guidelines for creating Windows Communication Foundation (WCF) applications.
Administration and Diagnostics
Describes the diagnostic features of WCF
System Requirements
Describes system requirements needed to run WCF
Operating System Resources Required by WCF
Describes operating system resources required by WCF
Troubleshooting Setup Issues
Provides guidance for fixing WCF setup issues
Migrating from .NET Remoting to WCF
Compares .NET Remoting to WCF and provides migration guidance for common scenarios.
Using the WCF Development Tools
Describes the Visual Studio Windows Communication Foundation development tools that can assist you in
developing your WCFservice.
Windows Communication Foundation Tools
Describes WCF tools designed to make it easier to create, deploy, and manage WCF applications
Windows Communication Foundation Samples
Samples that provide instruction on various aspects of Windows Communication Foundation
Windows Communication Foundation Glossary
Shows a list of terms specific to WCF
General Reference
The section describes the elements that are used to configure Windows Communication Foundation clients and
services.
Feedback and Community
Information about how to provide feedback about Windows Communication Foundation
Privacy Information
Information regarding WCF and Privacy
Windows Workflow Foundation
7/29/2017 • 1 min to read • Edit Online
This section describes the programming model, samples, and tools of the Windows Workflow Foundation (WF).
In This Section
Guide to the Windows Workflow Documentation
A set of suggested topics to read, depending upon your familiarity (novice to well-acquainted), and requirements.
What's New in Windows Workflow Foundation
Discusses the changes in several development paradigms from previous versions.
What's New in Windows Workflow Foundation in .NET 4.5
Describes the new features in Windows Workflow Foundation in .NET Framework 4.6.1.
Windows Workflow Foundation Feature Specifics
Describes the new features in Windows Workflow Foundation in .NET Framework 4
Windows Workflow Conceptual Overview
A set of topics that discusses the larger concepts behind Windows Workflow Foundation.
Getting Started Tutorial
A set of walkthrough topics that introduce you to programming Windows Workflow Foundation applications.
Windows Workflow Foundation Programming
A set of primer topics that you should understand to become a proficient WF programmer.
Extending Windows Workflow Foundation
A set of topics that discusses how to extend or customize Windows Workflow Foundation to suit your needs.
Windows Workflow Foundation Glossary for .NET Framework 4.5
Defines a list of terms that are specific to WF.
Windows Workflow Samples
Contains sample applications that demonstrate WF features and scenarios.
Developing Windows Service Applications
7/29/2017 • 1 min to read • Edit Online
Using Microsoft Visual Studio or the Microsoft .NET Framework SDK, you can easily create services by creating an
application that is installed as a service. This type of application is called a Windows service. With framework
features, you can create services, install them, and start, stop, and otherwise control their behavior.
WARNING
The Windows service template for C++ was not included in Visual Studio 2010. To create a Windows service, you can either
create a service in managed code in Visual C# or Visual Basic, which could interoperate with existing C++ code if required, or
you can create a Windows service in native C++ by using the ATL Project Wizard.
In This Section
Introduction to Windows Service Applications
Provides an overview of Windows service applications, the lifetime of a service, and how service applications differ
from other common project types.
Walkthrough: Creating a Windows Service Application in the Component Designer
Provides an example of creating a service in Visual Basic and Visual C#.
Service Application Programming Architecture
Explains the language elements used in service programming.
How to: Create Windows Services
Describes the process of creating and configuring Windows services using the Windows service project template.
Related Sections
ServiceBase
Describes the major features of the ServiceBase class, which is used to create services.
ServiceProcessInstaller
Describes the features of the ServiceProcessInstaller class, which is used along with the ServiceInstaller class to
install and uninstall your services.
ServiceInstaller
Describes the features of the ServiceInstaller class, which is used along with the ServiceProcessInstaller class to
install and uninstall your service.
NIB Creating Projects from Templates
Describes the projects types used in this chapter and how to choose between them.
64-bit Applications
7/29/2017 • 3 min to read • Edit Online
When you compile an application, you can specify that it should run on a Windows 64-bit operating system either
as a native application or under WOW64 (Windows 32-bit on Windows 64-bit). WOW64 is a compatibility
environment that enables a 32-bit application to run on a 64-bit system. WOW64 is included in all 64-bit versions
of the Windows operating system.
NOTE
Because of the design of x86 emulation and the WOW64 subsystem for the Itanium processor family, applications are
restricted to execution on one processor. These factors reduce the performance and scalability of 32-bit .NET Framework
applications that run on Itanium-based systems. We recommend that you use the .NET Framework 4, which includes native
64-bit support for Itanium-based systems, for increased performance and scalability.
By default, when you run a 64-bit managed application on a 64-bit Windows operating system, you can create an
object of no more than 2 gigabytes (GB). However, in the .NET Framework 4.5, you can increase this limit. For more
information, see the <gcAllowVeryLargeObjects> element.
Many assemblies run identically on both the 32-bit CLR and the 64-bit CLR. However, some programs may behave
differently, depending on the CLR, if they contain one or more of the following:
Structures that contain members that change size depending on the platform (for example, any pointer
type).
Pointer arithmetic that includes constant sizes.
Incorrect platform invoke or COM declarations that use Int32 for handles instead of IntPtr .
Code that casts IntPtr to Int32 .
For more information about how to port a 32-bit application to run on the 64-bit CLR, see Migrating 32-bit
Managed Code to 64-bit in the MSDN Library.
ASP.NET is a .NET Framework technology for creating web apps. Documentation for ASP.NET is in the Web
Development section of the MSDN Library and on the www.asp.net website. The following links are provided for
your convenience:
ASP.NET and Visual Studio for Web
ASP.NET MVC
ASP.NET Web Pages
ASP.NET Web API
See Also
Development Guide
Network Programming in the .NET Framework
7/29/2017 • 4 min to read • Edit Online
The Microsoft .NET Framework provides a layered, extensible, and managed implementation of Internet services
that can be quickly and easily integrated into your applications. Your network applications can build on pluggable
protocols to automatically take advantage of new Internet protocols, or they can use a managed implementation of
the Windows socket interface to work with the network on the socket level.
In This Section
Introducing Pluggable Protocols
Describes how to access an Internet resource without regard to the access protocol that it requires.
Requesting Data
Explains how to use pluggable protocols to upload and download data from Internet resources.
Programming Pluggable Protocols
Explains how to derive protocol-specific classes to implement pluggable protocols.
Using Application Protocols
Describes programming applications that take advantage of network protocols such as TCP, UDP, and HTTP.
Internet Protocol Version 6
Describes the advantages of Internet Protocol version 6 (IPv6) over the current version of the Internet Protocol
suite (IPv4), describes IPv6 addressing, routing and auto-configuration, and how to enable and disable IPv6.
Configuring Internet Applications
Explains how to use the .NET Framework configuration files to configure Internet applications.
Network Tracing in the .NET Framework
Explains how to use network tracing to get information about method invocations and network traffic generated by
a managed application.
Cache Management for Network Applications
Describes how to use caching for applications that use the System.Net.WebClient, System.Net.WebRequest, and
System.Net.HttpWebRequest classes.
Security in Network Programming
Describes how to use standard Internet security and authentication techniques.
Best Practices for System.Net Classes
Provides tips and tricks for getting the most out of your Internet applications.
Accessing the Internet Through a Proxy
Describes how to configure proxies.
NetworkInformation
Describes how to gather information about network events, changes, statistics, and properties and also explains
how to determine whether a remote host is reachable by using the System.Net.NetworkInformation.Ping class.
Changes to the System.Uri namespace in Version 2.0
Describes several changes made to the System.Uri class in Version 2.0 to fixed incorrect behavior, enhance
usability, and enhance security.
International Resource Identifier Support in System.Uri
Describes enhancements to the System.Uri class in Version 3.5, 3.0 SP1, and 2.0 SP1 for International Resource
Identifier (IRI) and Internationalized Domain Name (IDN) support.
Socket Performance Enhancements in Version 3.5
Describes a set of enhancements to the System.Net.Sockets.Socket class in Version 3.5, 3.0 SP1, and 2.0 SP1 that
provide an alternative asynchronous pattern that can be used by specialized high-performance socket applications.
Peer Name Resolution Protocol
Describes support added in Version 3.5 to support the Peer Name Resolution Protocol (PNRP), a serverless and
dynamic name registration and name resolution protocol. These new features are supported by the
System.Net.PeerToPeer namespace.
Peer-to-Peer Collaboration
Describes support added in Version 3.5 to support the Peer-to-Peer Collaboration that builds on PNRP. These new
features are supported by the System.Net.PeerToPeer.Collaboration namespace.
Changes to NTLM authentication for HttpWebRequest in Version 3.5 SP1
Describes security changes made in Version 3.5 SP1 that affect how integrated Windows authentication is handled
by the System.Net.HttpWebRequest, System.Net.HttpListener, System.Net.Security.NegotiateStream, and related
classes in the System.Net namespace.
Integrated Windows Authentication with Extended Protection
Describes enhancements for extended protection that affect how integrated Windows authentication is handled by
the System.Net.HttpWebRequest, System.Net.HttpListener, System.Net.Mail.SmtpClient,
System.Net.Security.SslStream, System.Net.Security.NegotiateStream, and related classes in the System.Net and
related namespaces.
NAT Traversal using IPv6 and Teredo
Describes enhancements added to the System.Net, System.Net.NetworkInformation, and System.Net.Sockets
namespaces to support NAT traversal using IPv6 and Teredo.
Network Isolation for Windows Store Apps
Describes the impact of network isolation when classes in the System.Net, System.Net.Http, and
System.Net.Http.Headers namespaces are used in Windows 8.x Store apps.
Network Programming Samples
Links to downloadable network programming samples that use classes in the System.Net, System.Net.Cache,
System.Net.Configuration, System.Net.Mail, System.Net.Mime, System.Net.NetworkInformation,
System.Net.PeerToPeer, System.Net.Security, System.Net.Sockets namespaces.
Reference
System.Net
Provides a simple programming interface for many of the protocols used on networks today. The
System.Net.WebRequest and System.Net.WebResponse classes in this namespace are the basis for pluggable
protocols.
System.Net.Cache
Defines the types and enumerations used to define cache policies for resources obtained using the
System.Net.WebRequest and System.Net.HttpWebRequest classes.
System.Net.Configuration
Classes that applications use to programmatically access and update configuration settings for the System.Net
namespaces.
System.Net.Http
Classes that provides a programming interface for modern HTTP applications.
System.Net.Http.Headers
Provides support for collections of HTTP headers used by the System.Net.Http namespace
System.Net.Mail
Classes to compose and send mail using the SMTP protocol.
System.Net.Mime
Defines types that are used to represent Multipurpose Internet Mail Exchange (MIME) headers used by classes in
the System.Net.Mail namespace.
System.Net.NetworkInformation
Classes to programmatically gather information about network events, changes, statistics, and properties.
System.Net.PeerToPeer
Provides a managed implementation of the Peer Name Resolution Protocol (PNRP) for developers.
System.Net.PeerToPeer.Collaboration
Provides a managed implementation of the Peer-to-Peer Collaboration interface for developers.
System.Net.Security
Classes to provide network streams for secure communications between hosts.
System.Net.Sockets
Provides a managed implementation of the Windows Sockets (Winsock) interface for developers who need to help
control access to the network.
System.Net.WebSockets
Provides a managed implementation of the WebSocket interface for developers.
System.Uri
Provides an object representation of a uniform resource identifier (URI) and easy access to the parts of the URI.
System.Security.Authentication.ExtendedProtection
Provides support for authentication using extended protection for applications.
System.Security.Authentication.ExtendedProtection.Configuration
Provides support for configuration of authentication using extended protection for applications.
See Also
Network Programming How-to Topics
Network Programming Samples
Networking Samples for .NET on MSDN Code Gallery
HttpClient Sample
Configuring Apps by using Configuration Files
7/29/2017 • 5 min to read • Edit Online
The .NET Framework, through configuration files, gives developers and administrators control and flexibility over
the way applications run. Configuration files are XML files that can be changed as needed. An administrator can
control which protected resources an application can access, which versions of assemblies an application will use,
and where remote applications and objects are located. Developers can put settings in configuration files,
eliminating the need to recompile an application every time a setting changes. This section describes what can be
configured and why configuring an application might be useful.
NOTE
Managed code can use the classes in the System.Configuration namespace to read settings from the configuration files, but
not to write settings to those files.
This topic describes the syntax of configuration files and provides information about the three types of
configuration files: machine, application, and security.
<codeBase version="2.0.0.0"
href="http://www.litwareinc.com/myAssembly.dll"/>
For more information about how the common language runtime uses the machine configuration file for assembly
binding, see How the Runtime Locates Assemblies.
NOTE
Starting with the .NET Framework 4, the security configuration files are present only if security policy has been changed.
In This Section
How to: Locate Assemblies by Using DEVPATH
Describes how to direct the runtime to use the DEVPATH environment variable when searching for assemblies.
Redirecting Assembly Versions
Describes how to specify the location of an assembly and which version of an assembly to use.
Specifying an Assembly's Location
Describes how to specify where the runtime should search for an assembly.
Configuring Cryptography Classes
Describes how to map an algorithm name to a cryptography class and an object identifier to a cryptography
algorithm.
How to: Create a Publisher Policy
Describes when and how you should add a publisher policy file to specify assembly redirection and code base
settings.
Configuration File Schema
Describes the schema hierarchy for startup, runtime, network, and other types of configuration settings.
See Also
Configuration File Schema
Specifying an Assembly's Location
Redirecting Assembly Versions
Registering Remote Objects Using Configuration Files
ASP.NET Web Site Administration
NIB: Security Policy Management
Caspol.exe (Code Access Security Policy Tool)
Assemblies in the Common Language Runtime
Remote Objects
Compiling Apps with .NET Native
7/29/2017 • 2 min to read • Edit Online
.NET Native is a precompilation technology for building and deploying Windows apps that is included with Visual
Studio 2015. It automatically compiles the release version of apps that are written in managed code (C# or Visual
Basic) and that target the .NET Framework and Windows 10 to native code.
Typically, apps that target the .NET Framework are compiled to intermediate language (IL). At run time, the just-in-
time (JIT) compiler translates the IL to native code. In contrast, .NET Native compiles Windows apps directly to
native code. For developers, this means:
Your apps will provide the superior performance of native code.
You can continue to program in C# or Visual Basic.
You can continue to take advantage of the resources provided by the .NET Framework, including its class
library, automatic memory management and garbage collection, and exception handling.
For users of your apps, .NET Native offers these advantages:
Fast execution times
Consistently speedy startup times
Low deployment and update costs
Optimized app memory usage
But .NET Native involves more than a compilation to native code. It transforms the way that .NET Framework apps
are built and executed. In particular:
During precompilation, required portions of the .NET Framework are statically linked into your app. This
allows the app to run with app-local libraries of the .NET Framework, and the compiler to perform global
analysis to deliver performance wins. As a result, apps launch consistently faster even after .NET Framework
updates.
The .NET Native runtime is optimized for static precompilation and thus is able to offer superior
performance. At the same time, it retains the core reflection features that developers find so productive.
.NET Native uses the same back end as the C++ compiler, which is optimized for static precompilation
scenarios.
.NET Native is able to bring the performance benefits of C++ to managed code developers because it uses the
same or similar tools as C++ under the hood, as shown in this table.
For Windows apps for Windows 10, you upload .NET Native Code Compilation binaries in app packages (.appx
files) to the Windows Store.
In This Section
For more information about developing apps with .NET Native Code Compilation, see these topics:
Getting Started with .NET Native Code Compilation: The Developer Experience Walkthrough
.NET Native and Compilation: How .NET Native compiles your project to native code.
Reflection and .NET Native
APIs That Rely on Reflection
Reflection API Reference
Runtime Directives (rd.xml) Configuration File Reference
Serialization and Metadata
Migrating Your Windows Store App to .NET Native
.NET Native General Troubleshooting
See Also
.NET Native FAQ
Windows Identity Foundation
7/29/2017 • 1 min to read • Edit Online
To debug a .NET Framework application, the compiler and runtime environment must be configured to enable a
debugger to attach to the application and to produce both symbols and line maps, if possible, for the application
and its corresponding Microsoft intermediate language (MSIL). After a managed application has been debugged, it
can be profiled to boost performance. Profiling evaluates and describes the lines of source code that generate the
most frequently executed code, and how much time it takes to execute them.
.NET Framework applications are easily debugged by using Visual Studio, which handles many of the configuration
details. If Visual Studio is not installed, you can examine and improve the performance of .NET Framework
applications by using the debugging classes in the .NET Framework System.Diagnostics namespace. This
namespace includes the Trace, Debug, and TraceSource classes for tracing execution flow, and the Process,
EventLog, and PerformanceCounter classes for profiling code.
In This Section
Enabling JIT-Attach Debugging
Shows how to configure the registry to JIT-attach a debug engine to a .NET Framework application.
Making an Image Easier to Debug
Shows how to turn JIT tracking on and optimization off to make an assembly easier to debug.
Tracing and Instrumenting Applications
Describes how to monitor the execution of your application while it is running, and how to instrument it to display
how well it is performing or whether something has gone wrong.
Diagnosing Errors with Managed Debugging Assistants
Describes managed debugging assistants (MDAs), which are debugging aids that work in conjunction with the
common language runtime (CLR) to provide information on runtime state.
Enhancing Debugging with the Debugger Display Attributes
Describes how the developer of a type can specify what that type will look like when it is displayed in a debugger.
Performance Counters
Describes the counters that you can use to track the performance of an application.
Related Sections
Debugging ASP.NET and AJAX Applications
Provides prerequisites and instructions for how to debug an ASP.NET application during development or after
deployment.
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.
Deploying the .NET Framework and Applications
7/29/2017 • 5 min to read • Edit Online
This article helps you get started deploying the .NET Framework with your application. Most of the information is
intended for developers, OEMs, and enterprise administrators. Users who want to install the .NET Framework on
their computers should read Installing the .NET Framework.
Related Topics
TITLE DESCRIPTION
How the Runtime Locates Assemblies Describes how the common language runtime determines
which assembly to use to fulfill a binding request.
Best Practices for Assembly Loading Discusses ways to avoid problems of type identity that can
lead to InvalidCastException, MissingMethodException, and
other errors.
Reducing System Restarts During .NET Framework 4.5 Describes the Restart Manager, which prevents reboots
Installations whenever possible, and explains how applications that install
the .NET Framework can take advantage of it.
Deployment Guide for Administrators Explains how a system administrator can deploy the .NET
Framework and its system dependencies across a network by
using System Center Configuration Manager (SCCM).
TITLE DESCRIPTION
Deployment Guide for Developers Explains how developers can install .NET Framework on their
users' computers with their applications.
Deploying Applications, Services, and Components Discusses deployment options in Visual Studio, including
instructions for publishing an application using the ClickOnce
and Windows Installer technologies.
Publishing ClickOnce Applications Describes how to package a Windows Forms application and
deploy it with ClickOnce to client computers on a network.
Packaging and Deploying Resources Describes the hub and spoke model that the .NET Framework
uses to package and deploy resources; covers resource
naming conventions, fallback process, and packaging
alternatives.
Deploying an Interop Application Explains how to ship and install interop applications, which
typically include a .NET Framework client assembly, one or
more interop assemblies representing distinct COM type
libraries, and one or more registered COM components.
How to: Get Progress from the .NET Framework 4.5 Installer Describes how to silently launch and track the .NET
Framework setup process while showing your own view of the
setup progress.
See Also
Development Guide
.NET Framework Performance
7/29/2017 • 5 min to read • Edit Online
If you want to create apps with great performance, you should design and plan for performance just as you would
design any other feature of your app. You can use the tools provided by Microsoft to measure your app's
performance, and, if needed, make improvements to memory use, code throughput, and responsiveness. This topic
lists the performance analysis tools that Microsoft provides, and provides links to other topics that cover
performance for specific areas of app development.
Analyzing performance
As part of your overall development plan, set points during development where you will measure the performance
of your app and compare the results with the goals you set previously. Measure your app in the environment and
hardware that you expect your users to have. By analyzing your app’s performance early and often you can change
architectural decisions that would be costly and expensive to fix later in the development cycle. The following
sections describe performance tools you can use to analyze your apps and discuss event tracing, which is used by
these tools.
Performance tools
Here are some of the performance tools you can use with your .NET Framework apps.
TOOL DESCRIPTION
Visual Studio Performance Analysis Use to analyze the CPU usage of your .NET Framework apps
that will be deployed to computers that are running the
Windows operating system.
Windows Phone Application Analysis Use to analyze the CPU and memory, network data transfer
rate, app responsiveness, and battery consumption in your
Windows Phone apps.
Windows Performance Analyzer Use to determine overall system performance such as your
app's memory and storage use when multiple apps are
running on the same computer. This tool is available from the
download center as part of the Windows Assessment and
Deployment Kit (ADK) for Windows 8. For more information,
see Windows Performance Analyzer.
.NET Framework apps for all platforms Garbage Collection and Performance
Performance Tips
Windows 8.x Store apps written in C++, C#, and Visual Basic Performance best practices for Windows Store apps using
C++, C#, and Visual Basic
APP TYPE SEE
Windows Forms Practical Tips for Boosting the Performance of Windows Forms
Apps
Related Topics
TITLE DESCRIPTION
Caching in .NET Framework Applications Describes techniques for caching data to improve performance
in your app.
Writing Large, Responsive .NET Framework Apps Provides performance tips gathered from rewriting the C# and
Visual Basic compilers in managed code, and includes several
real examples from the C# compiler.
Dynamic Programming in the .NET Framework
7/29/2017 • 1 min to read • Edit Online
This section of the documentation provides information about dynamic programming in the .NET Framework.
In This Section
Reflection
Describes how to use reflection to work with objects at run time.
Emitting Dynamic Methods and Assemblies
Describes how to create methods and assemblies at run time by using Reflection.Emit.
Dynamic Language Runtime Overview
Describes the features of the dynamic language runtime.
Dynamic Source Code Generation and Compilation
Describes how to generate and compile dynamic source code.
Related Sections
Development Guide
Advanced Reading for the .NET Framework
Managed Extensibility Framework (MEF)
7/29/2017 • 16 min to read • Edit Online
This topic provides an overview of the Managed Extensibility Framework introduced in the .NET Framework 4.
What is MEF?
The Managed Extensibility Framework or MEF is a library for creating lightweight, extensible applications. It allows
application developers to discover and use extensions with no configuration required. It also lets extension
developers easily encapsulate code and avoid fragile hard dependencies. MEF not only allows extensions to be
reused within applications, but across applications as well.
NOTE
The purpose of SimpleCalculator is to demonstrate the concepts and syntax of MEF, rather than to necessarily provide a
realistic scenario for its use. Many of the applications that would benefit most from the power of MEF are more complex than
SimpleCalculator. For more extensive examples, see the Managed Extensibility Framework on Codeplex.
To start, in Visual Studio 2010, create a new Console Application project named SimpleCalculator . Add a reference
to the System.ComponentModel.Composition assembly, where MEF resides. Open Module1.vb or Program.cs and
add Imports or using statements for System.ComponentModel.Composition and
System.ComponentModel.Composition.Hosting. These two namespaces contain MEF types you will need to
develop an extensible application. In Visual Basic, add the Public keyword to the line that declares the Module1
module.
In order to discover the parts available to it, the composition containers makes use of a catalog. A catalog is an
object that makes available parts discovered from some source. MEF provides catalogs to discover parts from a
provided type, an assembly, or a directory. Application developers can easily create new catalogs to discover parts
from other sources, such as a Web service.
Add the following constructor to the Program class:
'Adds all the parts found in the same assembly as the Program class
catalog.Catalogs.Add(New AssemblyCatalog(GetType(Program).Assembly))
private Program()
{
//An aggregate catalog that combines multiple catalogs
var catalog = new AggregateCatalog();
//Adds all the parts found in the same assembly as the Program class
catalog.Catalogs.Add(new AssemblyCatalog(typeof(Program).Assembly));
The call to ComposeParts tells the composition container to compose a specific set of parts, in this case the current
instance of Program . At this point, however, nothing will happen, since Program has no imports to fill.
Imports and Exports with Attributes
First, you have Program import a calculator. This allows the separation of user interface concerns, such as the
console input and output that will go into Program , from the logic of the calculator.
Add the following code to the Program class:
<Import(GetType(ICalculator))>
Public Property calculator As ICalculator
[Import(typeof(ICalculator))]
public ICalculator calculator;
Notice that the declaration of the calculator object is not unusual, but that it is decorated with the ImportAttribute
attribute. This attribute declares something to be an import; that is, it will be filled by the composition engine when
the object is composed.
Every import has a contract, which determines what exports it will be matched with. The contract can be an
explicitly specified string, or it can be automatically generated by MEF from a given type, in this case the interface
ICalculator . Any export declared with a matching contract will fulfill this import. Note that while the type of the
calculator object is in fact ICalculator , this is not required. The contract is independent from the type of the
importing object. (In this case, you could leave out the typeof(ICalculator) . MEF will automatically assume the
contract to be based on the type of the import unless you specify it explicitly.)
Add this very simple interface to the module or SimpleCalculator namespace:
Now that you have defined ICalculator , you need a class that implements it. Add the following class to the
module or SimpleCalculator namespace:
<Export(GetType(ICalculator))>
Public Class MySimpleCalculator
Implements ICalculator
End Class
[Export(typeof(ICalculator))]
class MySimpleCalculator : ICalculator
{
Here is the export that will match the import in Program . In order for the export to match the import, the export
must have the same contract. Exporting under a contract based on typeof(MySimpleCalculator) would produce a
mismatch, and the import would not be filled; the contract needs to match exactly.
Since the composition container will be populated with all the parts available in this assembly, the
MySimpleCalculator part will be available. When the constructor for Program performs composition on the
Program object, its import will be filled with a MySimpleCalculator object, which will be created for that purpose.
The user interface layer ( Program ) does not need to know anything else. You can therefore fill in the rest of the user
interface logic in the Main method.
Add the following code to the Main method:
Sub Main()
Dim p As New Program()
Dim s As String
Console.WriteLine("Enter Command:")
While (True)
s = Console.ReadLine()
Console.WriteLine(p.calculator.Calculate(s))
End While
End Sub
This code simply reads a line of input and calls the Calculate function of ICalculator on the result, which it writes
back to the console. That is all the code you need in Program . All the rest of the work will happen in the parts.
<ImportMany()>
Public Property operations As IEnumerable(Of Lazy(Of IOperation, IOperationData))
[ImportMany]
IEnumerable<Lazy<IOperation, IOperationData>> operations;
Lazy<T,TMetadata> is a type provided by MEF to hold indirect references to exports. Here, in addition to the
exported object itself, you also get export metadata, or information that describes the exported object. Each
Lazy<T,TMetadata> contains an IOperation object, representing an actual operation, and an IOperationData
object, representing its metadata.
Add the following simple interfaces to the module or SimpleCalculator namespace:
Public Interface IOperation
Function Operate(ByVal left As Integer, ByVal right As Integer) As Integer
End Interface
In this case, the metadata for each operation is the symbol that represents that operation, such as +, -, *, and so on.
To make the addition operation available, add the following class to the module or SimpleCalculator namespace:
<Export(GetType(IOperation))>
<ExportMetadata("Symbol", "+"c)>
Public Class Add
Implements IOperation
Public Function Operate(ByVal left As Integer, ByVal right As Integer) As Integer Implements
IOperation.Operate
Return left + right
End Function
End Class
[Export(typeof(IOperation))]
[ExportMetadata("Symbol", '+')]
class Add: IOperation
{
public int Operate(int left, int right)
{
return left + right;
}
}
The ExportAttribute attribute functions as it did before. The ExportMetadataAttribute attribute attaches metadata, in
the form of a name-value pair, to that export. While the Add class implements IOperation , a class that implements
IOperationData is not explicitly defined. Instead, a class is implicitly created by MEF with properties based on the
names of the metadata provided. (This is one of several ways to access metadata in MEF.)
Composition in MEF is recursive. You explicitly composed the Program object, which imported an ICalculator that
turned out to be of type MySimpleCalculator . MySimpleCalculator , in turn, imports a collection of IOperation
objects, and that import will be filled when MySimpleCalculator is created, at the same time as the imports of
Program . If the Add class declared a further import, that too would have to be filled, and so on. Any import left
unfilled results in a composition error. (It is possible, however, to declare imports to be optional or to assign them
default values.)
Calculator Logic
With these parts in place, all that remains is the calculator logic itself. Add the following code in the
MySimpleCalculator class to implement the Calculate method:
try
{
//separate out the operands
left = int.Parse(input.Substring(0, fn));
right = int.Parse(input.Substring(fn + 1));
}
catch
{
return "Could not parse command.";
}
operation = input[fn];
The initial steps parse the input string into left and right operands and an operator character. In the foreach loop,
every member of the operations collection is examined. These objects are of type Lazy<T,TMetadata>, and their
metadata values and exported object can be accessed with the Metadata property and the Valueproperty
respectively. In this case, if the Symbol property of the IOperationData object is discovered to be a match, the
calculator calls the Operate method of the IOperation object and returns the result.
To complete the calculator, you also need a helper method that returns the position of the first non-digit character
in a string. Add the following helper method to the MySimpleCalculator class:
Private Function FindFirstNonDigit(ByVal s As String) As Integer
For i = 0 To s.Length
If (Not (Char.IsDigit(s(i)))) Then Return i
Next
Return -1
End Function
You should now be able to compile and run the project. In Visual Basic, make sure that you added the Public
keyword to Module1 . In the console window, type an addition operation, such as "5+3", and the calculator will
return the results. Any other operator will result in the "Operation Not Found!" message.
<Export(GetType(IOperation))>
<ExportMetadata("Symbol", "-"c)>
Public Class Subtract
Implements IOperation
Public Function Operate(ByVal left As Integer, ByVal right As Integer) As Integer Implements
IOperation.Operate
Return left - right
End Function
End Class
[Export(typeof(IOperation))]
[ExportMetadata("Symbol", '-')]
class Subtract : IOperation
{
public int Operate(int left, int right)
{
return left - right;
}
}
Compile and run the project. Type a subtraction operation, such as "5-3". The calculator now supports subtraction
as well as addition.
catalog.Catalogs.Add(New DirectoryCatalog("C:\SimpleCalculator\SimpleCalculator\Extensions"))
catalog.Catalogs.Add(new DirectoryCatalog("C:\\SimpleCalculator\\SimpleCalculator\\Extensions"));
Replace the example path with the path to your Extensions directory. (This absolute path is for debugging purposes
only. In a production application, you would use a relative path.) The DirectoryCatalog will now add any parts found
in any assemblies in the Extensions directory to the composition container.
In the ExtendedOperations project, add references to SimpleCalculator and System.ComponentModel.Composition.
In the ExtendedOperations class file, add an Imports or a using statement for
System.ComponentModel.Composition. In Visual Basic, also add an Imports statement for SimpleCalculator. Then
add the following class to the ExtendedOperations class file:
<Export(GetType(SimpleCalculator.IOperation))>
<ExportMetadata("Symbol", "%"c)>
Public Class Modulo
Implements IOperation
Public Function Operate(ByVal left As Integer, ByVal right As Integer) As Integer Implements
IOperation.Operate
Return left Mod right
End Function
End Class
[Export(typeof(SimpleCalculator.IOperation))]
[ExportMetadata("Symbol", '%')]
public class Mod : SimpleCalculator.IOperation
{
public int Operate(int left, int right)
{
return left % right;
}
}
Note that in order for the contract to match, the ExportAttribute attribute must have the same type as the
ImportAttribute.
Compile and run the project. Test the new Mod (%) operator.
Conclusion
This topic covered the basic concepts of MEF.
Parts, catalogs, and the composition container
Parts and the composition container are the basic building blocks of a MEF application. A part is any object
that imports or exports a value, up to and including itself. A catalog provides a collection of parts from a
particular source. The composition container uses the parts provided by a catalog to perform composition,
the binding of imports to exports.
Imports and exports
Imports and exports are the way by which components communicate. With an import, the component
specifies a need for a particular value or object, and with an export it specifies the availability of a value. Each
import is matched with a list of exports by way of its contract.
Where Do I Go Now?
To download the complete code for this example, see the SimpleCalculator sample.
For more information and code examples, see Managed Extensibility Framework. For a list of the MEF types, see the
System.ComponentModel.Composition namespace.
Add-ins and Extensibility
7/29/2017 • 4 min to read • Edit Online
Add-ins provide extended features or services for a host application. The .NET Framework provides a programming
model that developers can use to develop add-ins and activate them in their host application. The model achieves
this by constructing a communication pipeline between the host and the add-in. The model is implemented by
using the types in the System.AddIn, System.AddIn.Hosting, System.AddIn.Pipeline, and System.AddIn.Contract
namespaces.
This overview contains the following sections:
Add-in Model
Distinguishing Between Add-ins and Hosts
Related Topics
Reference
NOTE
You can find additional sample code, and customer technology previews of tools for building add-in pipelines, at the
Managed Extensibility and Add-In Framework site on CodePlex.
Add-in Model
The add-in model consists of a series of segments that make up the add-in pipeline (also known as the
communication pipeline), that is responsible for all communication between the add-in and the host. The pipeline is
a symmetrical communication model of segments that exchange data between an add-in and its host. Developing
these segments between the host and the add-in provides the required layers of abstraction that support
versioning and isolation of the add-in.
The following illustration shows the pipeline.
Add-in pipeline
The assemblies for these segments are not required to be in the same application domain. You can load an add-in
into its own new application domain, into an existing application domain, or even into the host's application
domain. You can load multiple add-ins into the same application domain, which enables the add-ins to share
resources and security contexts.
The add-in model supports, and recommends, an optional boundary between the host and the add-in, which is
called the isolation boundary (also known as a remoting boundary). This boundary can be an application domain or
process boundary.
The contract segment in the middle of the pipeline is loaded into both the host's application domain and the add-
in's application domain. The contract defines the virtual methods that the host and the add-in use to exchange
types with each other.
To pass through the isolation boundary, types must be either contracts or serializable types. Types that are not
contracts or serializable types must be converted to contracts by the adapter segments in the pipeline.
The view segments of the pipeline are abstract base classes or interfaces that provide the host and the add-in with a
view of the methods that they share, as defined by the contract.
For more information about developing pipeline segments, see Pipeline Development.
The sections that follow describe the features of the add-in model.
Independent Versioning
The add-in model allows hosts and add-ins to version independently. As a result, the add-in model enables the
following scenarios:
Creating an adapter that enables a host to use an add-in built for a previous version of the host.
Creating an adapter that enables a host to use an add-in built for a later version of the host.
Creating an adapter that enables a host to use add-ins built for a different host.
Discovery and Activation
You can activate an add-in by using a token from a collection that represents the add-ins found from an
information store. Add-ins are found by searching for the type that defines the host's view of the add-in. You can
also find a specific add-in by the type that defines the add-in. The information store consists of two cache files: the
pipeline store and the add-in store.
For information about updating and rebuilding the information store, see Add-in Discovery. For information about
activating add-ins, see Add-in Activation and How to: Activate Add-ins with Different Isolation and Security.
Isolation Levels and External Processes
The add-in model supports several levels of isolation between an add-in and its host or between add-ins. Starting
from the least isolated, these levels are as follows:
The add-in runs in the same application domain as the host. This is not recommended because you lose the
isolation and unloading capabilities that you get when you use different application domains.
Multiple add-ins are loaded into the same application domain that is different from the application domain
used by the host.
Each add-in is loaded exclusively into its own application domain. This is the most common level of isolation.
Multiple add-ins are loaded into the same application domain in an external process.
Each add-in is loaded exclusively into its own application domain in an external process. This is the most
isolated scenario.
For more information about using external processes, see How to: Activate Add-ins with Different Isolation and
Security.
Lifetime Management
Because the add-in model spans application domain and process boundaries, garbage collection by itself is not
sufficient to release and reclaim objects. The add-in model provides a lifetime management mechanism that uses
tokens and reference counting, and usually does not require additional programming. For more information, see
Lifetime Management.
Back to top
Distinguishing Between Add-ins and Hosts
The difference between an add-in and a host is merely that the host is the one that activates the add-in. The host
can be the larger of the two, such as a word processing application and its spell checkers; or the host can be the
smaller of the two, such as an instant messaging client that embeds a media player. The add-in model supports
add-ins in both client and server scenarios. Examples of server add-ins include add-ins that provide mail servers
with virus scanning, spam filters, and IP protection. Client add-in examples include reference add-ins for word
processors, specialized features for graphics programs and games, and virus scanning for local e-mail clients.
Back to top
Related Topics
TITLE DESCRIPTION
Application Domains and Assemblies Describes the relationship between application domains, which
provide an isolation boundary for security, reliability, and
versioning, and assemblies.
Back to top
Reference
System.AddIn
System.AddIn.Contract
System.AddIn.Hosting
System.AddIn.Pipeline
Back to top
Interoperating with Unmanaged Code
7/29/2017 • 1 min to read • Edit Online
The .NET Framework promotes interaction with COM components, COM+ services, external type libraries, and
many operating system services. Data types, method signatures, and error-handling mechanisms vary between
managed and unmanaged object models. To simplify interoperation between .NET Framework components and
unmanaged code and to ease the migration path, the common language runtime conceals from both clients and
servers the differences in these object models.
Code that executes under the control of the runtime is called managed code. Conversely, code that runs outside the
runtime is called unmanaged code. COM components, ActiveX interfaces, and Win32 API functions are examples of
unmanaged code.
In This Section
Interoperating with Unmanaged Code How-to Topics
Provides links to all How-to topics found in the conceptual documentation for interoperating with unmanaged
code.
Exposing COM Components to the .NET Framework
Describes how to use COM components from .NET Framework applications.
Exposing .NET Framework Components to COM
Describes how to use .NET Framework components from COM applications.
Consuming Unmanaged DLL Functions
Describes how to call unmanaged DLL functions using platform invoke.
Design Considerations for Interoperation
Provides tips for writing integrated COM components.
Interop Marshaling
Describes marshaling for COM interop and platform invoke.
How to: Map HRESULTs and Exceptions
Describes the mapping between exceptions and HRESULTs.
Interoperating Using Generic Types
Describes the behavior of generic types when used in COM interop.
Related Sections
Advanced COM Interoperability
Provides links to more information about incorporating COM components into your .NET Framework application.
Unmanaged API Reference
7/29/2017 • 1 min to read • Edit Online
This section includes information on unmanaged APIs that can be used by managed-code-related applications, such
as runtime hosts, compilers, disassemblers, obfuscators, debuggers, and profilers.
In This Section
Common Data Types
Lists the common data types that are used, particularly in the unmanaged profiling and debugging APIs.
ALink
Describes the ALink API, which supports the creation of .NET Framework assemblies and unbound modules.
Authenticode
Supports the Authenticode XrML license creation and verification module.
Constants
Describes the constants that are defined in CorSym.idl.
Custom Interface Attributes
Describes component object model (COM) custom interface attributes.
Debugging
Describes the debugging API, which enables a debugger to debug code that runs in the common language runtime
(CLR) environment.
Diagnostics Symbol Store
Describes the diagnostics symbol store API, which enables a compiler to generate symbol information for use by a
debugger.
Fusion
Describes the fusion API, which enables a runtime host to access the properties of an application's resources in
order to locate the correct versions of those resources for the application.
Hosting
Describes the hosting API, which enables unmanaged hosts to integrate the CLR into their applications.
Metadata
Describes the metadata API, which enables a client such as a compiler to generate or access a component's
metadata without the types being loaded by the CLR.
Profiling
Describes the profiling API, which enables a profiler to monitor a program's execution by the CLR.
Strong Naming
Describes the strong naming API, which enables a client to administer strong name signing for assemblies.
Tlbexp Helper Functions
Describes the two helper functions and interface used by the Type Library Exporter (Tlbexp.exe) during the
assembly-to-type-library conversion process.
Related Sections
Development Guide
Advanced Reading for the .NET Framework
XAML Services
7/29/2017 • 8 min to read • Edit Online
This topic describes the capabilities of a technology set known as .NET Framework XAML Services. The majority of
the services and APIs described are located in the assembly System.Xaml, which is an assembly introduced with the
.NET Framework 4 set of .NET core assemblies. Services include readers and writers, schema classes and schema
support, factories, attributing of classes, XAML language intrinsic support, and other XAML language features.
The .NET Framework tools make it easier for you to create, deploy, and manage applications and components that
target the .NET Framework.
Most of the .NET Framework tools described in this section are automatically installed with Visual Studio. (For
installation information , see the Visual Studio Downloads.)
You can run all the tools from the command line with the exception of the Assembly Cache Viewer (Shfusion.dll).
You must access Shfusion.dll from File Explorer.
The best way to run the command-line tools is by using the Developer Command Prompt for Visual Studio. These
utilities enable you to run the tools easily, without navigating to the installation folder. For more information, see
Command Prompts.
NOTE
Some tools are specific to either 32-bit computers or 64-bit computers. Be sure to run the appropriate version of the tool for
your computer.
In This Section
Al.exe (Assembly Linker)
Generates a file that has an assembly manifest from modules or resource files.
Aximp.exe (Windows Forms ActiveX Control Importer)
Converts type definitions in a COM type library for an ActiveX control into a Windows Forms control.
Caspol.exe (Code Access Security Policy Tool)
Enables you to view and configure security policy for the machine policy level, the user policy level, and the
enterprise policy level. In the .NET Framework 4 and later, this tool does not affect code access security (CAS) policy
unless the <legacyCasPolicy> element is set to true . For more information, see Security Changes.
Cert2spc.exe (Software Publisher Certificate Test Tool)
Creates a Software Publisher's Certificate (SPC) from one or more X.509 certificates. This tool is for testing
purposes only.
Certmgr.exe (Certificate Manager Tool)
Manages certificates, certificate trust lists (CTLs), and certificate revocation lists (CRLs).
Clrver.exe (CLR Version Tool)
reports all the installed versions of the common language runtime (CLR) on the computer.
CorFlags.exe (CorFlags Conversion Tool)
Lets you configure the CorFlags section of the header of a portable executable (PE) image.
Fuslogvw.exe (Assembly Binding Log Viewer)
Displays information about assembly binds to help you diagnose why the .NET Framework cannot locate an
assembly at run time.
Gacutil.exe (Global Assembly Cache Tool)
Lets you view and manipulate the contents of the global assembly cache and download cache.
Ilasm.exe (IL Assembler)
Generates a portable executable (PE) file from intermediate language (IL). You can run the resulting executable to
determine whether the IL performs as expected.
Ildasm.exe (IL Disassembler)
Takes a portable executable (PE) file that contains intermediate language (IL) code and creates a text file that can be
input to the IL Assembler (Ilasm.exe).
Installutil.exe (Installer Tool)
Enables you to install and uninstall server resources by executing the installer components in a specified assembly.
(Works with classes in the System.Configuration.Install namespace.) Enables you to install and uninstall server
resources by executing the installer components in a specified assembly. (Works with classes in the
System.Configuration.Install namespace.)
Lc.exe (License Compiler)
Reads text files that contain licensing information and produces a .licenses file that can be embedded in a common
language runtime executable as a resource. Reads text files that contain licensing information and produces a
.licenses file that can be embedded in a common language runtime executable as a resource.
Mage.exe (Manifest Generation and Editing Tool)
Lets you create, edit, and sign application and deployment manifests. As a command-line tool, Mage.exe can be run
from both batch scripts and other Windows-based applications, including ASP.NET applications.
MageUI.exe (Manifest Generation and Editing Tool, Graphical Client)
Supports the same functionality as the command-line tool Mage.exe, but uses a Windows-based user interface (UI).
Supports the same functionality as the command-line tool Mage.exe, but uses a Windows-based user interface (UI).
MDbg.exe (.NET Framework Command-Line Debugger)
Helps tools vendors and application developers find and fix bugs in programs that target the .NET Framework
common language runtime. This tool uses the runtime debugging API to provide debugging services.
Mgmtclassgen.exe (Management Strongly Typed Class Generator)
Enables you to generate an early-bound managed class for a specified Windows Management Instrumentation
(WMI) class.
Mpgo.exe (Managed Profile Guided Optimization Tool)
Enables you to tune native image assemblies using common end-user scenarios. Mpgo.exe allows the generation
and consumption of profile data for native image application assemblies (not the .NET Framework assemblies)
using training scenarios selected by the application developer.
Ngen.exe (Native Image Generator)
Improves the performance of managed applications through the use of native images (files containing compiled
processor-specific machine code). The runtime can use native images from the cache instead of using the just-in-
time (JIT) compiler to compile the original assembly.
Peverify.exe (PEVerify Tool)
Helps you verify whether your Microsoft intermediate language (MSIL) code and associated metadata meet type
safety requirements. Helps you verify whether your Microsoft intermediate language (MSIL) code and associated
metadata meet type safety requirements.
Regasm.exe (Assembly Registration Tool)
Reads the metadata within an assembly and adds the necessary entries to the registry. This enables COM clients to
appear as .NET Framework classes.
Regsvcs.exe (.NET Services Installation Tool)
Loads and registers an assembly, generates and installs a type library into a specified COM+ version 1.0
application, and configures services that you have added programmatically to a class.
Resgen.exe (Resource File Generator)
Converts text (.txt or .restext) files and XML-based resource format (.resx) files to common language runtime binary
(.resources) files that can be embedded in a runtime binary executable or compiled into satellite assemblies.
SecAnnotate.exe (.NET Security Annotator Tool)
Identifies the SecurityCritical and SecuritySafeCritical portions of an assembly. Identifies the SecurityCritical and
SecuritySafeCritical portions of an assembly.
Related Sections
Tools
Includes tools such as the isXPS Conformance tool (isXPS.exe) and performance profiling tools.
Windows Communication Foundation Tools
Includes tools that make it easier for you to create, deploy, and manage Windows Communication Foundation
(WCF) applications.
Additional class libraries and APIs
7/29/2017 • 1 min to read • Edit Online
The .NET Framework is constantly evolving and in order to improve cross-platform development or to introduce
new functionality early to our customers, we release new features out of band (OOB). This topic lists the OOB
projects that we provide documentation for.
In addition, some libraries target specific platforms or implementations of the .NET Framework. For example, the
CodePagesEncodingProvider class makes code page encodings available to UWP apps developed using the .NET
Framework. This topic lists these libraries as well.
OOB projects
PROJECT DESCRIPTION
Platform-specific libraries
PROJECT DESCRIPTION
Private APIs
These APIs support the product infrastructure and are not intended/supported to be used directly from your code.
API NAME
System.Net.Connection Class
System.Net.Connection.m_WriteList Field
System.Net.ConnectionGroup Class
System.Net.ConnectionGroup.m_ConnectionList Field
API NAME
System.Net.HttpWebRequest._HttpResponse Field
System.Net.HttpWebRequest._AutoRedirects Field
System.Net.ServicePoint.m_ConnectionGroupList Field
System.Net.ServicePointManager.s_ServicePointTable Field
System.Windows.Diagnostics.VisualDiagnostics.s_isDebuggerCheckDisabledForTestPurposes Field
System.Windows.Forms.Design.DataMemberFieldEditor Class
System.Windows.Forms.Design.DataMemberListEditor Class
See also
The .NET Framework and Out-of-Band Releases
C# Guide
7/29/2017 • 3 min to read • Edit Online
The C# guide provides a wealth of information about the C# language. This site has many different audiences.
Depending on your experience with programming, or with the C# language and .NET, you may wish to explore
different sections of this guide.
For brand-new developers:
Start with our tutorials section. These tutorials show you how to create C# programs from scratch. The
tutorials provide a step-by-step process to create programs. You'll learn the language concepts, and how
to build C# programs on your own. If you prefer reading overview information first, try our tour of the
C# language. It explains the concepts of the C# language. After reading this, you'll have a basic
understanding of the language, and be ready to try the tutorials, or build something on your own.
For developers new to C#:
If you've done development before, but are new to C#, read the tour of the C# language. You will learn
the basic syntax and structure for the language, and you can use the language tour to contrast C# with
other languages you've used. You can also browse the tutorials to try basic C# programs.
Experienced C# developers:
If you've used C# before, you should start by reading what's in the latest version of the language. Check
out What's new in C# for the new features in the current version.
This section provides short, simple tutorials that let you quickly build an application using C# and .NET Core. There
are getting started topics for Visual Studio 2017 and Visual Studio Code. You can build either a simple Hello World
application or, if you have Visual Studio 2017, a simple class library that can be used by other applications.
The following topics are available:
Building a C# Hello World application with .NET Core in Visual Studio 2017
Visual Studio 2017, the latest release of Visual Studio, lets you code, compile, run, debug, profile, and
publish your applications from a integrated development environment for Windows.
The topic lets you create and run a simple Hello World application and then modify it to run a slightly more
interactive Hello World application. Once you've finished building and running your application, you can
also learn how to debug it and how to publish it so that it can be run on any platform supported by .NET
Core.
Building a class library with C# and .NET Core in Visual Studio 2017
A class library lets you define types and type members that can be called from another application. This
topic lets you create a class library with a single method that determines whether a string begins with an
uppercase character. Once you've finished building the library, you can develop a unit test to ensure that it
works as expected, and then you can make it available to applications that want to consume it.
Get started with C# and Visual Studio Code
Visual Studio Code is a free code editor optimized for building and debugging modern web and cloud
applications. It supports IntelliSense and is available for Linux, macOS, and Windows.
This topic shows you how to create and run a simple Hello World application with Visual Studio Code and
.NET Core.
C# Tutorials
7/29/2017 • 1 min to read • Edit Online
The following tutorials enable you to build C# programs using .NET Core:
Console Application: demonstrates Console I/O, the structure of a Console application, and the basics of the
Task based asynchronous programming model.
REST Client: demonstrates web communications, JSON serialization, and Object Oriented features in the C#
language.
Inheritance in C# and .NET: demonstrates inheritance in C#, including the use of inheritance to define base
classes, abstract base classes, and derived classes.
Working with LINQ: demonstrates many of the features of LINQ and the language elements that support it.
Microservices hosted in Docker: demonstrates building an ASP.NET Core microservice and hosting it in
Docker.
Inheritance: demonstrates how class and interface inheritance provide code reuse in C#.
String Interpolation: demonstrates many of the uses for the $ string interpolation in C#.
Using Attributes: how to create and use attributes in C#.
A Tour of the C# Language
7/29/2017 • 4 min to read • Edit Online
C# (pronounced "See Sharp") is a simple, modern, object-oriented, and type-safe programming language. C# has
its roots in the C family of languages and will be immediately familiar to C, C++, Java, and JavaScript
programmers.
C# is an object-oriented language, but C# further includes support for component-oriented programming.
Contemporary software design increasingly relies on software components in the form of self-contained and self-
describing packages of functionality. Key to such components is that they present a programming model with
properties, methods, and events; they have attributes that provide declarative information about the component;
and they incorporate their own documentation. C# provides language constructs to support directly these
concepts, making C# a very natural language in which to create and use software components.
Several C# features aid in the construction of robust and durable applications: Garbage collection automatically
reclaims memory occupied by unreachable unused objects; exception handling provides a structured and
extensible approach to error detection and recovery; and the type-safe design of the language makes it
impossible to read from uninitialized variables, to index arrays beyond their bounds, or to perform unchecked type
casts.
C# has a unified type system. All C# types, including primitive types such as int and double , inherit from a
single root object type. Thus, all types share a set of common operations, and values of any type can be stored,
transported, and operated upon in a consistent manner. Furthermore, C# supports both user-defined reference
types and value types, allowing dynamic allocation of objects as well as in-line storage of lightweight structures.
To ensure that C# programs and libraries can evolve over time in a compatible manner, much emphasis has been
placed on versioning in C#’s design. Many programming languages pay little attention to this issue, and, as a
result, programs written in those languages break more often than necessary when newer versions of dependent
libraries are introduced. Aspects of C#’s design that were directly influenced by versioning considerations include
the separate virtual and override modifiers, the rules for method overload resolution, and support for explicit
interface member declarations.
Hello world
The "Hello, World" program is traditionally used to introduce a programming language. Here it is in C#:
using System;
class Hello
{
static void Main()
{
Console.WriteLine("Hello, World");
}
}
C# source files typically have the file extension .cs . Assuming that the "Hello, World" program is stored in the file
hello.cs , the program might be compiled using the command line:
csc hello.cs
which produces an executable assembly named hello.exe. The output produced by this application when it is run is:
Hello, World
IMPORTANT
The csc command compiles for the full framework, and may not be available on all platforms.
The "Hello, World" program starts with a using directive that references the System namespace. Namespaces
provide a hierarchical means of organizing C# programs and libraries. Namespaces contain types and other
namespaces—for example, the System namespace contains a number of types, such as the Console class
referenced in the program, and a number of other namespaces, such as IO and Collections . A using directive
that references a given namespace enables unqualified use of the types that are members of that namespace.
Because of the using directive, the program can use Console.WriteLine as shorthand for
System.Console.WriteLine .
The Hello class declared by the "Hello, World" program has a single member, the method named Main . The
Main method is declared with the static modifier. While instance methods can reference a particular enclosing
object instance using the keyword this , static methods operate without reference to a particular object. By
convention, a static method named Main serves as the entry point of a program.
The output of the program is produced by the WriteLine method of the Console class in the System namespace.
This class is provided by the standard class libraries, which, by default, are automatically referenced by the
compiler.
There's a lot more to learn about C#. The following topics provide an overview of the elements of the C# language.
These overviews will provide basic information about all elements of the language and give you the information
necessary to dive deeper into elements of the C# language:
Program Structure
Learn the key organizational concepts in the C# language: programs, namespaces, types, members,
and assemblies.
Types and Variables
Learn about value types, reference types, and variables in the C# language.
Expressions
Expressions are constructed from operands and operators. Expressions produce a value.
Statements
You use statements to express the actions of a program.
Classes and objects
Classes are the most fundamental of C#'s types. Objects are instances of a class. Classes are built using
members, which are also covered in this topic.
Structs
Structs are data structures that, unlike classes, are value types.
Arrays
An array is a data structure that contains a number of variables that are accessed through computed
indices.
Interfaces
An interface defines a contract that can be implemented by classes and structs. An interface can contain
methods, properties, events, and indexers. An interface does not provide implementations of the
members it defines—it merely specifies the members that must be supplied by classes or structs that
implement the interface.
Enums
An enum type is a distinct value type with a set of named constants.
Delegates
A delegate type represents references to methods with a particular parameter list and return type.
Delegates make it possible to treat methods as entities that can be assigned to variables and passed as
parameters. Delegates are similar to the concept of function pointers found in some other languages,
but unlike function pointers, delegates are object-oriented and type-safe.
Attributes
Attributes enable programs to specify additional declarative information about types, members, and
other entities.
NEXT
What's new in C#
8/30/2017 • 2 min to read • Edit Online
This page provides a roadmap of new features in each major release of the C# language. The links below provide
detailed information on the major features added in each release.
IMPORTANT
The C# language relies on types and methods in a standard library for some of the features. One example is exception
processing. Every throw statement or expression is checked to ensure the object being thrown is derived from Exception.
Similarly, every catch is checked to ensure that the type being caught is derived from Exception. Each version may add new
requirements. To use the latest language features in older environments, you may need to install specific libraries. These are
documented in the page for each specific version. You can learn more about the relationships between language and library
for background on this dependency.
C# 7.1:
This page describes the latest features in the C# language. This covers C# 7.1, currently available in
Visual Studio 2017 version 15.3, and in the .NET Core 2.0 SDK.
C# 7:
This page describes the features added in C# 7. Theses were added in Visual Studio 2017 and .NET Core
1.0 and later
C# 6:
This page describes the features that were added in C# 6. These features are available in Visual Studio
2015 for Windows developers, and on .NET Core 1.0 for developers exploring C# on macOS and Linux.
Cross Platform Support:
C#, through .NET Core support, runs on multiple platforms. If you are interested in trying C# on macOS,
or on one of the many supported Linux distributions, learn more about .NET Core.
Previous Versions
The following lists key features that were introduced in previous versions of the C# language and Visual Studio
.NET.
Visual Studio .NET 2013:
This version of Visual Studio included bug fixes, performance improvements, and technology previews of
.NET Compiler Platform ("Roslyn") which became the .NET Compiler Platform SDK.
C# 5, Visual Studio .NET 2012:
Async / await , and caller information attributes.
C# 4, Visual Studio .NET 2010:
Dynamic , named arguments, optional parameters, and generic covariance and contra variance.
C# 3, Visual Studio .NET 2008:
Object and collection initializers, lambda expressions, extension methods, anonymous types, automatic
properties, local var type inference, and Language Integrated Query (LINQ).
C# 2, Visual Studio .NET 2005:
Anonymous methods, generics, nullable types, iterators/yield, static classes, and covariance and contra
variance for delegates.
C# 1.1, Visual Studio .NET 2003:
#line pragma and xml doc comments.
C# 1, Visual Studio .NET 2002:
The first release of C#.
What's new in C# 7.1
8/30/2017 • 3 min to read • Edit Online
C# 7.1 is the first point release to the C# language. It marks an increased release cadence for the language. You can
use the new features sooner, ideally when each new feature is ready. C# 7.1 adds the ability to configure the
compiler to match a specified version of the language. That enables you to separate the decision to upgrade tools
from the decision to upgrade language versions.
C# 7.1 adds the language version selection configuration element, three new language features and new compiler
behavior.
The new language features in this release are:
async Main method
The entry point for an application can have the async modifier.
default literal expressions
You can use default literal expressions in default value expressions when the target type can be inferred.
Inferred tuple element names
The names of tuple elements can be inferred from tuple initialization in many cases.
Finally, the compiler has two options /refout and /refonly that control reference assembly generation.
Alternatively, you can edit the "csproj" file and add or modify the following lines:
<PropertyGroup>
<LangVersion>latest</LangVersion>
</PropertyGroup>
NOTE
If you use the Visual Studio IDE to update your csproj files, the IDE creates separate nodes for each build configuration. You'll
typically set the value the same in all build configurations, but you need to set it explicitly for each build configuration, or
select "All Configurations" when you modify this setting. You'll see the following in your csproj file:
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
<LangVersion>latest</LangVersion>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<LangVersion>latest</LangVersion>
</PropertyGroup>
The special strings default and latest resolve to the latest major and minor language versions installed on the
build machine, respectively.
This setting decouples installing new versions of the SDK and tools in your development environment from
choosing to incorporate new language features in a project. You can install the latest SDK and tools on your build
machine. Each project can be configured to use a specific version of the language for its build.
Async main
An async main method enables you to use await in your Main method. Previously you would need to write:
If your program doesn't return an exit code, you can declare a Main method that returns a Task:
You can read more about the details in the async main topic in the programming guide.
You can now omit the type on the right-hand side of the initialization:
You can learn more about this enhancement in the C# Programming Guide topic on default value expressions.
This enhancement also changes some of the parsing rules for the default keyword.
int count = 5;
string label = "Colors used in the map";
var pair = (count: count, label: label);
The names of tuple elements can be inferred from the variables used to initialize the tuple in C# 7.1:
int count = 5;
string label = "Colors used in the map";
var pair = (count, label); // element names are "count" and "label"
You can learn more about this feature in the Tuples) topic.
out variables
The existing syntax that supports out parameters has been improved in this version.
Previously, you would need to separate the declaration of the out variable and its initialization into two different
statements:
int numericResult;
if (int.TryParse(input, out numericResult))
WriteLine(numericResult);
else
WriteLine("Could not parse input");
You can now declare out variables in the argument list of a method call, rather than writing a separate declaration
statement:
You may want to specify the type of the out variable for clarity, as shown above. However, the language does
support using an implicitly typed local variable:
return result;
Tuples
NOTE
The new tuples features require the ValueTuple types. You must add the NuGet package System.ValueTuple in order to
use it on platforms that do not include the types.
This is similar to other language features that rely on types delivered in the framework. Example include async and await
relying on the INotifyCompletion interface, and LINQ relying on IEnumerable<T> . However, the delivery mechanism is
changing as .NET is becoming more platform independent. The .NET Framework may not always ship on the same cadence as
the language compiler. When new language features rely on new types, those types will be available as NuGet packages
when the language features ship. As these new types get added to the .NET Standard API and delivered as part of the
framework, the NuGet package requirement will be removed.
C# provides a rich syntax for classes and structs that is used to explain your design intent. But sometimes that rich
syntax requires extra work with minimal benefit. You may often write methods that need a simple structure
containing more than one data element. To support these scenarios tuples were added to C#. Tuples are
lightweight data structures that contain multiple fields to represent the data members. The fields are not validated,
and you cannot define your own methods
NOTE
Tuples were available before C# 7, but they were inefficient and had no language support. This meant that tuple elements
could only be referenced as Item1 , Item2 and so on. C# 7 introduces language support for tuples, which enables semantic
names for the fields of a tuple using new, more efficient tuple types.
That assignment creates a tuple whose members are Item1 and Item2 , which you can use in the same way as
Tuple You can change the syntax to create a tuple that provides semantic names to each of the members of the
tuple:
The namedLetters tuple contains fields referred to as Alpha and Beta . Those names exist only at compile time
and are not preserved for example when inspecting the tuple using reflection at runtime.
In a tuple assignment, you can also specify the names of the fields on the right-hand side of the assignment:
You can specify names for the fields on both the left and right-hand side of the assignment:
The line above generates a warning, CS8123 , telling you that the names on the right side of the assignment, Alpha
and Beta are ignored because they conflict with the names on the left side, First and Second .
The examples above show the basic syntax to declare tuples. Tuples are most useful as return types for private
and internal methods. Tuples provide a simple syntax for those methods to return multiple discrete values: You
save the work of authoring a class or a struct that defines the type returned. There is no need for creating a
new type.
Creating a tuple is more efficient and more productive. It is a simpler, lightweight syntax to define a data structure
that carries more than one value. The example method below returns the minimum and maximum values found in
a sequence of integers:
There may be times when you want to unpackage the members of a tuple that were returned from a method. You
can do that by declaring separate variables for each of the values in the tuple. This is called deconstructing the
tuple:
You can also provide a similar deconstruction for any type in .NET. This is done by writing a Deconstruct method
as a member of the class. That Deconstruct method provides a set of out arguments for each of the properties
you want to extract. Consider this Point class that provides a deconstructor method that extracts the X and Y
coordinates:
You are not bound by the names defined in the Deconstruct method. You can rename the extract variables as part
of the assignment:
You can learn more in depth about tuples in the tuples topic.
Discards
Often when deconstructing a tuple or calling a method with out parameters, you're forced to define a variable
whose value you don't care about and don't intend to use. C# adds support for discards to handle this scenario. A
discard is a write-only variable whose name is _ (the underscore character); you can assign all of the values that
you intend to discard to the single variable. A discard is like an unassigned variable; apart from the assignment
statement, the discard can't be used in code.
Discards are supported in the following scenarios:
When deconstructing tuples or user-defined types.
When calling methods with out parameters.
In a pattern matching operation with the is and switch statements.
As a standalone identifier when you want to explicitly identify the value of an assignment as a discard.
The following example defines a QueryCityDataForYears method that returns a 6-tuple that contains a data for a
city for two different years. The method call in the example is concerned only with the two population values
returned by the method and so treats the remaining values in the tuple as discards when it deconstructs the tuple.
using System;
using System.Collections.Generic;
private static (string, double, int, int, int, int) QueryCityDataForYears(string name, int year1, int
year2)
{
int population1 = 0, population2 = 0;
double area = 0;
Pattern matching
Pattern matching is a feature that allows you to implement method dispatch on properties other than the type of
an object. You're probably already familiar with method dispatch based on the type of an object. In Object Oriented
programming, virtual and override methods provide language syntax to implement method dispatching based on
an object's type. Base and Derived classes provide different implementations. Pattern matching expressions extend
this concept so that you can easily implement similar dispatch patterns for types and data elements that are not
related through an inheritance hierarchy.
Pattern matching supports is expressions and switch expressions. Each enables inspecting an object and its
properties to determine if that object satisfies the sought pattern. You use the when keyword to specify additional
rules to the pattern.
is expression
The is pattern expression extends the familiar is operator to query an object beyond its type.
Let's start with a simple scenario. We'll add capabilities to this scenario that demonstrate how pattern matching
expressions make algorithms that work with unrelated types easy. We'll start with a method that computes the
sum of a number of die rolls:
You might quickly find that you need to find the sum of die rolls where some of the rolls are made with more than
one die. Part of the input sequence may be multiple results instead of a single number:
The is pattern expression works quite well in this scenario. As part of checking the type, you write a variable
initialization. This creates a new variable of the validated runtime type.
As you keep extending these scenarios, you may find that you build more if and else if statements. Once that
becomes unwieldy, you'll likely want to switch to switch pattern expressions.
switch statement updates
The match expression has a familiar syntax, based on the switch statement already part of the C# language. Let's
translate the existing code to use a match expression before adding new cases:
public static int DiceSum3(IEnumerable<object> values)
{
var sum = 0;
foreach (var item in values)
{
switch (item)
{
case int val:
sum += val;
break;
case IEnumerable<object> subList:
sum += DiceSum3(subList);
break;
}
}
return sum;
}
The match expressions have a slightly different syntax than the is expressions, where you declare the type and
variable at the beginning of the case expression.
The match expressions also support constants. This can save time by factoring out simple cases:
The code above adds cases for 0 as a special case of int , and null as a special case when there is no input. This
demonstrates one important new feature in switch pattern expressions: the order of the case expressions now
matters. The 0 case must appear before the general int case. Otherwise, the first pattern to match would be the
int case, even when the value is 0 . If you accidentally order match expressions such that a later case has already
been handled, the compiler will flag that and generate an error.
This same behavior enables the special case for an empty input sequence. You can see that the case for an
IEnumerable item that has elements must appear before the general IEnumerable case.
This version has also added a default case. The default case is always evaluated last, regardless of the order it
appears in the source. For that reason, convention is to put the default case last.
Finally, let's add one last case for a new style of die. Some games use percentile dice to represent larger ranges of
numbers.
NOTE
Two 10-sided percentile dice can represent every number from 0 through 99. One die has sides labelled 00 , 10 , 20 , ...
90 . The other die has sides labeled 0 , 1 , 2 , ... 9 . Add the two die values together and you can get every number from
0 through 99.
To add this kind of die to your collection, first define a type to represent the percentile die:
The new syntax for pattern matching expressions makes it easier to create dispatch algorithms based on an object's
type, or other properties, using a clear and concise syntax. Pattern matching expressions enable these constructs on
data types that are unrelated by inheritance.
You can learn more about pattern matching in the topic dedicated to pattern matching in C#.
There are many issues with this code. First of all, it's a public method that's returning a tuple. The language
supports this, but user defined types (either classes or structs) are preferred for public APIs.
Second, this method is returning the indices to the item in the matrix. That leads callers to write code that uses
those indices to dereference the matrix and modify a single element:
You'd rather write a method that returns a reference to the element of the matrix that you want to change. You
could only accomplish this by using unsafe code and returning a pointer to an int in previous versions.
Let's walk through a series of changes to demonstrate the ref local feature and show how to create a method that
returns a reference to internal storage. Along the way, you'll learn the rules of the ref return and ref local feature
that protects you from accidentally misusing it.
Start by modifying the Find method declaration so that it returns a ref int instead of a tuple. Then, modify the
return statement so it returns the value stored in the matrix instead of the two indices:
When you declare that a method returns a ref variable, you must also add the ref keyword to each return
statement. That indicates return by reference, and helps developers reading the code later remember that the
method returns by reference:
The second WriteLine statement in the example above prints out the value 42 , not 24 . The variable valItem is
an int , not a ref int . The var keyword enables the compiler to specify the type, but will not implicitly add the
ref modifier. Instead, the value referred to by the ref return is copied to the variable on the left-hand side of the
assignment. The variable is not a ref local.
In order to get the result you want, you need to add the ref modifier to the local variable declaration to make the
variable a reference when the return value is a reference:
Now, the second WriteLine statement in the example above will print out the value 24 , indicating that the storage
in the matrix has been modified. The local variable has been declared with the ref modifier, and it will take a ref
return. You must initialize a ref variable when it is declared, you cannot split the declaration and the initialization.
The C# language has three other rules that protect you from misusing the ref locals and returns:
You cannot assign a standard method return value to a ref local variable.
That disallows statements like ref int i = sequence.Count();
You cannot return a ref to a variable whose lifetime does not extend beyond the execution of the method.
That means you cannot return a reference to a local variable or a variable with a similar scope.
ref locals and returns can't be used with async methods.
The compiler can't know if the referenced variable has been set to its final value when the async method
returns.
The addition of ref locals and ref returns enable algorithms that are more efficient by avoiding copying values, or
performing dereferencing operations multiple times.
Local functions
Many designs for classes include methods that are called from only one location. These additional private methods
keep each method small and focused. However, they can make it harder to understand a class when reading it the
first time. These methods must be understood outside of the context of the single calling location.
For those designs, local functions enable you to declare methods inside the context of another method. This makes
it easier for readers of the class to see that the local method is only called from the context in which is it declared.
There are two very common use cases for local functions: public iterator methods and public async methods. Both
types of methods generate code that reports errors later than programmers might expect. In the case of iterator
methods, any exceptions are observed only when calling code that enumerates the returned sequence. In the case
of async methods, any exceptions are only observed when the returned Task is awaited.
Let's start with an iterator method:
public static IEnumerable<char> AlphabetSubset(char start, char end)
{
if (start < 'a' || start > 'z')
throw new ArgumentOutOfRangeException(paramName: nameof(start), message: "start must be a letter");
if (end < 'a' || end > 'z')
throw new ArgumentOutOfRangeException(paramName: nameof(end), message: "end must be a letter");
Examine the code below that calls the iterator method incorrectly:
The exception is thrown when resultSet is iterated, not when resultSet is created. In this contained example,
most developers could quickly diagnose the problem. However, in larger codebases, the code that creates an
iterator often isn't as close to the code that enumerates the result. You can refactor the code so that the public
method validates all arguments, and a private method generates the enumeration:
This refactored version will throw exceptions immediately because the public method is not an iterator method;
only the private method uses the yield return syntax. However, there are potential problems with this refactoring.
The private method should only be called from the public interface method, because otherwise all argument
validation is skipped. Readers of the class must discover this fact by reading the entire class and searching for any
other references to the alphabetSubsetImplementation method.
You can make that design intent more clear by declaring the alphabetSubsetImplementation as a local function
inside the public API method:
public static IEnumerable<char> AlphabetSubset3(char start, char end)
{
if (start < 'a' || start > 'z')
throw new ArgumentOutOfRangeException(paramName: nameof(start), message: "start must be a letter");
if (end < 'a' || end > 'z')
throw new ArgumentOutOfRangeException(paramName: nameof(end), message: "end must be a letter");
return alphabetSubsetImplementation();
IEnumerable<char> alphabetSubsetImplementation()
{
for (var c = start; c < end; c++)
yield return c;
}
}
The version above makes it clear that the local method is referenced only in the context of the outer method. The
rules for local functions also ensure that a developer can't accidentally call the local function from another location
in the class and bypass the argument validation.
The same technique can be employed with async methods to ensure that exceptions arising from argument
validation are thrown before the asynchronous work begins:
return longRunningWorkImplementation();
NOTE
Some of the designs that are supported by local functions could also be accomplished using lambda expressions. Those
interested can read more about the differences
// Expression-bodied finalizer
~ExpressionMembersExample() => Console.Error.WriteLine("Finalized!");
NOTE
This example does not need a finalizer, but it is shown to demonstrate the syntax. You should not implement a finalizer in
your class unless it is necessary to release unmanaged resources. You should also consider using the SafeHandle class instead
of managing unmanaged resources directly.
These new locations for expression-bodied members represent an important milestone for the C# language: These
features were implemented by community members working on the open-source Roslyn project.
Throw expressions
In C#, throw has always been a statement. Because throw is a statement, not an expression, there were C#
constructs where you could not use it. These included conditional expressions, null coalescing expressions, and
some lambda expressions. The addition of expression-bodied members adds more locations where throw
expressions would be useful. So that you can write any of these constructs, C# 7 introduces throw expressions.
The syntax is the same as you've always used for throw statements. The only difference is that now you can place
them in new locations, such as in a conditional expression:
Previously, those initializations would need to be in a constructor, with the throw statements in the body of the
constructor:
public ApplicationOptions()
{
loadedConfig = LoadConfigResourceOrDefault();
if (loadedConfig == null)
throw new InvalidOperationException("Could not load config");
NOTE
Both of the preceding constructs will cause exceptions to be thrown during the construction of an object. Those are often
difficult to recover from. For that reason, designs that throw exceptions during construction are discouraged.
NOTE
You need to add the NuGet package System.Threading.Tasks.Extensions in order to use the ValueTask<TResult> type.
A simple optimization would be to use ValueTask in places where Task would be used before. However, if you
want to perform extra optimizations by hand, you can cache results from async work and reuse the result in
subsequent calls. The ValueTask struct has a constructor with a Task parameter so that you can construct a
ValueTask from the return value of any existing async method:
The 0b at the beginning of the constant indicates that the number is written as a binary number.
Binary numbers can get very long, so it's often easier to see the bit patterns by introducing the _ as a digit
separator:
The digit separator can appear anywhere in the constant. For base 10 numbers, it would be common to use it as a
thousands separator:
The digit separator can be used with decimal , float and double types as well:
Taken together, you can declare numeric constants with much more readability.
What's New in C# 6
7/29/2017 • 21 min to read • Edit Online
The 6.0 release of C# contained many features that improve productivity for developers. Features in this release
include:
Read-only Auto-properties:
You can create read-only auto-properties that can be set only in constructors.
Auto-Property Initializers:
You can write initialization expressions to set the initial value of an auto-property.
Expression-bodied function members:
You can author one-line methods using lambda expressions.
using static:
You can import all the methods of a single class into the current namespace.
Null - conditional operators:
You can concisely and safely access members of an object while still checking for null with the null
conditional operator.
String Interpolation:
You can write string formatting expressions using inline expressions instead of positional arguments.
Exception filters:
You can catch expressions based on properties of the exception or other program state.
nameof Expressions:
You can let the compiler generate string representations of symbols.
await in catch and finally blocks:
You can use await expressions in locations that previously disallowed them.
index initializers:
You can author initialization expressions for associative containers as well as sequence containers.
Extension methods for collection initializers:
Collection initializers can rely on accessible extension methods, in addition to member methods.
Improved overload resolution:
Some constructs that previously generated ambiguous method calls now resolve correctly.
The overall effect of these features is that you write more concise code that is also more readable. The syntax
contains less ceremony for many common practices. It's easier to see the design intent with less ceremony. Learn
these features well, and you'll be more productive, write more readable code, and concentrate more on your core
features than on the constructs of the language.
The remainder of this topic provides details on each of these features.
Auto-Property enhancements
The syntax for automatically implemented properties (usually referred to as 'auto-properties') made it very easy to
create properties that had simple get and set accessors:
Using this syntax, the compiler doesn't ensure that the type really is immutable. It only enforces that the FirstName
and LastName properties are not modified from any code outside the class.
Read-only auto-properties enable true read-only behavior. You declare the auto-property with only a get accessor:
The FirstName and LastName properties can be set only in the body of a constructor:
This feature enables true language support for creating immutable types and using the more concise and
convenient auto-property syntax.
Auto -Property Initializers
Auto-Property Initializers let you declare the initial value for an auto-property as part of the property declaration. In
earlier versions, these properties would need to have setters and you would need to use that setter to initialize the
data storage used by the backing field. Consider this class for a student that contains the name and a list of the
student's grades:
public Student(string firstName, string lastName)
{
FirstName = firstName;
LastName = lastName;
}
As this class grows, you may include other constructors. Each constructor needs to initialize this field, or you'll
introduce errors.
C# 6 enables you to assign an initial value for the storage used by an auto-property in the auto-property
declaration:
The Grades member is initialized where it is declared. That makes it easier to perform the initialization exactly
once. The initialization is part of the property declaration, making it easier to equate the storage allocation with
public interface for Student objects.
Property Initializers can be used with read/write properties as well as read only properties, as shown here.
You can also use expression-bodied members in read only properties as well:
using static
The using static enhancement enables you to import the static methods of a single class. Previously, the using
statement imported all types in a namespace.
Often we use a class' static methods throughout our code. Repeatedly typing the class name can obscure the
meaning of your code. A common example is when you write classes that perform many numeric calculations.
Your code will be littered with @System.Math.Sin, @System.Math.Sqrt and other calls to different methods in the
Math class. The new using static syntax can make these classes much cleaner to read. You specify the class
you're using:
And now, you can use any static method in the Math class without qualifying the Math class. The Math class is a
great use case for this feature because it does not contain any instance methods. You can also use using static to
import a class' static methods for a class that has both static and instance methods. One of the most useful
examples is String:
NOTE
You must use the fully qualified class name, System.String in a static using statement. You cannot use the string
keyword instead.
You can now call static methods defined in the String class without qualifying those methods as members of that
class:
if (IsNullOrWhiteSpace(lastName))
throw new ArgumentException(message: "Cannot be blank", paramName: nameof(lastName));
The static using feature and extension methods interact in interesting ways, and the language design included
some rules that specifically address those interactions. The goal is to minimize any chances of breaking changes in
existing codebases, including yours.
Extension methods are only in scope when called using the extension method invocation syntax, not when called as
a static method. You'll often see this in LINQ queries. You can import the LINQ pattern by importing Enumerable.
This imports all the methods in the Enumerable class. However, the extension methods are only in scope when
called as extension methods. They are not in scope if they are called using the static method syntax:
This decision is because extension methods are typically called using extension method invocation expressions. In
the rare case where they are called using the static method call syntax it is to resolve ambiguity. Requiring the class
name as part of the invocation seems wise.
There's one last feature of static using . The static using directive also imports any nested types. That enables
you to reference any nested types without qualification.
Null-conditional operators
Null values complicate code. You need to check every access of variables to ensure you are not dereferencing
null . The null conditional operator makes those checks much easier and fluid.
In the preceding example, the variable first is assigned null if the person object is null . Otherwise, it gets
assigned the value of the FirstName property. Most importantly, the ?. means that this line of code does not
generate a NullReferenceException when the person variable is null . Instead, it short-circuits and produces
null .
Also, note that this expression returns a string , regardless of the value of person . In the case of short circuiting,
the null value returned is typed to match the full expression.
You can often use this construct with the null coalescing operator to assign default values when one of the
properties are null :
The right hand side operand of the ?. operator is not limited to properties or fields. You can also use it to
conditionally invoke methods. The most common use of member functions with the null conditional operator is to
safely invoke delegates (or event handlers) that may be null . You'll do this by calling the delegate's Invoke
method using the ?. operator to access the member. You can see an example in the
delegate patterns topic.
The rules of the ?. operator ensure that the left-hand side of the operator is evaluated only once. This is
important and enables many idioms, including the example using event handlers. Let's start with the event handler
usage. In previous versions of C#, you were encouraged to write code like this:
// Not recommended
if (this.SomethingHappened != null)
this.SomethingHappened(this, eventArgs);
IMPORTANT
The preceding example introduces a race condition. The SomethingHappened event may have subscribers when checked
against null , and those subscribers may have been removed before the event is raised. That would cause a
NullReferenceException to be thrown.
In this second version, the SomethingHappened event handler might be non-null when tested, but if other code
removes a handler, it could still be null when the event handler was called.
The compiler generates code for the ?. operator that ensures the left side ( this.SomethingHappened ) of the ?.
expression is evaluated once, and the result is cached:
// preferred in C# 6:
this.SomethingHappened?.Invoke(this, eventArgs);
Ensuring that the left side is evaluated only once also enables you to use any expression, including method calls, on
the left side of the ?. Even if these have side-effects, they are evaluated once, so the side effects occur only once.
You can see an example in our content on events.
String Interpolation
C# 6 contains new syntax for composing strings from a format string and expressions that can be evaluated to
produce other string values.
Traditionally, you needed to use positional parameters in a method like string.Format :
With C# 6, the new string interpolation feature enables you to embed the expressions in the format string. Simple
preface the string with $ :
This initial example used variable expressions for the substituted expressions. You can expand on this syntax to use
any expression. For example, you could compute a student's grade point average as part of the interpolation:
Running the preceding example, you would find that the output for Grades.Average() might have more decimal
places than you would like. The string interpolation syntax supports all the format strings available using earlier
formatting methods. You add the format strings inside the braces. Add a : following the expression to format:
The preceding line of code will format the value for Grades.Average() as a floating-point number with two decimal
places.
The : is always interpreted as the separator between the expression being formatted and the format string. This
can introduce problems when your expression uses a : in another way, such as a conditional operator:
In the preceding example, the : is parsed as the beginning of the format string, not part of the conditional
operator. In all cases where this happens, you can surround the expression with parentheses to force the compiler
to interpret the expression as you intend:
There aren't any limitations on the expressions you can place between the braces. You can execute a complex LINQ
query inside an interpolated string to perform computations and display the result:
public string GetAllGrades() =>
$@"All Grades: {Grades.OrderByDescending(g => g)
.Select(s => s.ToString("F2")).Aggregate((partial, element) => $"{partial}, {element}")}";
You can see from this sample that you can even nest a string interpolation expression inside another string
interpolation expression. This example is very likely more complex than you would want in production code.
Rather, it is illustrative of the breadth of the feature. Any C# expression can be placed between the curly braces of
an interpolated string.
String interpolation and specific cultures
All the examples shown in the preceding section will format the strings using the current culture and language on
the machine where the code executes. Often you may need to format the string produced using a specific culture.
The object produced from a string interpolation is a type that has an implicit conversion to either String or
FormattableString.
The FormattableString type contains the format string, and the results of evaluating the arguments before
converting them to strings. You can use public methods of FormattableString to specify the culture when
formatting a string. For example, the following will produce a string using German as the language and culture. (It
will use the ',' character for the decimal separator, and the '.' character as the thousands separator.)
NOTE
The preceding example is not supported in .NET Core version 1.0.1. It is only supported in the .NET Framework.
In general, string interpolation expressions produce strings as their output. However, when you want greater
control over the culture used to format the string, you can specify a specific output. If this is a capability you often
need, you can create convenience methods, as extension methods, to enable easy formatting with specific cultures.
Exception Filters
Another new feature in C# 6 is exception filters. Exception Filters are clauses that determine when a given catch
clause should be applied. If the expression used for an exception filter evaluates to true , the catch clause performs
its normal processing on an exception. If the expression evaluates to false , then the catch clause is skipped.
One use is to examine information about an exception to determine if a catch clause can process the exception:
The code generated by exception filters provides better information about an exception that is thrown and not
processed. Before exception filters were added to the language, you would need to create code like the following:
The point where the exception is thrown changes between these two examples. In the previous code, where a
throw clause is used, any stack trace analysis or examination of crash dumps will show that the exception was
thrown from the throw statement in your catch clause. The actual exception object will contain the original call
stack, but all other information about any variables in the call stack between this throw point and the location of
the original throw point has been lost.
Contrast that with how the code using an exception filter is processed: the exception filter expression evaluates to
false . Therefore, execution never enters the catch clause. Because the catch clause does not execute, no stack
unwinding takes place. That means the original throw location is preserved for any debugging activities that would
take place later.
Whenever you need to evaluate fields or properties of an exception, instead of relying solely on the exception type,
use an exception filter to preserve more debugging information.
Another recommended pattern with exception filters is to use them for logging routines. This usage also leverages
the manner in which the exception throw point is preserved when an exception filter evaluates to false .
A logging method would be a method whose argument is the exception that unconditionally returns false :
Whenever you want to log an exception, you can add a catch clause, and use this method as the exception filter:
The exceptions are never caught, because the LogException method always returns false . That always false
exception filter means that you can place this logging handler before any other exception handlers:
public void MethodThatFailsButHasRecoveryPath()
{
try {
PerformFailingOperation();
} catch (Exception e) when (e.LogException())
{
// This is never reached!
}
catch (RecoverableException ex)
{
Console.WriteLine(ex.ToString());
// This can still catch the more specific
// exception because the exception filter
// above always returns false.
// Perform recovery here
}
}
The preceding example highlights a very important facet of exception filters. The exception filters enable scenarios
where a more general exception catch clause may appear before a more specific one. It's also possible to have the
same exception type appear in multiple catch clauses:
Another recommended pattern helps prevent catch clauses from processing exceptions when a debugger is
attached. This technique enables you to run an application with the debugger, and stop execution when an
exception is thrown.
In your code, add an exception filter so that any recovery code executes only when a debugger is not attached:
After adding this in code, you set your debugger to break on all unhandled exceptions. Run the program under the
debugger, and the debugger breaks whenever PerformFailingOperation() throws a RecoverableException . The
debugger breaks your program, because the catch clause won't be executed due to the false-returning exception
filter.
nameof Expressions
The nameof expression evaluates to the name of a symbol. It's a great way to get tools working whenever you
need the name of a variable, a property, or a member field.
One of the most common uses for nameof is to provide the name of a symbol that caused an exception:
if (IsNullOrWhiteSpace(lastName))
throw new ArgumentException(message: "Cannot be blank", paramName: nameof(lastName));
Another use is with XAML based applications that implement the INotifyPropertyChanged interface:
The advantage of using the nameof operator over a constant string is that tools can understand the symbol. If you
use refactoring tools to rename the symbol, it will rename it in the nameof expression. Constant strings don't have
that advantage. Try it yourself in your favorite editor: rename a variable, and any nameof expressions will update as
well.
The nameof expression produces the unqualified name of its argument ( LastName in the previous examples) even
if you use the fully qualified name for the argument:
The implementation details for adding await support inside catch and finally clauses ensures that the
behavior is consistent with the behavior for synchronous code. When code executed in a catch or finally clause
throws, execution looks for a suitable catch clause in the next surrounding block. If there was a current exception,
that exception is lost. The same happens with awaited expressions in catch and finally clauses: a suitable catch
is searched for, and the current exception, if any, is lost.
NOTE
This behavior is the reason it's recommended to write catch and finally clauses carefully, to avoid introducing new
exceptions.
Index Initializers
Index Initializers is one of two features that make collection initializers more consistent. In earlier releases of C#,
you could use collection initializers only with sequence style collections:
Now, you can also use them with @System.Collections.Generic.Dictionary collections and similar types:
private Dictionary<int, string> webErrors = new Dictionary<int, string>
{
[404] = "Page not Found",
[302] = "Page moved, but left a forwarding address.",
[500] = "The web server can't come out to play today."
};
This feature means that associative containers can be initialized using syntax similar to what's been in place for
sequence containers for several versions.
Extension Add methods in collection initializers
Another feature that makes collection initialization easier is the ability to use an extension method for the Add
method. This feature was added for parity with Visual Basic.
The feature is most useful when you have a custom collection class that has a method with a different name to
semantically add new items.
For example, consider a collection of students like this:
IEnumerator IEnumerable.GetEnumerator()
{
return ((IEnumerable<Student>)allStudents).GetEnumerator();
}
}
The Enroll method adds a student. But it doesn't follow the Add pattern. In previous versions of C#, you could
not use collection initializers with an Enrollment object:
var classList = new Enrollment()
{
new Student("Lessie", "Crosby"),
new Student("Vicki", "Petty"),
new Student("Ofelia", "Hobbs"),
new Student("Leah", "Kinney"),
new Student("Alton", "Stoker"),
new Student("Luella", "Ferrell"),
new Student("Marcy", "Riggs"),
new Student("Ida", "Bean"),
new Student("Ollie", "Cottle"),
new Student("Tommy", "Broadnax"),
new Student("Jody", "Yates"),
new Student("Marguerite", "Dawson"),
new Student("Francisca", "Barnett"),
new Student("Arlene", "Velasquez"),
new Student("Jodi", "Green"),
new Student("Fran", "Mosley"),
new Student("Taylor", "Nesmith"),
new Student("Ernesto", "Greathouse"),
new Student("Margret", "Albert"),
new Student("Pansy", "House"),
new Student("Sharon", "Byrd"),
new Student("Keith", "Roldan"),
new Student("Martha", "Miranda"),
new Student("Kari", "Campos"),
new Student("Muriel", "Middleton"),
new Student("Georgette", "Jarvis"),
new Student("Pam", "Boyle"),
new Student("Deena", "Travis"),
new Student("Cary", "Totten"),
new Student("Althea", "Goodwin")
};
Now you can, but only if you create an extension method that maps Add to Enroll :
What you are doing with this feature is to map whatever method adds items to a collection to a method named
Add by creating an extension method:
public class Enrollment : IEnumerable<Student>
{
private List<Student> allStudents = new List<Student>();
IEnumerator IEnumerable.GetEnumerator()
{
return ((IEnumerable<Student>)allStudents).GetEnumerator();
}
}
In earlier versions of C#, calling that method using the method group syntax would fail:
Task.Run(DoThings);
The earlier compiler could not distinguish correctly between Task.Run(Action) and Task.Run(Func<Task>()) . In
previous versions, you'd need to use a lambda expression as an argument:
The C# language definition requires a standard library to have certain types and certain accessible members on
those types. The compiler generates code that uses these required types and members for many different language
features. When necessary, there are NuGet packages that contain types needed for newer versions of the language
when writing code for environments where those types or members have not been deployed yet.
This dependency on standard library functionality has been part of the C# language since its first version. In that
version, examples included:
Exception - used for all compiler generated exceptions.
String - the C# string type is a synonym for String.
Int32 - synonym of int .
That first version was simple: the compiler and the standard library shipped together, and there was only one
version of each.
Subsequent versions of C# have occasionally added new types or members to the dependencies. Examples include:
INotifyCompletion, CallerFilePathAttribute and CallerMemberNameAttribute. C# 7.0 continues this by adding a
dependency on ValueTuple to implement the tuples language feature.
The language design team works to minimize the surface area of the types and members required in a compliant
standard library. That goal is balanced against a clean design where new library features are incorporated
seamlessly into the language. There will be new features in future versions of C# that require new types and
members in a standard library. It's important to understand how to manage those dependencies in your work.
int a = 5;
int b = a + 2; //OK
// Error. Operator '+' cannot be applied to operands of type 'int' and 'bool'.
int c = a + test;
NOTE
C and C++ developers, notice that in C#, bool is not convertible to int.
The compiler embeds the type information into the executable file as metadata. The common language runtime
(CLR) uses that metadata at run time to further guarantee type safety when it allocates and reclaims memory.
Specifying Types in Variable Declarations
When you declare a variable or constant in a program, you must either specify its type or use the var keyword to let
the compiler infer the type. The following example shows some variable declarations that use both built-in numeric
types and complex user-defined types:
// Declaration only:
float temperature;
string name;
MyClass myClass;
The types of method parameters and return values are specified in the method signature. The following signature
shows a method that requires an int as an input argument and returns a string:
After a variable is declared, it cannot be re-declared with a new type, and it cannot be assigned a value that is not
compatible with its declared type. For example, you cannot declare an int and then assign it a Boolean value of true.
However, values can be converted to other types, for example when they are assigned to new variables or passed
as method arguments. A type conversion that does not cause data loss is performed automatically by the compiler.
A conversion that might cause data loss requires a cast in the source code.
For more information, see Casting and Type Conversions.
Built-in Types
C# provides a standard set of built-in numeric types to represent integers, floating point values, Boolean
expressions, text characters, decimal values, and other types of data. There are also built-in string and object
types. These are available for you to use in any C# program. For more information about the built-in types, see
Reference Tables for Types.
Custom Types
You use the struct, class, interface, and enum constructs to create your own custom types. The .NET Framework
class library itself is a collection of custom types provided by Microsoft that you can use in your own applications.
By default, the most frequently used types in the class library are available in any C# program. Others become
available only when you explicitly add a project reference to the assembly in which they are defined. After the
compiler has a reference to the assembly, you can declare variables (and constants) of the types declared in that
assembly in source code. For more information, see .NET Framework Class Library.
NOTE
You can see that the most commonly used types are all organized in the System namespace. However, the namespace in
which a type is contained has no relation to whether it is a value type or reference type.
Value Types
Value types derive from System.ValueType, which derives from System.Object. Types that derive from
System.ValueType have special behavior in the CLR. Value type variables directly contain their values, which means
that the memory is allocated inline in whatever context the variable is declared. There is no separate heap allocation
or garbage collection overhead for value-type variables.
There are two categories of value types: struct and enum.
The built-in numeric types are structs, and they have properties and methods that you can access:
But you declare and assign values to them as if they were simple non-aggregate types:
byte num = 0xA;
int i = 5;
char c = 'Z';
Value types are sealed, which means, for example, that you cannot derive a type from System.Int32, and you cannot
define a struct to inherit from any user-defined class or struct because a struct can only inherit from
System.ValueType. However, a struct can implement one or more interfaces. You can cast a struct type to an
interface type; this causes a boxing operation to wrap the struct inside a reference type object on the managed
heap. Boxing operations occur when you pass a value type to a method that takes a System.Object as an input
parameter. For more information, see Boxing and Unboxing.
You use the struct keyword to create your own custom value types. Typically, a struct is used as a container for a
small set of related variables, as shown in the following example:
For more information about structs, see Structs. For more information about value types in the .NET Framework,
see Common Type System.
The other category of value types is enum. An enum defines a set of named integral constants. For example, the
System.IO.FileMode enumeration in the .NET Framework class library contains a set of named constant integers
that specify how a file should be opened. It is defined as shown in the following example:
The System.IO.FileMode.Create constant has a value of 2. However, the name is much more meaningful for
humans reading the source code, and for that reason it is better to use enumerations instead of constant literal
numbers. For more information, see System.IO.FileMode.
All enums inherit from System.Enum, which inherits from System.ValueType. All the rules that apply to structs also
apply to enums. For more information about enums, see Enumeration Types.
Reference Types
A type that is defined as a class, delegate, array, or interface is a reference type. At run time, when you declare a
variable of a reference type, the variable contains the value null until you explicitly create an instance of the object
by using the new operator, or assign it an object that has been created elsewhere by using new , as shown in the
following example:
MyClass mc = new MyClass();
MyClass mc2 = mc;
An interface must be initialized together with a class object that implements it. If MyClass implements
IMyInterface , you create an instance of IMyInterface as shown in the following example:
When the object is created, the memory is allocated on the managed heap, and the variable holds only a reference
to the location of the object. Types on the managed heap require overhead both when they are allocated and when
they are reclaimed by the automatic memory management functionality of the CLR, which is known as garbage
collection. However, garbage collection is also highly optimized, and in most scenarios it does not create a
performance issue. For more information about garbage collection, see Automatic Memory Management.
All arrays are reference types, even if their elements are value types. Arrays implicitly derive from the System.Array
class, but you declare and use them with the simplified syntax that is provided by C#, as shown in the following
example:
Reference types fully support inheritance. When you create a class, you can inherit from any other interface or class
that is not defined as sealed, and other classes can inherit from your class and override your virtual methods. For
more information about how to create your own classes, see Classes and Structs. For more information about
inheritance and virtual methods, see Inheritance.
Generic Types
A type can be declared with one or more type parameters that serve as a placeholder for the actual type (the
concrete type) that client code will provide when it creates an instance of the type. Such types are called generic
types. For example, the .NET Framework type System.Collections.Generic.List<T> has one type parameter that by
convention is given the name T. When you create an instance of the type, you specify the type of the objects that
the list will contain, for example, string:
The use of the type parameter makes it possible to reuse the same class to hold any type of element, without
having to convert each element to object. Generic collection classes are called strongly-typed collections because
the compiler knows the specific type of the collection's elements and can raise an error at compile-time if, for
example, you try to add an integer to the strings object in the previous example. For more information, see
Generics.
Related Sections
For more information, see the following topics:
Casting and Type Conversions
Boxing and Unboxing
Using Type dynamic
Value Types
Reference Types
Classes and Structs
Anonymous Types
Generics
C# Language Specification
For more information, see the C# Language Specification. The language specification is the definitive source for C#
syntax and usage.
See Also
C# Reference
C# Programming Guide
Conversion of XML Data Types
Integral Types Table
Namespaces (C# Programming Guide)
7/29/2017 • 1 min to read • Edit Online
Namespaces are heavily used in C# programming in two ways. First, the .NET Framework uses namespaces to
organize its many classes, as follows:
System.Console.WriteLine("Hello World!");
System is a namespace and Console is a class in that namespace. The using keyword can be used so that the
complete name is not required, as in the following example:
using System;
Console.WriteLine("Hello");
Console.WriteLine("World!");
namespace SampleNamespace
{
class SampleClass
{
public void SampleMethod()
{
System.Console.WriteLine(
"SampleMethod inside SampleNamespace");
}
}
}
Namespaces Overview
Namespaces have the following properties:
They organize large code projects.
They are delimited by using the . operator.
The using directive obviates the requirement to specify the name of the namespace for every class.
The global namespace is the "root" namespace: global::System will always refer to the .NET Framework
namespace System .
Related Sections
See the following topics for more information about namespaces:
Using Namespaces
How to: Use the Global Namespace Alias
How to: Use the My Namespace
C# Language Specification
For more information, see the C# Language Specification. The language specification is the definitive source for C#
syntax and usage.
See Also
C# Programming Guide
Namespace Keywords
using Directive
:: Operator
. Operator
Types, variables, and values
7/29/2017 • 6 min to read • Edit Online
C# is a strongly-typed language. Every variable and constant has a type, as does every expression that evaluates to
a value. Every method signature specifies a type for each input parameter and for the return value. The .NET
Framework class library defines a set of built-in numeric types as well as more complex types that represent a wide
variety of logical constructs, such as the file system, network connections, collections and arrays of objects, and
dates. A typical C# program uses types from the class library as well as user-defined types that model the concepts
that are specific to the program's problem domain.
The information stored in a type can include the following:
The storage space that a variable of the type requires.
The maximum and minimum values that it can represent.
The members (methods, fields, events, and so on) that it contains.
The base type it inherits from.
The location where the memory for variables will be allocated at run time.
The kinds of operations that are permitted.
The compiler uses type information to make sure that all operations that are performed in your code are type safe.
For example, if you declare a variable of type int, the compiler allows you to use the variable in addition and
subtraction operations. If you try to perform those same operations on a variable of type bool, the compiler
generates an error, as shown in the following example:
int a = 5;
int b = a + 2; //OK
// Error. Operator '+' cannot be applied to operands of type 'int' and 'bool'.
int c = a + test;
NOTE
C and C++ developers, notice that in C#, bool is not convertible to int.
The compiler embeds the type information into the executable file as metadata. The common language runtime
(CLR) uses that metadata at run time to further guarantee type safety when it allocates and reclaims memory.
The types of method parameters and return values are specified in the method signature. The following signature
shows a method that requires an int as an input argument and returns a string:
After a variable is declared, it cannot be re-declared with a new type, and it cannot be assigned a value that is not
compatible with its declared type. For example, you cannot declare an int and then assign it a Boolean value of true.
However, values can be converted to other types, for example when they are assigned to new variables or passed
as method arguments. A type conversion that does not cause data loss is performed automatically by the compiler.
A conversion that might cause data loss requires a cast in the source code.
For more information, see Casting and type conversions.
Built-in types
C# provides a standard set of built-in numeric types to represent integers, floating point values, Boolean
expressions, text characters, decimal values, and other types of data. There are also built-in string and object types.
These are available for you to use in any C# program. For a more information about the built-in types, see Types
reference tables.
Custom types
You use the struct, class, interface, and enum constructs to create your own custom types. The .NET Framework
class library itself is a collection of custom types provided by Microsoft that you can use in your own applications.
By default, the most frequently used types in the class library are available in any C# program. Others become
available only when you explicitly add a project reference to the assembly in which they are defined. After the
compiler has a reference to the assembly, you can declare variables (and constants) of the types declared in that
assembly in source code. For more information, see .NET Framework class library.
Generic types
A type can be declared with one or more type parameters that serve as a placeholder for the actual type (the
concrete type) that client code will provide when it creates an instance of the type. Such types are called generic
types. For example, the .NET Framework type List<T> has one type parameter that by convention is given the name
T. When you create an instance of the type, you specify the type of the objects that the list will contain, for example,
string:
List<string> strings = new List<string>();
The use of the type parameter makes it possible to reuse the same class to hold any type of element, without
having to convert each element to object. Generic collection classes are called strongly-typed collections because
the compiler knows the specific type of the collection's elements and can raise an error at compile-time if, for
example, you try to add an integer to the strings object in the previous example. For more information, see
Generics.
See also
Structs
Classes
Classes
7/29/2017 • 5 min to read • Edit Online
A class is a construct that enables you to create your own custom types by grouping together variables of other
types, methods and events. A class is like a blueprint. It defines the data and behavior of a type. If the class is not
declared as static, client code can use it by creating objects or instances which are assigned to a variable. The
variable remains in memory until all references to it go out of scope. At that time, the CLR marks it as eligible for
garbage collection. If the class is declared as static, then only one copy exists in memory and client code can only
access it through the class itself, not an instance variable. For more information, see Static classes and static class
members.
Reference types
A type that is defined as a class is a reference type. At run time, when you declare a variable of a reference type, the
variable contains the value null until you explicitly create an instance of the object by using the new operator, or
assign it an object that has been created elsewhere by using new, as shown in the following example:
When the object is created, the memory is allocated on the managed heap, and the variable holds only a reference
to the location of the object. Types on the managed heap require overhead both when they are allocated and when
they are reclaimed by the automatic memory management functionality of the CLR, which is known as garbage
collection. However, garbage collection is also highly optimized, and in most scenarios, it does not create a
performance issue. For more information about garbage collection, see Automatic memory management and
garbage collection.
Reference types fully support inheritance, a fundamental characteristic of object-oriented programming. When
you create a class, you can inherit from any other interface or class that is not defined as sealed, and other classes
can inherit from your class and override your virtual methods. For more information, see Inheritance.
Declaring classes
Classes are declared by using the class keyword, as shown in the following example:
The class keyword is preceded by the access modifier. Because public is used in this case, anyone can create
objects from this class. The name of the class follows the class keyword. The remainder of the definition is the
class body, where the behavior and data are defined. Fields, properties, methods, and events on a class are
collectively referred to as class members.
Creating objects
A class defines a type of object, but it is not an object itself. An object is a concrete entity based on a class, and is
sometimes referred to as an instance of a class.
Objects can be created by using the new keyword followed by the name of the class that the object will be based
on, like this:
When an instance of a class is created, a reference to the object is passed back to the programmer. In the previous
example, object1 is a reference to an object that is based on Customer . This reference refers to the new object but
does not contain the object data itself. In fact, you can create an object reference without creating an object at all:
Customer object2;
We do not recommend creating object references such as this one that does not refer to an object because trying
to access an object through such a reference will fail at run time. However, such a reference can be made to refer
to an object, either by creating a new object, or by assigning it to an existing object, such as this:
This code creates two object references that both refer to the same object. Therefore, any changes to the object
made through object3 will be reflected in subsequent uses of object4 . Because objects that are based on classes
are referred to by reference, classes are known as reference types.
Class inheritance
Inheritance is accomplished by using a derivation, which means a class is declared by using a base class from
which it inherits data and behavior. A base class is specified by appending a colon and the name of the base class
following the derived class name, like this:
When a class declares a base class, it inherits all the members of the base class except the constructors.
Unlike C++, a class in C# can only directly inherit from one base class. However, because a base class may itself
inherit from another class, a class may indirectly inherit multiple base classes. Furthermore, a class can directly
implement more than one interface. For more information, see Interfaces.
A class can be declared abstract. An abstract class contains abstract methods that have a signature definition but
no implementation. Abstract classes cannot be instantiated. They can only be used through derived classes that
implement the abstract methods. By contrast, a sealed class does not allow other classes to derive from it. For
more information, see Abstract and sealed classes and class members.
Class definitions can be split between different source files. For more information, see Partial class definitions.
Example
In the following example, a public class that contains a single field, a method, and a special method called a
constructor is defined. For more information, see Constructors. The class is then instantiated with the new
keyword.
public class Person
{
// Field
public string name;
// Method
public void SetName(string newName)
{
name = newName;
}
}
class TestPerson
{
static void Main()
{
// Call the constructor that has no parameters.
Person person1 = new Person();
Console.WriteLine(person1.name);
person1.SetName("John Smith");
Console.WriteLine(person1.name);
C# language specification
For more information, see the C# language specification. The language specification is the definitive source for C#
syntax and usage.
See also
C# programming guide
Polymorphism
Class and struct members
Class and struct methods
Constructors
Finalizers
Objects
Structs
7/29/2017 • 4 min to read • Edit Online
A struct is a value type. When a struct is created, the variable to which the struct is assigned holds the struct's
actual data. When the struct is assigned to a new variable, it is copied. The new variable and the original variable
therefore contain two separate copies of the same data. Changes made to one copy do not affect the other copy.
Value type variables directly contain their values, which means that the memory is allocated inline in whatever
context the variable is declared. There is no separate heap allocation or garbage collection overhead for value-type
variables.
There are two categories of value types: struct and enum.
The built-in numeric types are structs, and they have properties and methods that you can access:
But you declare and assign values to them as if they were simple non-aggregate types:
Value types are sealed, which means, for example, that you cannot derive a type from Int32, and you cannot define
a struct to inherit from any user-defined class or struct because a struct can only inherit from ValueType. However,
a struct can implement one or more interfaces. You can cast a struct type to an interface type; this causes a boxing
operation to wrap the struct inside a reference type object on the managed heap. Boxing operations occur when
you pass a value type to a method that takes an Object as an input parameter. For more information, see Boxing
and Unboxing.
You use the struct keyword to create your own custom value types. Typically, a struct is used as a container for a
small set of related variables, as shown in the following example:
For more information about value types in the .NET Framework, see Common Type System.
Structs share most of the same syntax as classes, although structs are more limited than classes:
Within a struct declaration, fields cannot be initialized unless they are declared as const or static .
A struct cannot declare a default constructor (a constructor without parameters) or a finalizer.
Structs are copied on assignment. When a struct is assigned to a new variable, all the data is copied, and any
modification to the new copy does not change the data for the original copy. This is important to remember
when working with collections of value types such as Dictionary.
Structs are value types and classes are reference types.
Unlike classes, structs can be instantiated without using a new operator.
Structs can declare constructors that have parameters.
A struct cannot inherit from another struct or class, and it cannot be the base of a class. All structs inherit
directly from ValueType, which inherits from Object.
A struct can implement interfaces.
Literal values
In C#, literal values receive a type from the compiler. You can specify how a numeric literal should be typed by
appending a letter to the end of the number. For example, to specify that the value 4.56 should be treated as a
float, append an "f" or "F" after the number: 4.56f . If no letter is appended, the compiler will infer the double type
for the literal. For more information about which types can be specified with letter suffixes, see the reference pages
for individual types in Value Types.
Because literals are typed, and all types derive ultimately from Object, you can write and compile code such as the
following:
var x = 123_456;
string s2 = "I can use an underscore as a digit separator: " + x;
// Outputs: "I can use an underscore as a digit separator:
Console.WriteLine(s2);
var b = 0b1010_1011_1100_1110_1111;
string s3 = "I can specify bit patterns: " + b.ToString();
// Outputs: "I can specify bit patterns: 703727
Console.WriteLine(s3);
The last two examples demonstrate language features introduced in C# 7.0. The first allows you to use an
underscore character as a digit separator inside numeric literals. You can put them wherever you want between
digits to improve readability. They have no effect on the value.
The second demonstrates binary literals, which allow you to specify bit patterns directly instead of using
hexadecimal notation.
Nullable types
Ordinary value types cannot have a value of null. However, you can create nullable value types by affixing a ? after
the type. For example, int? is an int type that can also have the value null. In the CTS, nullable types are instances
of the generic struct type Nullable<T>. Nullable types are especially useful when you are passing data to and from
databases in which numeric values might be null. For more information, see Nullable Types (C# Programming
Guide).
See also
Classes
Basic Types
C# Tuple types
8/24/2017 • 17 min to read • Edit Online
C# Tuples are types that you define using a lightweight syntax. The advantages include a simpler syntax, rules for
conversions based on number (referred to as cardinality) and types of elements, and consistent rules for copies
and assignments. As a tradeoff, Tuples do not support some of the object oriented idioms associated with
inheritance. You can get an overview in the section on Tuples in the What's new in C# 7 topic.
In this topic, you'll learn the language rules governing Tuples in C# 7, different ways to use them, and initial
guidance on working with Tuples.
NOTE
The new tuples features require the ValueTuple types. You must add the NuGet package System.ValueTuple in order to
use it on platforms that do not include the types.
This is similar to other language features that rely on types delivered in the framework. Examples include async and
await relying on the INotifyCompletion interface, and LINQ relying on IEnumerable<T> . However, the delivery
mechanism is changing as .NET is becoming more platform independent. The .NET Framework may not always ship on the
same cadence as the language compiler. When new language features rely on new types, those types will be available as
NuGet packages when the language features ship. As these new types get added to the .NET Standard API and delivered as
part of the framework, the NuGet package requirement will be removed.
Let's start with the reasons for adding new Tuple support. Methods return a single object. Tuples enable you to
package multiple values in that single object more easily.
The .NET Framework already has generic Tuple classes. These classes, however, had two major limitations. For
one, the Tuple classes named their properties Item1 , Item2 , and so on. Those names carry no semantic
information. Using these Tuple types does not enable communicating the meaning of each of the properties. The
new language features enable you to declare and use semantically meaningful names for the elements in a tuple.
Another concern is that the Tuple classes are reference types. Using one of the Tuple types means allocating
objects. On hot paths, this can have a measurable impact on your application's performance. Therefore, the
language support for tuples leverages the new ValueTuple structs.
To avoid those deficiencies, you could create a class or a struct to carry multiple elements. Unfortunately,
that's more work for you, and it obscures your design intent. Making a struct or class implies that you are
defining a type with both data and behavior. Many times, you simply want to store multiple values in a single
object.
The language features and the ValueTuple generic structs enforce the rule that you cannot add any behavior
(methods) to these tuple types. All the ValueTuple types are mutable structs. Each member field is a public field.
That makes them very lightweight. However, that means tuples should not be used where immutability is
important.
Tuples are both simpler and more flexible data containers than class and struct types. Let's explore those
differences.
The tuple in the previous example was initialized using literal constants and won't have element names created
using Tuple field name projections in C# 7.1.
However, when you initialize a tuple, you can use new language features that give better names to each field.
Doing so creates a named tuple. Named tuples still have elements named Item1 , Item2 , Item3 and so on. But
they also have synonyms for any of those elements that you have named. You create a named tuple by specifying
the names for each element. One way is to specify the names as part of the tuple initialization:
These synonyms are handled by the compiler and the language so that you can use named tuples effectively. IDEs
and editors can read these semantic names using the Roslyn APIs. This enables you to reference the elements of a
named tuple by those semantic names anywhere in the same assembly. The compiler replaces the names you've
defined with Item* equivalents when generating the compiled output. The compiled Microsoft Intermediate
Language (MSIL) does not include the names you've given these elements.
Beginning with C# 7.1, the field names for a tuple may be provided from the variables used to initialize the tuple.
This is referred to as tuple projection initializers. The following code creates a tuple named accumulation with
elements count (an integer), and sum (a double).
The compiler must communicate those names you created for tuples that are returned from public methods or
properties. In those cases, the compiler adds a @System.Runtime.CompilerServices.TupleElementNames attribute
on the method. This attribute contains a
@System.Runtime.CompilerServices.TupleElementNames.TransformNames list property that contains the names
given to each of the elements in the Tuple.
NOTE
Development Tools, such as Visual Studio, also read that metadata, and provide IntelliSense and other features using the
metadata field names.
It is important to understand these underlying fundamentals of the new tuples and the ValueTuple type in order
to understand the rules for assigning named tuples to each other.
For any field where an explicit name is not provided, an applicable implicit name will be projected. Note that there
is no requirement to provide semantic names, either explicitly or implicitly. The folowing initializer will have field
names Item1 , whose value is 42 and StringContent , whose value is "The answer to everything":
There are two conditions where candidate field names are not projected onto the tuple field:
1. When the candidate name is a reserved tuple name. Examples include Item3 , ToString or Rest .
2. When the candidate name is a duplicate of another tuple field name, either explicit or implicit.
These conditions avoid ambiguity. These names would cause an ambiguity if they were used as the field names
for a field in a tuple. Neither of these conditions cause compile time errors. Instead, the elements without
projected names do not have semantic names projected for them. The following examples demonstrate these
conditions:
These situations do not cause compiler errors because that would be a breaking change for code written with C#
7.0, when tuple field name projections were not available.
The first two variables, unnamed and anonymous do not have semantic names provided for the elements. The field
names are Item1 and Item2 . The last two variables, named and differentName have semantic names given for
the elements. Note that these two tuples have different names for the elements.
All four of these tuples have the same number of elements (referred to as 'cardinality') and the types of those
elements are identical. Therefore, all of these assignments work:
unnamed = named;
named = unnamed;
// 'named' still has fields that can be referred to
// as 'answer', and 'message':
Console.WriteLine($"{named.Answer}, {named.Message}");
// unnamed to unnamed:
anonymous = unnamed;
// named tuples.
named = differentNamed;
// The field names are not assigned. 'named' still has
// fields that can be referred to as 'answer' and 'message':
Console.WriteLine($"{named.Answer}, {named.Message}");
Notice that the names of the tuples are not assigned. The values of the elements are assigned following the order
of the elements in the tuple.
Tuples of different types or numbers of elements are not assignable:
NOTE
These examples compute the uncorrected sample standard deviation. The corrected sample standard deviation formula
would divide the sum of the squared differences from the mean by (N-1) instead of N, as the Average extension method
does. Consult a statistics text for more details on the differences between these formulas for standard deviation.
This follows the textbook formula for the standard deviation. It produces the correct answer, but it's a very
inefficient implementation. This method enumerates the sequence twice: Once to produce the average, and once
to produce the average of the square of the difference of the average. (Remember that LINQ queries are evaluated
lazily, so the computation of the differences from the mean and the average of those differences makes only one
enumeration.)
There is an alternative formula that computes standard deviation using only one enumeration of the sequence.
This computation produces two values as it enumerates the sequence: the sum of all items in the sequence, and
the sum of the each value squared:
This version enumerates the sequence exactly once. But, it's not very reusable code. As you keep working, you'll
find that many different statistical computations use the number of items in the sequence, the sum of the
sequence, and the sum of the squares of the sequence. Let's refactor this method and write a utility method that
produces all three of those values.
This is where tuples come in very useful.
Let's update this method so the three values computed during the enumeration are stored in a tuple. That creates
this version:
public static double StandardDeviation(IEnumerable<double> sequence)
{
var computation = (Count: 0, Sum: 0.0, SumOfSquares: 0.0);
Visual Studio's Refactoring suport makes it easy to extract the functionality for the core statistics into a private
method. That gives you a private static method that returns the tuple type with the three values of Sum ,
SumOfSquares , and Count :
return computation;
}
The language enables a couple more options that you can use, if you want to make a few quick edits by hand.
First, you can use the var declaration to initialize the tuple result from the ComputeSumAndSumOfSquares method
call. You can also create three discrete variables inside the ComputeSumAndSumOfSquares method. The final version is
below:
public static double StandardDeviation(IEnumerable<double> sequence)
{
var computation = ComputeSumAndSumOfSquares(sequence);
This final version can be used for any method that needs those three values, or any subset of them.
The language supports other options in managing the names of the elements in these tuple-returning methods.
You can remove the field names from the return value declaration and return an unnamed tuple:
You must address the fields of this tuple as Item1 , Item2 , and Item3 . It's recommended that you provide
semantic names to the elements of tuples returned from methods.
Another idiom where tuples can be very useful is when you are authoring LINQ queries where the final result is a
projection that contains some, but not all, of the properties of the objects being selected.
You would traditionally project the results of the query into a sequence of objects that were an anonymous type.
That presented many limitations, primarily because anonymous types could not conveniently be named in the
return type for a method. Alternatives using object or dynamic as the type of the result came with significant
performance costs.
Returning a sequence of a tuple type is easy, and the names and types of the elements are available at compile
time and through IDE tools. For example, consider a ToDo application. You might define a class similar to the
following to represent a single entry in the ToDo list:
public class ToDoItem
{
public int ID { get; set; }
public bool IsDone { get; set; }
public DateTime DueDate { get; set; }
public string Title { get; set; }
public string Notes { get; set; }
}
Your mobile applications may support a compact form of the current ToDo items that only displays the title. That
LINQ query would make a projection that includes only the ID and the title. A method that returns a sequence of
tuples expresses that design very well:
NOTE
In C# 7.1, tuple projections enable you to create named tuples using elements, in a manner similar to the property naming
in anonymous types. In the above code, the select statement in the query projection creates a tuple that has elements
ID and Title .
The named tuple can be part of the signature. It lets the compiler and IDE tools provide static checking that you
are using the result correctly. The named tuple also carries the static type information so there is no need to use
expensive run time features like reflection or dynamic binding to work with the results.
Deconstruction
You can unpackage all the items in a tuple by deconstructing the tuple returned by a method. There are two
different approaches to deconstructing tuples. First, you can explicitly declare the type of each field inside
parentheses to create discrete variables for each of the elements in the tuple:
You can also declare implicitly typed variables for each field in a tuple by using the var keyword outside the
parentheses:
Note that you cannot use a specific type outside the parentheses, even if every field in the tuple has the same type.
Deconstructing user defined types
Any tuple type can be deconstructed as shown above. It's also easy to enable deconstruction on any user defined
type (classes, structs, or even interfaces).
The type author can define one or more Deconstruct methods that assign values to any number of out variables
representing the data elements that make up the type. For example, the following Person type defines a
Deconstruct method that deconstructs a person object into the elements representing the first name and last
name:
The deconstruct method enables assignment from a Person to two strings, representing the FirstName and
LastName properties:
You can enable deconstruction even for types you did not author. The Deconstruct method can be an extension
method that unpackages the accessible data members of an object. The example below shows a Student type,
derived from the Person type, and an extension method that deconstructs a Student into three variables,
representing the FirstName , the LastName and the GPA :
public class Student : Person
{
public double GPA { get; }
public Student(string first, string last, double gpa) :
base(first, last)
{
GPA = gpa;
}
}
A Student object now has two accessible Deconstruct methods: the extension method declared for Student
types, and the member of the Person type. Both are in scope, and that enables a Student to be deconstructed
into either two variables or three. If you assign a student to three variables, the first name, last name, and GPA are
all returned. If you assign a student to two variables, only the first name and the last name are returned.
You should be very careful defining multiple Deconstruct methods in a class or a class hierarchy. Multiple
Deconstruct methods that have the same number of out parameters can quickly cause ambiguities. Callers may
not be able to easily call the desired Deconstruct method.
In this example, there is minimal chance for an ambiguous call because the Deconstruct method for Person has
two output parameters, and the Deconstruct method for Student has three.
Conclusion
The new language and library support for named tuples makes it much easier to work with designs that use data
structures that store multiple elements but do not define behavior, as classes and structs do. It's easy and concise
to use tuples for those types. You get all the benefits of static type checking, without needing to author types
using the more verbose class or struct syntax. Even so, they are most useful for utility methods that are
private , or internal . Create user defined types, either class or struct types when your public methods
return a value that has multiple elements.
Deconstructing tuples and other types
8/14/2017 • 10 min to read • Edit Online
A tuple provides a light-weight way to retrieve multiple values from a method call. But once you retrieve the tuple,
you have to handle its individual elements. Doing this on an element-by-element basis is cumbersome, as the
following example shows. The QueryCityData method returns a 3-tuple, and each of its elements is assigned to a
variable in a separate operation.
using System;
Retrieving multiple field and property values from an object can be equally cumbersome: you have to assign a field
or property value to a variable on a member-by-member basis.
Starting with C# 7, you can retrieve multiple elements from a tuple or retrieve multiple field, property, and
computed values from an object in a single deconstruct operation. When you deconstruct a tuple, you assign its
elements to individual variables. When you deconstruct an object, you assign selected values to individual
variables.
Deconstructing a tuple
C# features built-in support for deconstructing tuples, which lets you unpackage all the items in a tuple in a single
operation. The general syntax for deconstructing a tuple is similar to the syntax for defining one: you enclose the
variables to which each element is to be assigned in parentheses in the left side of an assignment statement. For
example, the following statement assigns the elements of a 4-tuple to four separate variables:
You can use the var keyword so that C# infers the type of each variable. You place the var keyword
outside of the parentheses. The following example uses type inference when deconstructing the 3-tuple
returned by the QueryCityData method.
You can also use the var keyword individually with any or all of the variable declarations inside the
parentheses.
private static (string, double, int, int, int, int) QueryCityDataForYears(string name, int year1, int
year2)
{
int population1 = 0, population2 = 0;
double area = 0;
You can then deconstruct an instance of the Person class named p with an assignment like the following:
The following example overloads the Deconstruct method to return various combinations of properties of a
Person object. Individual overloads return:
public void Deconstruct(out string fname, out string mname, out string lname)
{
fname = FirstName;
mname = MiddleName;
lname = LastName;
}
Because you can overload the Deconstruct method to reflect groups of data that are commonly extracted from an
object, you should be careful to define Deconstruct methods with signatures that are distinctive and unambiguous.
Multiple Deconstruct methods that have the same number of out parameters or the same number and type of
out parameters in a different order can cause confusion.
The overloaded Deconstruct method in the following example illustrates one possible source of confusion. The
first overload returns the first name, middle name, last name, and age of a Person object, in that order. The second
overload returns name information only along with annual income, but the first, middle, and last name are in a
different order. This makes it easy to confuse the order of arguments when deconstructing a Person instance.
using System;
public void Deconstruct(out string fname, out string mname, out string lname, out int age)
{
fname = FirstName;
mname = MiddleName;
lname = LastName;
age = DateTime.Now.Year - DateOfBirth.Year;
public void Deconstruct(out string lname, out string fname, out string mname, decimal income)
{
fname = FirstName;
mname = MiddleName;
lname = LastName;
income = AnnualIncome;
}
}
using System;
using System.Collections.Generic;
using System.Reflection;
if (getter != null) {
if (getter.IsPublic)
getAccessTemp = "public";
else if (getter.IsPrivate)
getAccessTemp = "private";
else if (getter.IsAssembly)
getAccessTemp = "internal";
else if (getter.IsFamily)
getAccessTemp = "protected";
else if (getter.IsFamilyOrAssembly)
getAccessTemp = "protected internal";
}
if (setter != null) {
if (setter.IsPublic)
setAccessTemp = "public";
else if (setter.IsPrivate)
setAccessTemp = "private";
setAccessTemp = "private";
else if (setter.IsAssembly)
setAccessTemp = "internal";
else if (setter.IsFamily)
setAccessTemp = "protected";
else if (setter.IsFamilyOrAssembly)
setAccessTemp = "protected internal";
}
if (!hasGetAndSet | sameAccess) {
Console.WriteLine(accessibility);
}
else {
Console.WriteLine($"\n The get accessor: {getAccessibility}");
Console.WriteLine($" The set accessor: {setAccessibility}");
}
}
}
// The example displays the following output:
// The System.DateTime.Now property:
// PropertyType: DateTime
// Static: True
// Read-only: True
// Indexed: False
//
// Accessibility of the System.Collections.Generic.List`1.Item property: public
See also
Discards
Tuples
Interfaces (C# Programming Guide)
7/29/2017 • 4 min to read • Edit Online
An interface contains definitions for a group of related functionalities that a class or a struct can implement.
By using interfaces, you can, for example, include behavior from multiple sources in a class. That capability is
important in C# because the language doesn't support multiple inheritance of classes. In addition, you must use an
interface if you want to simulate inheritance for structs, because they can't actually inherit from another struct or
class.
You define an interface by using the interface keyword, as the following example shows.
interface IEquatable<T>
{
bool Equals(T obj);
}
Any class or struct that implements the IEquatable<T> interface must contain a definition for an Equals method
that matches the signature that the interface specifies. As a result, you can count on a class that implements
IEquatable<T> to contain an Equals method with which an instance of the class can determine whether it's equal
to another instance of the same class.
The definition of IEquatable<T> doesn’t provide an implementation for Equals . The interface defines only the
signature. In that way, an interface in C# is similar to an abstract class in which all the methods are abstract.
However, a class or struct can implement multiple interfaces, but a class can inherit only a single class, abstract or
not. Therefore, by using interfaces, you can include behavior from multiple sources in a class.
For more information about abstract classes, see Abstract and Sealed Classes and Class Members.
Interfaces can contain methods, properties, events, indexers, or any combination of those four member types. For
links to examples, see Related Sections. An interface can't contain constants, fields, operators, instance constructors,
finalizers, or types. Interface members are automatically public, and they can't include any access modifiers.
Members also can't be static.
To implement an interface member, the corresponding member of the implementing class must be public, non-
static, and have the same name and signature as the interface member.
When a class or struct implements an interface, the class or struct must provide an implementation for all of the
members that the interface defines. The interface itself provides no functionality that a class or struct can inherit in
the way that it can inherit base class functionality. However, if a base class implements an interface, any class that's
derived from the base class inherits that implementation.
The following example shows an implementation of the IEquatable interface. The implementing class, Car , must
provide an implementation of the Equals method.
public class Car : IEquatable<Car>
{
public string Make {get; set;}
public string Model { get; set; }
public string Year { get; set; }
Properties and indexers of a class can define extra accessors for a property or indexer that's defined in an interface.
For example, an interface might declare a property that has a get accessor. The class that implements the interface
can declare the same property with both a get and set accessor. However, if the property or indexer uses explicit
implementation, the accessors must match. For more information about explicit implementation, see Explicit
Interface Implementation and Interface Properties.
Interfaces can implement other interfaces. A class might include an interface multiple times through base classes
that it inherits or through interfaces that other interfaces implement. However, the class can provide an
implementation of an interface only one time and only if the class declares the interface as part of the definition of
the class ( class ClassName : InterfaceName ). If the interface is inherited because you inherited a base class that
implements the interface, the base class provides the implementation of the members of the interface. However,
the derived class can reimplement the interface members instead of using the inherited implementation.
A base class can also implement interface members by using virtual members. In that case, a derived class can
change the interface behavior by overriding the virtual members. For more information about virtual members,
see Polymorphism.
Interfaces Summary
An interface has the following properties:
An interface is like an abstract base class. Any class or struct that implements the interface must implement
all its members.
An interface can't be instantiated directly. Its members are implemented by any class or struct that
implements the interface.
Interfaces can contain events, indexers, methods, and properties.
Interfaces contain no implementation of methods.
A class or struct can implement multiple interfaces. A class can inherit a base class and also implement one
or more interfaces.
In This Section
Explicit Interface Implementation
Explains how to create a class member that’s specific to an interface.
How to: Explicitly Implement Interface Members
Provides an example of how to explicitly implement members of interfaces.
How to: Explicitly Implement Members of Two Interfaces
Provides an example of how to explicitly implement members of interfaces with inheritance.
Related Sections
Interface Properties
Indexers in Interfaces
How to: Implement Interface Events
Classes and Structs
Inheritance
Methods
Polymorphism
Abstract and Sealed Classes and Class Members
Properties
Events
Indexers
See Also
C# Programming Guide
Inheritance
Methods
7/29/2017 • 21 min to read • Edit Online
A method is a code block that contains a series of statements. A program causes the statements to be executed by
calling the method and specifying any required method arguments. In C#, every executed instruction is performed
in the context of a method. The Main method is the entry point for every C# application and it is called by the
common language runtime (CLR) when the program is started.
NOTE
This topic discusses named methods. For information about anonymous functions, see Anonymous Functions.
Method signatures
Methods are declared in a class or struct by specifying:
An optional access level, such as public or private . The default is private .
Optional modifiers such as abstract or sealed .
The return value, or void if the method has none.
The method name.
Any method parameters. Method parameters are enclosed in parentheses and are separated by commas. Empty
parentheses indicate that the method requires no parameters.
These parts together form the method signature.
NOTE
A return type of a method is not part of the signature of the method for the purposes of method overloading. However, it is
part of the signature of the method when determining the compatibility between a delegate and the method that it points
to.
The following example defines a class named Motorcycle that contains five methods:
using System;
Note that the Motorcycle class includes an overloaded method, Drive . Two methods have the same name, but
must be differentiated by their parameter types.
Method invocation
Methods can be either instance or static. Invoking an instance method requires that you instantiate an object and
call the method on that object; an instance method operates on that instance and its data. You invoke a static
method by referencing the name of the type to which the method belongs; static methods operate do not operate
on instance data. Attempting to call a static method through an object instance generates a compiler error.
Calling a method is like accessing a field. After the object name (if you are calling an instance method) or the type
name (if you are calling a static method), add a period, the name of the method, and parentheses. Arguments are
listed within the parentheses, and are separated by commas.
The method definition specifies the names and types of any parameters that are required. When a caller invokes the
method, it provides concrete values, called arguments, for each parameter. The arguments must be compatible with
the parameter type, but the argument name, if one is used in the calling code, does not have to be the same as the
parameter named defined in the method. In the following example, the Square method includes a single parameter
of type int named i. The first method call passes the Square method a variable of type int named num; the
second, a numeric constant; and the third, an expression.
public class Example
{
public static void Main()
{
// Call with an int variable.
int num = 4;
int productA = Square(num);
The most common form of method invocation used positional arguments; it supplies arguments in the same order
as method parameters. The methods of the Motorcycle class can therefore be called as in the following example.
The call to the Drive method, for example, includes two arguments that correspond to the two parameters in the
method's syntax. The first becomes the value of the miles parameter, the second the value of the speed
parameter.
moto.StartEngine();
moto.AddGas(15);
moto.Drive(5, 20);
double speed = moto.GetTopSpeed();
Console.WriteLine("My top speed is {0}", speed);
}
}
You can also used named arguments instead of positional arguments when invoking a method. When using named
arguments, you specify the parameter name followed by a colon (":") and the argument. Arguments to the method
can appear in any order, as long as all required arguments are present. The following example uses named
arguments to invoke the TestMotorcycle.Drive method. In this example, the named arguments are passed in the
opposite order from the method's parameter list.
using System;
You can invoke a method using both positional arguments and named arguments. However, a positional argument
cannot follow a named argument. The following example invokes the TestMotorcycle.Drive method from the
previous example using one positional argument and one named argument.
Types can override inherited members by using the override keyword and providing an implementation for the
overridden method. The method signature must be the same as that of the overriden method. The following
example is like the previous one, except that it overrides the @Object.Equals(System.Object) method. (It also
overrides the @Object.GetHashCode method, since the two methods are intended to provide consistent results.)
using System;
Passing parameters
Types in C# are either value types or reference types. For a list of built-in value types, see Types and variables. By
default, both value types and reference types are passed to a method by value.
Passing parameters by value
When a value type is passed to a method by value, a copy of the object instead of the object itself is passed to the
method. Therefore, changes to the object in the called method have no effect on the original object when control
returns to the caller.
The following example passes a value type to a method by value, and the called method attempts to change the
value type's value. It defines a variable of type int , which is a value type, initializes its value to 20, and passes it to
a method named ModifyValue that changes the variable's value to 30. When the method returns, however, the
variable's value remains unchanged.
using System;
When an object of a reference type is passed to a method by value, a reference to the object is passed by value.
That is, the method receives not the object itself, but an argument that indicates the location of the object. If you
change a member of the object by using this reference, the change is reflected in the object when control returns to
the calling method. However, replacing the object passed to the method has no effect on the original object when
control returns to the caller.
The following example defines a class (which is a reference type) named SampleRefType . It instantiates a
SampleRefType object, assigns 44 to its value field, and passes the object to the ModifyObject method. This
example does essentially the same thing as the previous example -- it passes an argument by value to a method.
But because a reference type is used, the result is different. The modification that is made in ModifyObject to the
obj.value field also changes the value field of the argument, rt , in the Main method to 33, as the output from
the example shows.
using System;
using System;
A common pattern that uses by ref parameters involves swapping the values of variables. You pass two variables to
a method by reference, and the method swaps their contents. The following example swaps integer values.
using System;
Passing a reference-type parameter allows you to change the value of the reference itself, rather than the value of
its individual elements or fields.
Parameter arrays
Sometimes, the requirement that you specify the exact number of arguments to your method is restrictive. By using
the params keyword to indicate that a parameter is a parameter array, you allow your method to be called with a
variable number of arguments. The parameter tagged with the params keyword must must be an array type, and it
must be the last parameter in the method's parameter list.
A caller can then invoke the method in either of three ways:
By passing an array of the appropriate type that contains the desired number of elements.
By passing a comma-separated list of individual arguments of the appropriate type to the method.
By not providing an argument to the parameter array.
The following example defines a method named DoStringOperation that performs the string operation specified by
its first parameter, a StringOperation enumeration member. The strings upon which it is to perform the operation
are defined by a parameter array. The Main method illustrates all three ways of invoking the method. Note that the
method tagged with the params keyword must be prepared to handle the case in which no argument is supplied
for the parameter array, so that its value is null .
using System;
class Example
{
static void Main()
{
int[] arr = {1, 4, 5};
Console.WriteLine("In Main, array has {0} elements and starts with {1}",
arr.Length, arr[0]);
Change(ref arr);
Console.WriteLine("Back in Main, array has {0} elements and starts with {1}",
arr.Length, arr[0]);
}
If a method includes both required and optional parameters, optional parameters are defined at the end of the
parameter list, after all required parameters.
The following example defines a method, ExampleMethod , that has one required and two optional parameters.
using System;
If a method with multiple optional arguments is invoked using positional arguments, the caller must supply an
argument for all optional parameters from the first one to the last one for which an argument is supplied. In the
case of the ExampleMethod method, for example, if the caller supplies an argument for the description parameter,
it must also supply one for the optionalInt parameter. opt.ExampleMethod(2, 2, "Addition of 2 and 2"); is a valid
method call; opt.ExampleMethod(2, , "Addition of 2 and 0); generates an "Argument missing" compiler error.
If a method is called using named arguments or a combination of positional and named arguments, the caller can
omit any arguments that follow the last positional argument in the method call.
The following example calls the ExampleMethod method three times. The first two method calls use positional
arguments. The first omits both optional arguments, while the second omits the last argument. The third method
call supplies a positional argument for the required parameter, but uses a named argument to supply a value to the
description parameter while omitting the optionalInt argument.
The use of optional parameters affects overload resolution, or the way in which the C# compiler determines which
particular overload should be invoked by a method call, as follows:
A method, indexer, or constructor is a candidate for execution if each of its parameters either is optional or
corresponds, by name or by position, to a single argument in the calling statement, and that argument can be
converted to the type of the parameter.
If more than one candidate is found, overload resolution rules for preferred conversions are applied to the
arguments that are explicitly specified. Omitted arguments for optional parameters are ignored.
If two candidates are judged to be equally good, preference goes to a candidate that does not have optional
parameters for which arguments were omitted in the call. This is a consequence of a general preference in
overload resolution for candidates that have fewer parameters.
Return values
Methods can return a value to the caller. If the return type (the type listed before the method name) is not void ,
the method can return the value by using the return keyword. A statement with the return keyword followed by
a variable, constant, or expression that matches the return type will return that value to the method caller. Methods
with a non-void return type are required to use the return keyword to return a value. The return keyword also
stops the execution of the method.
If the return type is void , a return statement without a value is still useful to stop the execution of the method.
Without the return keyword, the method will stop executing when it reaches the end of the code block.
For example, these two methods use the return keyword to return integers:
class SimpleMath
{
public int AddTwoNumbers(int number1, int number2)
{
return number1 + number2;
}
To use a value returned from a method, the calling method can use the method call itself anywhere a value of the
same type would be sufficient. You can also assign the return value to a variable. For example, the following two
code examples accomplish the same goal:
Using a local variable, in this case, result , to store a value is optional. It may help the readability of the code, or it
may be necessary if you need to store the original value of the argument for the entire scope of the method.
Sometimes, you want your method to return more than a single value. Starting with C# 7.0, you can do this easily
by using tuple types and tuple literals. The tuple type defines the data types of the tuple's elements. Tuple literals
provide the actual values of the returned tuple. In teh following example, (string, string, string, int) defines
the tuple type that is returned by the GetPersonalInfo method. The expression
(per.FirstName, per.MiddleName, per.LastName, per.Age) is the tuple literal; the method returns the first, middle,
and last name, along with the age, of a PersonInfo object.
The caller can then consume the returned tuple with code like the following:
Names can also be assigned to the tuple elements in the tuple type definition. The following example shows an
alternate version of the GetPersonalInfo method that uses named elements:
public (string FName, string MName, string LName, int Age) GetPersonalInfo(string id)
{
PersonInfo per = PersonInfo.RetrieveInfoById(id);
if (per != null)
return (per.FirstName, per.MiddleName, per.LastName, per.Age);
else
return null;
}
The previous call to the GetPersonInfo method can then be modified as follows:
If a method is passed an array as an argument and modifies the value of individual elements, it is not necessary for
the method to return the array, although you may choose to do so for good style or functional flow of values. This
is because C# passes all reference types by value, and the value of an array reference is the pointer to the array. In
the following example, changes to the contents of the values array that are made in the DoubleValues method are
observable by any code that has a reference to the array.
using System;
Extension methods
Ordinarily, there are two ways to add a method to an existing type:
Modify the source code for that type. You cannot do this, of course, if you do not own the type's source code.
And this becomes a breaking change if you also add any private data fields to support the method.
Define the new method in a derived class. A method cannot be added in this way using inheritance for other
types, such as structures and enumerations. Nor can it be used to "add" a method to a sealed class.
Extension methods let you "add" a method to an existing type without modifying the type itself or implementing
the new method in an inherited type. The extension method also does not have to reside in the same assembly as
the type it extends. You call an extension method as if it were a defined member of a type.
For more information, see Extension Methods.
Async Methods
By using the async feature, you can invoke asynchronous methods without using explicit callbacks or manually
splitting your code across multiple methods or lambda expressions.
If you mark a method with the async modifier, you can use the await operator in the method. When control reaches
an await expression in the async method, control returns to the caller if the awaited task is not completed, and
progress in the method with the await keyword is suspended until the awaited task completes. When the task is
complete, execution can resume in the method.
NOTE
An async method returns to the caller when either it encounters the first awaited object that’s not yet complete or it gets to
the end of the async method, whichever occurs first.
An async method can have a return type of @System.Threading.Tasks.Task<TResult>, Task, or void . The void
return type is used primarily to define event handlers, where a void return type is required. An async method that
returns void can't be awaited, and the caller of a void-returning method can't catch exceptions that the method
throws. C# 7, when it is released, will ease this restriction to allow an async method to return any task-like type.
In the following example, DelayAsync is an async method that has a return statement that returns an integer.
Because it is an async method, its method declaration must have a return type of Task<int> . Because the return
type is Task<int> , the evaluation of the await expression in DoSomethingAsync produces an integer, as the
following int result = await delayTask statement demonstrates.
using System;
using System.Diagnostics;
using System.Threading.Tasks;
// Output:
// Result: 5
}
// The example displays the following output:
// Result: 5
An async method can't declare any ref or out parameters, but it can call methods that have such parameters.
For more information about async methods, see Asynchronous Programming with Async and Await, Control Flow
in Async Programs, and Async Return Types.
Expression-bodied members
It is common to have method definitions that simply return immediately with the result of an expression, or that
have a single statement as the body of the method. There is a syntax shortcut for defining such methods using => :
public Point Move(int dx, int dy) => new Point(x + dx, y + dy);
public void Print() => Console.WriteLine(First + " " + Last);
// Works with operators, properties, and indexers too.
public static Complex operator +(Complex a, Complex b) => a.Add(b);
public string Name => First + " " + Last;
public Customer this[long id] => store.LookupCustomer(id);
If the method returns void or is an async method, the body of the method must be a statement expression (same
as with lambdas). For properties and indexers, they must be read-only, and you do not use the get accessor
keyword.
Iterators
An iterator performs a custom iteration over a collection, such as a list or an array. An iterator uses the yield return
statement to return each element one at a time. When a yield return statement is reached, the current location is
remembered so that the caller can request the next element in the sequence.
The return type of an iterator can be IEnumerable, IEnumerable<T>, IEnumerator, or IEnumerator<T>.
For more information, see Iterators.
See also
Access Modifiers
Static Classes and Static Class Members
Inheritance
Abstract and Sealed Classes and Class Members
params
out
ref
Passing Parameters
Lambda expressions
8/5/2017 • 10 min to read • Edit Online
A lambda expression is a block of code (an expression or a statement block) that is treated as an object. It can be
passed as an argument to methods, and it can also be returned by method calls. Lambda expressions are used
extensively for:
Passing the code that is to be executed to asynchronous methods, such as Run(Action).
Writing LINQ query expressions.
Creating expression trees.
Lambda expressions are code that can be represented either as a delegate, or as an expression tree that compiles to
a delegate. The specific delegate type of a lambda expression depends on its parameters and return value. Lambda
expressions that don't return a value correspond to a specific Action delegate, depending on its number of
parameters. Lambda expressions that return a value correspond to a specific Func delegate, depending on its
number of parameters. For example, a lambda expression that has two parameters but returns no value
corresponds to an Action<T1,T2> delegate. A lambda expression that has one parameter and returns a value
corresponds to Func<T,TResult> delegate.
A lambda expression uses => , the lambda declaration operator, to separate the lambda's parameter list from its
executable code. To create a lambda expression, you specify input parameters (if any) on the left side of the lambda
operator, and you put the expression or statement block on the other side. For example, the single-line lambda
expression x => x * x specifies a parameter that’s named x and returns the value of x squared. You can assign
this expression to a delegate type, as the following example shows:
using System;
class Example
{
public static void Main()
{
Func<int, int> square = x => x * x;
Console.WriteLine(square(25));
}
}
// The example displays the following output:
// 625
Expression lambdas
A lambda expression with an expression on the right side of the => operator is called an expression lambda.
Expression lambdas are used extensively in the construction of expression trees. An expression lambda returns the
result of the expression and takes the following basic form:
The parentheses are optional only if the lambda has one input parameter; otherwise they are required. Specify zero
input parameters with empty parentheses:
Ordinarily, the compiler uses type inference in determining parameter types. However, sometimes it is difficult or
impossible for the compiler to infer the input types. When this occurs, you can specify the types explicitly, as in the
following example:
Note in the previous example that the body of an expression lambda can consist of a method call. However, if you
are creating expression trees that are evaluated outside of the .NET Framework, such as in SQL Server or Entity
Framework (EF), you should refrain from using method calls in lambda expressions, since the methods may have
no meaning outside the context of the .NET implementation. If you do choose to use method calls in this case, be
sure to test them thoroughly to ensure that the method calls can be successfuly resolved.
Statement lambdas
A statement lambda resembles an expression lambda except that the statement(s) is enclosed in braces:
The body of a statement lambda can consist of any number of statements; however, in practice there are typically
no more than two or three.
using System;
Statement lambdas, like anonymous methods, cannot be used to create expression trees.
Async lambdas
You can easily create lambda expressions and statements that incorporate asynchronous processing by using the
async and await keywords. For example, the example calls a ShowSquares method that executes asynchronously.
using System;
using System.Threading.Tasks;
For more information about how to create and use async methods, see Asynchronous programming with async
and await.
using System;
Ordinarily, the fields of a tuple are named Item1 , Item2 , etc. You can, however, define a tuple with named
components, as the following example does.
using System;
For more information on support for tuples in C#, see C# Tuple types.
where int is an input parameter, and bool is the return value. The return value is always specified in the last type
parameter. When the following Func delegate is invoked, it returns true or false to indicate whether the input
parameter is equal to 5:
You can also supply a lambda expression when the argument type is an Expression<TDelegate>, for example in the
standard query operators that are defined in the Queryable type. When you specify an Expression<TDelegate>
argument, the lambda is compiled to an expression tree. The following example uses the
System.Linq.Enumerable.Count standard query operator.
int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };
int oddNumbers = numbers.Count(n => n % 2 == 1);
Console.WriteLine("There are {0} odd numbers in the set", oddNumbers);
// Output: There are 5 odd numbers in the set
The compiler can infer the type of the input parameter, or you can also specify it explicitly. This particular lambda
expression counts those integers ( n ) that, when divided by two, have a remainder of 1.
The following example produces a sequence that contains all elements in the numbers array that precede the 9,
because that's the first number in the sequence that doesn't meet the condition.
The following example specifies multiple input parameters by enclosing them in parentheses. The method returns
all the elements in the numbers array until it encounters a number whose value is less than its ordinal position in
the array.
class Test
{
D del;
D2 del2;
public void TestMethod(int input)
{
int j = 0;
// Initialize the delegates with lambda expressions.
// Note access to 2 outer variables.
// del will be invoked within this method.
del = () => { j = 10; return j > input; };
// Demonstrate value of j:
// Output: j = 0
// The delegate has not been invoked yet.
Console.WriteLine("j = {0}", j); // Invoke the delegate.
bool boolResult = del();
// Output: j = 10 b = True
Console.WriteLine("j = {0}. b = {1}", j, boolResult);
}
// Output: True
Console.WriteLine(result);
}
}
// The example displays the following output:
// j = 0
// j = 10. b = True
// True
See also
LINQ (Language-Integrated Query)
Anonymous methods
Expression trees
Properties
7/29/2017 • 8 min to read • Edit Online
Properties are first class citizens in C#. The language defines syntax that enables developers to write code that
accurately expresses their design intent.
Properties behave like fields when they are accessed. However, unlike fields, properties are implemented with
accessors that define the statements executed when a property is accessed or assigned.
Property Syntax
The syntax for properties is a natural extension to fields. A field defines a storage location:
A property definition contains declarations for a get and set accessor that retrieves and assigns the value of that
property:
The syntax shown above is the auto property syntax. The compiler generates the storage location for the field that
backs up the property. The compiler also implements the body of the get and set accessors.
Sometimes, you need to initialize a property to a value other than the default for its type. C# enables that by setting
a value after the closing brace for the property. You may prefer the initial value for the FirstName property to be
the empty string rather than null . You would specify that as shown below:
This is most useful for read-only properties, as you'll see later in this topic.
You can also define the storage yourself, as shown below:
public class Person
{
public string FirstName
{
get { return firstName; }
set { firstName = value; }
}
private string firstName;
// remaining implementation removed from listing
}
When a property implementation is a single expression, you can use expression bodied members for the getter or
setter:
This simplified syntax will be used where applicable throughout this topic.
The property definition shown above is a read-write property. Notice the keyword value in the set accessor. The
set accessor always has a single parameter named value . The get accessor must return a value that is
convertible to the type of the property ( string in this example).
That's the basics of the syntax. There are many different variations that support a variety of different design idioms.
Let's explore those, and learn the syntax options for each.
Scenarios
The examples above showed one of the simplest cases of property definition: a read-write property with no
validation. By writing the code you want in the get and set accessors, you can create many different scenarios.
Validation
You can write code in the set accessor to ensure that the values represented by a property are always valid. For
example, suppose one rule for the Person class is that the name cannot be blank, or whitespace. You would write
that as follows:
public class Person
{
public string FirstName
{
get => firstName;
set
{
if (string.IsNullOrWhiteSpace(value))
throw new ArgumentException("First name must not be blank");
firstName = value;
}
}
private string firstName;
// remaining implementation removed from listing
}
The example above enforces the rule that the first name must not be blank, or whitespace. If a developer writes
hero.FirstName = "";
That assignment throws an ArgumentException . Because a property set accessor must have a void return type, you
report errors in the set accessor by throwing an exception.
That is a simple case of validation. You can extend this same syntax to anything needed in your scenario. You can
check the relationships between different properties, or validate against any external conditions. Any valid C#
statements are valid in a property accessor.
Read-only
Up to this point, all the property definitions you have seen are read/write properties with public accessors. That's
not the only valid accessibility for properties. You can create read-only properties, or give different accessibility to
the set and get accessors. Suppose that your Person class should only enable changing the value of the FirstName
property from other methods in that class. You could give the set accessor private accessibility instead of public
:
Now, the FirstName property can be accessed from any code, but it can only be assigned from other code in the
Person class.
You can add any restrictive access modifier to either the set or get accessors. Any access modifier you place on the
individual accessor must be more limited than the access modifier on the property definition. The above is legal
because the FirstName property is public , but the set accessor is private . You could not declare a private
property with a public accessor. Property declarations can also be declared protected , internal ,
protected internal or even private .
It is also legal to place the more restrictive modifier on the get accessor. For example, you could have a public
property, but restrict the get accessor to private . That scenario is rarely done in practice.
You can also restrict modifications to a property so that it can only be set in a constructor or a property initializer.
You can modify the Person class so as follows:
public class Person
{
public Person(string firstName)
{
this.FirstName = firstName;
}
This feature is most commonly used for initializing collections that are exposed as read-only properties:
Computed Properties
A property does not need to simply return the value of a member field. You can create properties that return a
computed value. Let's expand the Person object to return the full name, computed by concatenating the first and
last names:
The example above uses the String Interpolation syntax to create the formatted string for the full name.
You can also use Expression-bodied Members, which provides a more succinct way to create the computed
FullName property:
Expression-bodied Members use the lambda expression syntax to define a method that contain a single expression.
Here, that expression returns the full name for the person object.
Lazy Evaluated Properties
You can mix the concept of a computed property with storage and create a lazy evaluated property. For example,
you could update the FullName property so that the string formatting only happened the first time it was accessed:
public class Person
{
public string FirstName { get; set; }
The above code contains a bug though. If code updates the value of either the FirstName or LastName property,
the previously evaluated fullName field is invalid. You need to update the set accessors of the FirstName and
LastName property so that the fullName field is calculated again:
This final version evaluates the FullName property only when needed. If the previously calculated version is valid,
it's used. If another state change invalidates the previously calculated version, it will be recalculated. Developers
that use this class do not need to know the details of the implementation. None of these internal changes affect the
use of the Person object. That's the key reason for using Properties to expose data members of an object.
INotifyPropertyChanged
A final scenario where you need to write code in a property accessor is to support the INotifyPropertyChanged
interface used to notify data binding clients that a value has changed. When the value of a property changes, the
object raises the PropertyChanged event to indicate the change. The data binding libraries, in turn, update display
elements based on that change. The code below shows how you would implement INotifyPropertyChanged for the
FirstName property of this person class.
The ?. operator is called the null conditional operator. It checks for a null reference before evaluating the right
side of the operator. The end result is that if there are no subscribers to the PropertyChanged event, the code to
raise the event doesn't execute. It would throw a NullReferenceException without this check in that case. See the
page on events for more details. This example also uses the new nameof operator to convert from the property
name symbol to its text representation. Using nameof can reduce errors where you have mistyped the name of the
property.
Again, this is an example of a case where you can write code in your accessors to support the scenarios you need.
Summing up
Properties are a form of smart fields in a class or object. From outside the object, they appear like fields in the
object. However, properties can be implemented using the full palette of C# functionality. You can provide
validation, different accessibility, lazy evaluation, or any requirements your scenarios need.
Indexers
7/29/2017 • 9 min to read • Edit Online
Indexers are similar to properties. In many ways indexers build on the same language features as properties.
Indexers enable indexed properties: properties referenced using one or more arguments. Those arguments provide
an index into some collection of values.
Indexer Syntax
You access an indexer through a variable name and square brackets . You place the indexer arguments inside the
brackets:
You declare indexers using the this keyword as the property name, and declaring the arguments within square
brackets. This declaration would match the usage shown in the previous paragraph:
From this initial example, you can see the relationship between the syntax for properties and for indexers. This
analogy carries through most of the syntax rules for indexers. Indexers can have any valid access modifiers (public,
protected internal, protected, internal, or private). They may be sealed, virtual, or abstract. As with properties, you
can specify different access modifiers for the get and set accesssors in an indexer. You may also specify read-only
indexers (by omitting the set accessor), or write-only indexers (by omitting the get accessor).
You can apply almost everything you learn from working with properties to indexers. The only exception to that
rule is auto implemented properties. The compiler cannot always generate the correct storage for an indexer.
The presence of arguments to reference an item in a set of items distinguishes indexers from properties. You may
define multiple indexers on a type, as long as the argument lists for each indexer is unique. Let's explore different
scenarios where you might use one or more indexers in a class definition.
Scenarios
You would define indexers in your type when its API models some collection where you define the arguments to
that collection. Your indexers may or may not map directly to the collection types that are part of the .NET core
framework. Your type may have other responsibilities in addition to modeling a collection. Indexers enable you to
provide the API that matches your type's abstraction without exposing the inner details of how the values for that
abstraction are stored or computed.
Let's walk through some of the common scenarios for using indexers. You can access the sample folder for
indexers. For download instructions, see Samples and Tutorials.
Arrays and Vectors
One of the most common scenarios for creating indexers is when your type models an array, or a vector. You can
create an indexer to model an ordered list of data.
The advantage of creating your own indexer is that you can define the storage for that collection to suit your needs.
Imagine a scenario where your type models historical data that is too large to load into memory at once. You need
to load and unload sections of the collection based on usage. The example following models this behavior. It
reports on how many data points exist. It creates pages to hold sections of the data on demand. It removes pages
from memory to make room for pages needed by more recent requests.
page[index] = value;
}
}
You can follow this design idiom to model any sort of collection where there are good reasons not to load the
entire set of data into an in- memory collection. Notice that the Page class is a private nested class that is not part
of the public interface. Those details are hidden from any users of this class.
Dictionaries
Another common scenario is when you need to model a dictionary or a map. This scenario is when your type stores
values based on key, typically text keys. This example creates a dictionary that maps command line arguments to
lamdba expressions that manage those options. The following example shows two classes: an ArgsActions class
that maps a command line option to an Action delegate, and an ArgsProcessor that uses the ArgsActions to
execute each Action when it encounters that option.
}
public class ArgsActions
{
readonly private Dictionary<string, Action> argsActions = new Dictionary<string, Action>();
In this example, the ArgsAction collection maps closely to the underlying collection. The get determines if a given
option has been configured. If so, it returns the Action associated with that option. If not, it returns an Action that
does nothing. The public accessor does not include a set accessor. Rather, the design using a public method for
setting options.
Multi-Dimensional Maps
You can create indexers that use multiple arguments. In addition, those arguments are not constrained to be the
same type. Let's look at two examples.
The first example shows a class that generates values for a Mandelbrot set. For more information on the
mathematics behind the set, read this article. The indexer uses two doubles to define a point in the X, Y plane. The
get accessor computes the number of iterations until a point is determined to be not in the set. If the maximum
iterations is reached, the point is in the set, and the class's maxIterations value is returned. (The computer
generated images popularized for the Mandelbrot set define colors for the number of iterations necessary to
determine that a point is outside the set.
public class Mandelbrot
{
readonly private int maxIterations;
The Mandelbrot Set defines values at every (x,y) coordinate for real number values. That defines a dictionary that
could contain an infinite number of values. Therefore, there is no storage behind the set. Instead, this class
computes the value for each point when code calls the get accessor. There's no underlying storage used.
Let's examine one last use of indexers, where the indexer takes multiple arguments of different types. Consider a
program that manages historical temperature data. This indexer uses a city and a date to set or get the high and
low temperatures for that location:
using DateMeasurements =
System.Collections.Generic.Dictionary<System.DateTime, IndexersSamples.Common.Measurements>;
using CityDataMeasurements =
System.Collections.Generic.Dictionary<string, System.Collections.Generic.Dictionary<System.DateTime,
IndexersSamples.Common.Measurements>>;
This example creates an indexer that maps weather data on two different arguments: a city (represented by a
string ) and a date (represented by a DateTime ). The internal storage uses two Dictionary classes to represent
the two-dimensional dictionary. The public API no longer represents the underlying storage. Rather, the language
features of indexers enables you to create a public interface that represents your abstraction, even though the
underlying storage must use different core collection types.
There are two parts of this code that may be unfamiliar to some developers. These two using statements:
create an alias for a constructed generic type. Those statements enable the code later to use the more descriptive
DateMeasurements and CityDateMeasurements names instead of the generic construction of
Dictionary<DateTime, Measurements> and Dictionary<string, Dictionary<DateTime, Measurements> > . This construct
does require using the fully qualified type names on the right side of the = sign.
The second technique is to strip off the time portions of any DateTime object used to index into the collections. The
.NET framework does not include a Date only type. Developers use the DateTime type, but use the Date property
to ensure that any DateTime object from that day are equal.
Summing Up
You should create indexers anytime you have a property-like element in your class where that property represents
not a single value, but rather a collection of values where each individual item is identified by a set of arguments.
Those arguments can uniquely identify which item in the collection should be referenced. Indexers extend the
concept of properties, where a member is treated like a data item from outside the class, but like a method on the
side. Indexers allow arguments to find a single item in a property that represents a set of items.
Discards - C# Guide
8/29/2017 • 7 min to read • Edit Online
Starting with C# 7, C# supports discards, which are temporary, dummy variables that are intentionally unused in
application code. Discards are equivalent to unassigned variables; they do not have a value. Because there is only a
single discard variable, and that variable may not even be allocated storage, discards can reduce memory
allocations. Because they make the intent of your code clear, they enhance its readability and maintainability.
You indicate that a variable is a discard by assigning it the underscore ( _ ) as its name. For example, the following
method call returns a 3-tuple in which the first and second values are discards:
private static (string, double, int, int, int, int) QueryCityDataForYears(string name, int year1, int
year2)
{
int population1 = 0, population2 = 0;
double area = 0;
For more information on deconstructing tuples with discards, see Deconstructing tuples and other types.
The Deconstruct method of a class, structure, or interface also allows you to retrieve and deconstruct a specific set
of data from an object. You can use discards when you are interested in working with only a subset of the
deconstructed values. Ihe following example deconstructs a Person object into four strings (the first and last
names, the city, and the state), but discards the last name and the state.
using System;
public void Deconstruct(out string fname, out string mname, out string lname)
{
fname = FirstName;
mname = MiddleName;
lname = LastName;
}
// <Snippet1>
// Deconstruct the person object.
var (fName, _, city, _) = p;
Console.WriteLine($"Hello {fName} of {city}!");
// The example displays the following output:
// Hello John of Boston!
// </Snippet1>
}
}
// The example displays the following output:
// Hello John Adams of Boston, MA!
For more information on deconstructing user-defined types with discards, see Deconstructing tuples and other
types.
Pattern matching with switch and is
The discard pattern can be used in pattern matching with the is and switch keywords. Every expression always
matches the discard pattern.
The following example defines a ProvidesFormatInfo method that uses is statements to determine whether an
object provides an IFormatProvider implementation and tests whether the object is null . It also uses the discard
pattern to handle non-null objects of any other type.
using System;
using System.Globalization;
A standalone discard
You can use a standalone discard to indicate any variable that you choose to ignore. The following example uses a
standalone discard to ignore the Task object returned by an asynchronous operation. This has the effect of
suppressing the exception that the operation throws as it is about to complete.
using System;
using System.Threading.Tasks;
Note that _ is also a valid identifier. When used outside of a supported context, _ is treated not as a discard but
as a valid variable. If an identifier named _ is already in scope, the use of _ as a standalone discard can result in:
Accidental modification of the value of the in-scope _ variable by assigning it the value of the intended
discard. For example:
Compiler error CS0136, "A local or parameter named '_' cannot be declared in this scope because that name
is used in an enclosing local scope to define a local or parameter." For example:
public void DoSomething(int _)
{
var _ = GetValue(); // Error: cannot declare local _ when one is already in scope
}
// The example displays the following compiler error:
// error CS0136:
// A local or parameter named '_' cannot be declared in this scope
// because that name is used in an enclosing local scope
// to define a local or parameter
See also
Deconstructing tuples and other types
is keyword
switch keyword
Generics (C# Programming Guide)
8/29/2017 • 1 min to read • Edit Online
Generics were added to version 2.0 of the C# language and the common language runtime (CLR). Generics
introduce to the .NET Framework the concept of type parameters, which make it possible to design classes and
methods that defer the specification of one or more types until the class or method is declared and instantiated by
client code. For example, by using a generic type parameter T you can write a single class that other client code can
use without incurring the cost or risk of runtime casts or boxing operations, as shown here:
Generics Overview
Use generic types to maximize code reuse, type safety, and performance.
The most common use of generics is to create collection classes.
The .NET Framework class library contains several new generic collection classes in the
System.Collections.Generic namespace. These should be used whenever possible instead of classes such as
ArrayList in the System.Collections namespace.
You can create your own generic interfaces, classes, methods, events and delegates.
Generic classes may be constrained to enable access to methods on particular data types.
Information on the types that are used in a generic data type may be obtained at run-time by using
reflection.
Related Sections
For more information:
Introduction to Generics
Benefits of Generics
Generic Type Parameters
Constraints on Type Parameters
Generic Classes
Generic Interfaces
Generic Methods
Generic Delegates
Differences Between C++ Templates and C# Generics
Generics and Reflection
Generics in the Run Time
Generics in the .NET Framework Class Library
C# Language Specification
For more information, see the C# Language Specification.
See Also
System.Collections.Generic
C# Programming Guide
Types
<typeparam>
<typeparamref>
Iterators
7/29/2017 • 5 min to read • Edit Online
Almost every program you write will have some need to iterate over a collection. You'll write code that examines
every item in a collection.
You'll also create iterator methods which are methods that produces an iterator for the elements of that class.
These can be used for:
Performing an action on each item in a collection.
Enumerating a custom collection.
Extending LINQ or other libraries.
Creating a data pipeline where data flows efficiently through iterator methods.
The C# language provides features for both these scenarios. This article provides an overview of those features.
This tutorial has multiple steps. After each step, you can run the application and see the progress. You can also view
or download the completed sample for this topic. For download instructions, see Samples and Tutorials.
That's all there is to it. To iterate over all the contents of a collection, the foreach statement is all you need. The
foreach statement isn't magic, though. It relies on two generic interfaces defined in the .NET core library in order
to generate the code necessary to iterate a collection: IEnumerable<T> and IEnumerator<T> . This mechanism is
explained in more detail below.
Both of these interfaces also have non-generic counterparts: IEnumerable and IEnumerator . The generic versions
are preferred for modern code.
The code above shows distinct yield return statements to highlight the fact that you can use multiple discrete
yield return statements in an iterator method. You can (and often do) use other language constructs to simplify
the code of an iterator method. The method definition below produces the exact same sequence of numbers:
You don't have to decide one or the other. You can have as many yield return statements as necessary to meet
the needs of your method:
index = 100;
while (index++ < 110)
yield return index;
}
That's the basic syntax. Let's consider a real world example where you would write an iterator method. Imagine
you're on an IoT project and the device sensors generate a very large stream of data. To get a feel for the data, you
might write a method that samples every Nth data element. This small iterator method does the trick:
There is one important restriction on iterator methods: you can't have both a return statement and a
yield return statement in the same method. The following will not compile:
public IEnumerable<int> GetSingleDigitNumbers()
{
int index = 0;
while (index++ < 10)
yield return index;
This restriction normally isn't a problem. You have a choice of either using yield return throughout the method,
or separating the original method into multiple methods, some using return , and some using yield return .
You can modify the last method slightly to use yield return everywhere:
var items = new int[] {100, 101, 102, 103, 104, 105, 106, 107, 108, 109 };
foreach (var item in items)
yield return item;
}
Sometimes, the right answer is to split an iterator method into two different methods. One that uses return , and a
second that uses yield return . Consider a situation where you might want to return an empty collection, or the
first 5 odd numbers, based on a boolean argument. You could write that as these two methods:
Look at the methods above. The first uses the standard return statement to return either an empty collection, or
the iterator created by the second method. The second method uses the yield return statement to create the
requested sequence.
The construct above represents the code generated by the C# compiler as of version 5 and above. Prior to version
5, the item variable had a different scope:
// C# versions 1 through 4:
IEnumerator<int> enumerator = collection.GetEnumerator();
int item = default(int);
while (enumerator.MoveNext())
{
item = enumerator.Current;
Console.WriteLine(item.ToString());
}
This was changed because the earlier behavior could lead to subtle and hard to diagnose bugs involving lambda
expressions. See the section on lambda expressions for more information.
The exact code generated by the compiler is somewhat more complicated, and handles situations where the object
returned by GetEnumerator() implements the IDisposable interface. The full expansion generates code more like
this:
{
var enumerator = collection.GetEnumerator();
try
{
while (enumerator.MoveNext())
{
var item = enumerator.Current;
Console.WriteLine(item.ToString());
}
} finally
{
// dispose of enumerator.
}
}
The manner in which the enumerator is disposed of depends on the characteristics of the type of enumerator . In
the general case, the finally clause expands to:
finally
{
(enumerator as IDisposable)?.Dispose();
}
However, if the type of enumerator is a sealed type and there is no implicit conversion from the type of enumerator
to IDisposable , the finally clause expands to an empty block:
finally
{
}
If there is an implicit conversion from the type of enumerator to IDisposable , and enumerator is a non-nullable
value type, the finally clause expands to:
finally
{
((IDisposable)enumerator).Dispose();
}
Thankfully, you don't need to remember all these details. The foreach statement handles all those nuances for you.
The compiler will generate the correct code for any of these constructs.
Delegates & events
7/29/2017 • 1 min to read • Edit Online
Previous
Delegates provide a late binding mechanism in .NET. Late Binding means that you create an algorithm where the
caller also supplies at least one method that implements part of the algorithm.
For example, consider sorting a list of stars in an astronomy application. You may choose to sort those stars by
their distance from the earth, or the magnitude of the star, or their perceived brightness.
In all those cases, the Sort() method does essentially the same thing: arranges the items in the list based on some
comparison. The code that compares two stars is different for each of the sort orderings.
These kinds of solutions have been used in software for half a century. The C# language delegate concept provides
first class language support, and type safety around the concept.
As you'll see later in this series, the C# code you write for algorithms like this is type safe, and leverages the
language and the compiler to ensure that the types match for arguments and return types.
Previous
This article will cover the classes in the .NET framework that support delegates, and how those map to the
delegate keyword.
The compiler generates a class, derived from System.Delegate that matches the signature used (in this case, a
method that returns an integer, and has two arguments). The type of that delegate is Comparison . The Comparison
delegate type is a generic type. For details on generics see here.
Notice that the syntax may appear as though it is declaring a variable, but it is actually declaring a type. You can
define delegate types inside classes, directly inside namespaces, or even in the global namespace.
NOTE
Declaring delegate types (or other types) directly in the global namespace is not recommended.
The compiler also generates add and remove handlers for this new type so that clients of this class can add and
remove methods from an instance's invocation list. The compiler will enforce that the signature of the method
being added or removed matches the signature used when declaring the method.
The type of the variable is Comparison<T> , the delegate type defined earlier. The name of the variable is
comparator .
That code snippet above declared a member variable inside a class. You can also declare delegate variables that
are local variables, or arguments to methods.
Invoking Delegates
You invoke the methods that are in the invocation list of a delegate by calling that delegate. Inside the Sort()
method, the code will call the comparison method to determine which order to place objects:
In the line above, the code invokes the method attached to the delegate. You treat the variable as a method name,
and invoke it using normal method call syntax.
That line of code makes an unsafe assumption: There's no guarantee that a target has been added to the delegate.
If no targets have been attached, the line above would cause a NullReferenceException to be thrown. The idioms
used to address this problem are more complicated than a simple null-check, and are covered later in this series.
The method is declared as a private method. That's fine. You may not want this method to be part of your public
interface. It can still be used as the comparison method when attached to a delegate. The calling code will have this
method attached to the target list of the delegate object, and can access it through that delegate.
You create that relationship by passing that method to the List.Sort() method:
phrases.Sort(CompareLength);
Notice that the method name is used, without parentheses. Using the method as an argument tells the compiler to
convert the method reference into a reference that can be used as a delegate invocation target, and attach that
method as an invocation target.
You could also have been explicit by declaring a variable of type 'Comparison` and doing an assignment:
In uses where the method being used as a delegate target is a small method, it's common to use Lambda
Expression syntax to perform the assignment:
Comparison<string> comparer = (left, right) => left.Length.CompareTo(right.Length);
phrases.Sort(comparer);
Using Lambda Expressions for delegate targets is covered more in a later section.
The Sort() example typically attaches a single target method to the delegate. However, delegate objects do support
invocation lists that have multiple target methods attached to a delegate object.
Previous
In the previous article, you saw that you create specific delegate types using the delegate keyword.
The abstract Delegate class provide the infrastructure for loose coupling and invocation. Concrete Delegate types
become much more useful by embracing and enforcing type safety for the methods that are added to the
invocation list for a delegate object. When you use the delegate keyword and define a concrete delegate type, the
compiler generates those methods.
In practice, this would lead to creating new delegate types whenever you need a different method signature. This
work could get tedious after a time. Every new feature requires new delegate types.
Thankfully, this isn't necessary. The .NET Core framework contains several types that you can reuse whenever you
need delegate types. These are generic definitions so you can declare customizations when you need new method
declarations.
The first of these types is the Action type, and several variations:
The in modifier on the generic type argument is covered in the article on covariance.
There are variations of the Action delegate that contain up to 16 arguments such as
Action<T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16> . It's important that these definitions use different
generic arguments for each of the delegate arguments: That gives you maximum flexibility. The method arguments
need not be, but may be, the same type.
Use one of the Action types for any delegate type that has a void return type.
The framework also includes several generic delegate types that you can use for delegate types that return values:
The out modifier on the result generic type argument is covered in the article on covariance.
There are variations of the Func delegate with up to 16 input arguments such as
Func<T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,TResult> . The type of the result is always the last
type parameter in all the Func declarations, by convention.
Use one of the Func types for any delegate type that returns a value.
There's also a specialized Predicate<T> type for a delegate that returns a test on a single value:
You might think these two types are equivalent. They are not. These two variables cannot be used interchangeably.
A variable of one type cannot be assigned the other type. The C# type system uses the names of the defined types,
not the structure.
All these delegate type definitions in the .NET Core Library should mean that you do not need to define a new
delegate type for any new feature you create that requires delegates. These generic definitions should provide all
the delegate types you need under most situations. You can simply instantiate one of these types with the required
type parameters. In the case of algorithms that can be made generic, these delegates can be used as generic types.
This should save time, and minimize the number of new types that you need to create in order to work with
delegates.
In the next article, you'll see several common patterns for working with delegates in practice.
Next
Common Patterns for Delegates
7/29/2017 • 8 min to read • Edit Online
Previous
Delegates provide a mechanism that enables software designs involving minimal coupling between components.
One excellent example for this kind of design is LINQ. The LINQ Query Expression Pattern relies on delegates for
all of its features. Consider this simple example:
This filters the sequence of numbers to only those less than the value 10. The Where method uses a delegate that
determines which elements of a sequence pass the filter. When you create a LINQ query, you supply the
implementation of the delegate for this specific purpose.
The prototype for the Where method is:
This example is repeated with all the methods that are part of LINQ. They all rely on delegates for the code that
manages the specific query. This API design pattern is a very powerful one to learn and understand.
This simple example illustrates how delegates require very little coupling between components. You don't need to
create a class that derives from a particular base class. You don't need to implement a specific interface. The only
requirement is to provide the implementation of one method that is fundamental to the task at hand.
The static class above is the simplest thing that can work. We need to write the single implementation for the
method that writes messages to the console:
Finally, you need to hook up the delegate by attaching it to the WriteMessage delegate declared in the logger:
Logger.WriteMessage += LogToConsole;
Practices
Our sample so far is fairly simple, but it still demonstrates some of the important guidelines for designs involving
delegates.
Using the delegate types defined in the Core Framework makes it easier for users to work with the delegates. You
don't need to define new types, and developers using your library do not need to learn new, specialized delegate
types.
The interfaces used are as minimal and as flexible as possible: To create a new output logger, you must create one
method. That method may be a static method, or an instance method. It may have any access.
Formatting Output
Let's make this first version a bit more robust, and then start creating other logging mechanisms.
Next, let's add a few arguments to the LogMessage() method so that your log class creates more structured
messages:
// Logger implementation two
public enum Severity
{
Verbose,
Trace,
Information,
Warning,
Error,
Critical
}
Next, let's make use of that Severity argument to filter the messages that are sent to the log's output.
Practices
You've added new features to the logging infrastructure. Because the logger component is very loosely coupled to
any output mechanism, these new features can be added with no impact on any of the code implementing the
logger delegate.
As you keep building this, you'll see more examples of how this loose coupling enables greater flexibility in
updating parts of the site without any changes to other locations. In fact, in a larger application, the logger output
classes might be in a different assembly, and not even need to be rebuilt.
Once you've created this class, you can instantiate it and it attaches its LogMessage method to the Logger
component:
These two are not mutually exclusive. You could attach both log methods and generate messages to the console
and a file:
Later, even in the same application, you can remove one of the delegates without any other issues to the system:
Logger.WriteMessage -= LogToConsole;
Practices
Now, you've added a second output handler for the logging sub-system. This one needs a bit more infrastructure
to correctly support the file system. The delegate is an instance method. It's also a private method. There's no need
for greater accessibility because the delegate infrastructure can connect the delegates.
Second, the delegate-based design enables multiple output methods without any extra code. You don't need to
build any additional infrastructure to support multiple output methods. They simply become another method on
the invocation list.
Pay special attention to the code in the file logging output method. It is coded to ensure that it does not throw any
exceptions. While this isn't always strictly necessary, it's often a good practice. If either of the delegate methods
throws an exception, the remaining delegates that are on the invocation won't be invoked.
As a last note, the file logger must manage its resources by opening and closing the file on each log message. You
could choose to keep the file open and implement IDisposable to close the file when you are completed. Either
method has its advantages and disadvantages. Both do create a bit more coupling between the classes.
None of the code in the Logger class would need to be updated in order to support either scenario.
The null conditional operator ( ?. ) short-circuits when the left operand ( WriteMessage in this case) is null, which
means no attempt is made to log a message.
You won't find the Invoke() method listed in the documentation for System.Delegate or
System.MulticastDelegate . The compiler generates a type safe Invoke method for any delegate type declared. In
this example, that means Invoke takes a single string argument, and has a void return type.
Summary of Practices
You've seen the beginnings of a log component that could be expanded with other writers, and other features. By
using delegates in the design these different components are very loosely coupled. This provides several
advantages. It's very easy to create new output mechanisms and attach them to the system. These other
mechanisms only need one method: the method that writes the log message. It's a design that is very resilient
when new features are added. The contract required for any writer is to implement one method. That method
could be a static or instance method. It could be public, private, or any other legal access.
The Logger class can make any number of enhancements or changes without introducing breaking changes. Like
any class, you cannot modify the public API without the risk of breaking changes. But, because the coupling
between the logger and any output engines is only through the delegate, no other types (like interfaces or base
classes) are involved. The coupling is as small as possible.
Next
Introduction to Events
7/29/2017 • 3 min to read • Edit Online
Previous
Events are, like delegates, a late binding mechanism. In fact, events are built on the language support for delegates.
Events are a way for an object to broadcast (to all interested components in the system) that something has
happened. Any other component can subscribe to the event, and be notified when an event is raised.
You've probably used events in some of your programming. Many graphical systems have an event model to
report user interaction. These events would report mouse movement, button presses and similar interactions.
That's one of the most common, but certainly not the only scenario where events are used.
You can define events that should be raised for your classes. One important consideration when working with
events is that there may not be any object registered for a particular event. You must write your code so that it
does not raise events when no listeners are configured.
Subscribing to an event also creates a coupling between two objects (the event source, and the event sink). You
need to ensure that the event sink unsubscribes from the event source when no longer interested in events.
The type of the event ( EventHandler<FileListArgs> in this example) must be a delegate type. There are a number of
conventions that you should follow when declaring an event. Typically, the event delegate type has a void return.
Event declarations should be a verb, or a verb phrase. Use past tense (as in this example) when the event reports
something that has happened. Use a present tense verb (for example, Closing ) to report something that is about
to happen. Often, using present tense indicates that your class supports some kind of customization behavior. One
of the most common scenarios is to support cancellation. For example, a Closing event may include an argument
that would indicate if the close operation should continue, or not. Other scenarios may enable callers to modify
behavior by updating properties of the event arguments. You may raise an event to indicate a proposed next action
an algorithm will take. The event handler may mandate a different action by modifying properties of the event
argument.
When you want to raise the event, you call the event handlers using the delegate invocation syntax:
As discussed in the section on delegates, the ?. operator makes it easy to ensure that you do not attempt to raise
the event when there are no subscribers to that event.
You subscribe to an event by using the += operator:
The handler method typically is the prefix 'On' followed by the event name, as shown above.
You unsubscribe using the -= operator:
lister.Progress -= onProgress;
It's important to note that I declared a local variable for the expression that represents the event handler. That
ensures the unsubscribe removes the handler. If, instead, you used the body of the lambda expression, you are
attempting to remove a handler that has never been attached, which does nothing.
In the next article, you'll learn more about typical event patterns, and different variations on this example.
Next
Standard .NET event patterns
7/29/2017 • 8 min to read • Edit Online
Previous
.NET events generally follow a few known patterns. Standardizing on these patterns means that developers can
leverage knowledge of those standard patterns, which can be applied to any .NET event program.
Let's go through these standard patterns so you will have all the knowledge you need to create standard event
sources, and subscribe and process standard events in your code.
The return type is void. Events are based on delegates and are multicast delegates. That supports multiple
subscribers for any event source. The single return value from a method doesn't scale to multiple event
subscribers. Which return value does the event source see after raising an event? Later in this article you'll see how
to create event protocols that support event subscribers that report information to the event source.
The argument list contains two arguments: the sender, and the event arguments. The compile time type of sender
is System.Object , even though you likely know a more derived type that would always be correct. By convention,
use object .
The second argument has typically been a type that is derived from System.EventArgs . (You'll see in the next
section that this convention is no longer enforced.) If your event type does not need any additional arguments, you
will still provide both arguments. There is a special value, EventArgs.Empty that you should use to denote that your
event does not contain any additional information.
Let's build a class that lists files in a directory, or any of its subdirectories that follow a pattern. This component
raises an event for each file found that matches the pattern.
Using an event model provides some design advantages. You can create multiple event listeners that perform
different actions when a sought file is found. Combining the different listeners can create more robust algorithms.
Here is the initial event argument declaration for finding a sought file:
Even though this type looks like a small, data-only type, you should follow the convention and make it a reference (
class ) type. That means the argument object will be passed by reference, and any updates to the data will be
viewed by all subscribers. The first version is an immutable object. You should prefer to make the properties in
your event argument type immutable. That way, one subscriber cannot change the values before another
subscriber sees them. (There are exceptions to this, as you'll see below.)
Next, we need to create the event declaration in the FileSearcher class. Leveraging the EventHandler<T> type means
that you don't need to create yet another type definition. You simply use a generic specialization.
Let's fill out the FileSearcher class to search for files that match a pattern, and raise the correct event when a match
is discovered.
This looks like it's declaring a public field, which would appear to be bad object oriented practice. You want to
protect data access through properties, or methods. While this make look like a bad practice, the code generated by
the compiler does create wrappers so that the event objects can only be accessed in safe ways. The only operations
available on a field-like event are add handler:
lister.FileFound -= onFileFound;
Note that there's a local variable for the handler. If you used the body of the lambda, the remove would not work
correctly. It would be a different instance of the delegate, and silently do nothing.
Code outside the class cannot raise the event, nor can it perform any other operations.
This new Field should be initialized to false, so you don't cancel for no reason. That is the default value for a
boolean field, so that happens automatically. The only other change to the component is to check the flag after
raising the event to see if any of the subscribers have requested a cancellation:
One advantage of this pattern is that it isn't a breaking change. None of the subscribers requested a cancel before,
and they still are not. None of the subscriber code needs updating unless they want to support the new cancel
protocol. It's very loosely coupled.
Let's update the subscriber so that it requests a cancellation once it finds the first executable:
Again, you can follow the recommendations to make an immutable reference type for the event arguments.
Next, define the event. This time, you'll use a different syntax. In addition to using the field syntax, you can explicitly
create the property, with add and remove handlers. In this sample, you won't need extra code in those handlers in
this project, but this shows how you would create them.
In may ways, the code you write here mirrors the code the compiler generates for the field event definitions you've
seen earlier. You create the event using syntax very similar to that used for properties. Notice that the handlers
have different names: add and remove . These are called to subscribe to the event, or unsubscribe from the event.
Notice that you also must declare a private backing field to store the event variable. It is initialized to null.
Next, let's add the overload of the Search() method that traverses subdirectories and raises both events. The easiest
way to accomplish this is to use a default argument to specify that you want to search all directories:
public void Search(string directory, string searchPattern, bool searchSubDirs = false)
{
if (searchSubDirs)
{
var allDirectories = Directory.GetDirectories(directory, "*.*", SearchOption.AllDirectories);
var completedDirs = 0;
var totalDirs = allDirectories.Length + 1;
foreach (var dir in allDirectories)
{
directoryChanged?.Invoke(this,
new SearchDirectoryArgs(dir, totalDirs, completedDirs++));
// Recursively search this child directory:
SearchDirectory(dir, searchPattern);
}
// Include the Current Directory:
directoryChanged?.Invoke(this,
new SearchDirectoryArgs(directory, totalDirs, completedDirs++));
SearchDirectory(directory, searchPattern);
}
else
{
SearchDirectory(directory, searchPattern);
}
}
At this point, you can run the application calling the overload for searching all sub-directories. There are no
subscribers on the new ChangeDirectory event, but using the ?.Invoke() idiom ensures that this works correctly.
Let's add a handler to write a line that shows the progress in the console window.
You've seen patterns that are followed throughout the .NET ecosystem. By learning these patterns and conventions,
you'll be writing idiomatic C# and .NET quickly.
Next, you'll see some changes in these patterns in the most recent release of .NET.
Next
The Updated .NET Core Event Pattern
7/29/2017 • 3 min to read • Edit Online
Previous
The previous article discussed the most common event patterns. .NET Core has a more relaxed pattern. In this
version, the EventHandler<TEventArgs> definition no longer has the constraint that TEventArgs must be a class
derived from System.EventArgs .
This increases flexibility for you, and is backwards compatible. Let's start with the flexibility. The class
System.EventArgs introduces one method: MemberwiseClone() , which creates a shallow copy of the object. That
method must use reflection in order to implement its functionality for any class derived from EventArgs . That
functionality is easier to create in a specific derived class. That effectively means that deriving from
System.EventArgs is a constraint that limits your designs, but does not provide any additional benefit. In fact, you
can changes the definitions of FileFoundArgs and SearchDirectoryArgs so that they do not derive from EventArgs
. The program will work exactly the same.
You could also change the SearchDirectoryArgs to a struct, if you also make one more change:
The additional change is to call the default constructor before entering the constructor that initializes all the fields.
Without that addition, the rules of C# would report that the properties are being accessed before they have been
assigned.
You should not change the FileFoundArgs from a class (reference type) to a struct (value type). That's because the
protocol for handling cancel requires that the event arguments are passed by reference. If you made the same
change, the file search class could never observe any changes made by any of the event subscribers. A new copy of
the structure would be used for each subscriber, and that copy would be a different copy than the one seen by the
file search object.
Next, let's consider how this change can be backwards compatible. The removal of the constraint does not affect
any existing code. Any existing event argument types do still derive from System.EventArgs . Backwards
compatibility is one major reason why they will continue to derive from System.EventArgs . Any existing event
subscribers will be subscribers to an event that followed the classic pattern.
Following similar logic, any event argument type created now would not have any subscribers in any existing
codebases. New event types that do not derive from System.EventArgs will not break those codebases.
You need to reconcile this opposing guidance. Somehow, you must create a safe async void method. The basics
of the pattern you need to implement are below:
First, notice that the handler is marked as an async handler. Because it is being assigned to an event handler
delegate type, it will have a void return type. That means you must follow the pattern shown in the handler, and
not allow any exceptions to be thrown out of the context of the async handler. Because it does not return a task,
there is no task that can report the error by entering the faulted state. Because the method is async, the method
can't simply throw the exception. (The calling method has continued execution because it is async .) The actual
runtime behavior will be defined differently for different environments. It may terminate the thread, it may
terminate the program, or it may leave the program in an undetermined state. None of those are good outcomes.
That's why you should wrap the await statement for the async Task in your own try block. If it does cause a faulted
task, you can log the error. If it is an error from which your application cannot recover, you can exit the program
quickly and gracefully
Those are the major updates to the .NET event pattern. You will see many examples of the earlier versions in the
libraries you work with. However, you should understand what the latest patterns are as well.
The next article in this series helps you distinguish between using delegates and events in your designs. They
are similar concepts, and that article will help you make the best decision for your programs.
Next
Distinguishing Delegates and Events
7/29/2017 • 2 min to read • Edit Online
Previous
Developers that are new to the .NET Core platform often struggle when deciding between a design based on
delegates and a design based on events . This is a difficult concept, because the two language features are very
similar. Events are even built using the language support for delegates.
They both offer a late binding scenario: they enable scenarios where a component communicates by calling a
method that is only known at runtime. They both support single and multiple subscriber methods. You may find
this referred to as singlecast and multicast support. They both support similar syntax for adding and removing
handlers. Finally, raising an event and calling a delegate use exactly the same method call syntax. They even both
support the same Invoke() method syntax for use with the ?. operator.
With all those similarities, it is easy to have trouble determining when to use which.
Language-Integrated Query (LINQ) is the name for a set of technologies based on the integration of query
capabilities directly into the C# language. Traditionally, queries against data are expressed as simple strings
without type checking at compile time or IntelliSense support. Furthermore, you have to learn a different query
language for each type of data source: SQL databases, XML documents, various Web services, and so on. With
LINQ, a query is a first-class language construct, just like classes, methods, events.
For a developer who writes queries, the most visible "language-integrated" part of LINQ is the query expression.
Query expressions are written in a declarative query syntax. By using query syntax, you can perform filtering,
ordering, and grouping operations on data sources with a minimum of code. You use the same basic query
expression patterns to query and transform data in SQL databases, ADO .NET Datasets, XML documents and
streams, and .NET collections.
The following example shows the complete query operation. The complete operation includes creating a data
source, defining the query expression, and executing the query in a foreach statement.
class LINQQueryExpressions
{
static void Main()
{
Next steps
To learn more details about LINQ, start by becoming familiar with some basic concepts in Query expression basics,
and then read the documentation for the LINQ technology in which you are interested:
XML documents: LINQ to XML
ADO.NET Entity Framework: LINQ to entities
.NET collections, files, strings and so on: LINQ to objects
To gain a deeper understanding of LINQ in general, see LINQ in C#.
To start working with LINQ in C#, see the tutorial Working with LINQ.
Asynchronous programming
8/29/2017 • 10 min to read • Edit Online
If you have any I/O-bound needs (such as requesting data from a network or accessing a database), you'll want to
utilize asynchronous programming. You could also have CPU-bound code, such as performing an expensive
calculation, which is also a good scenario for writing async code.
C# has a language-level asynchronous programming model which allows for easily writing asynchronous code
without having to juggle callbacks or conform to a library which supports asynchrony. It follows what is known as
the Task-based Asynchronous Pattern (TAP).
There are other ways to approach async code than async and await outlined in the TAP article linked above, but
this document will focus on the language-level constructs from this point forward.
I/O -Bound Example: Downloading data from a web service
You may need to download some data from a web service when a button is pressed, but don’t want to block the UI
thread. It can be accomplished simply like this:
And that’s it! The code expresses the intent (downloading some data asynchronously) without getting bogged
down in interacting with Task objects.
CPU -bound Example: Performing a Calculation for a Game
Say you're writing a mobile game where pressing a button can inflict damage on many enemies on the screen.
Performing the damage calculation can be expensive, and doing it on the UI thread would make the game appear
to pause as the calculation is performed!
The best way to handle this is to start a background thread which does the work using Task.Run , and await its
result. This will allow the UI to feel smooth as the work is being done.
private DamageResult CalculateDamageDone()
{
// Code omitted:
//
// Does an expensive calculation and returns
// the result of that calculation.
}
And that's it! This code cleanly expresses the intent of the button's click event, it doesn't require managing a
background thread manually, and it does so in a non-blocking way.
What happens under the covers
There's a lot of moving pieces where asynchronous operations are concerned. If you're curious about what's
happening underneath the covers of Task and Task<T> , checkout the Async in-depth article for more
information.
On the C# side of things, the compiler transforms your code into a state machine which keeps track of things like
yielding execution when an await is reached and resuming execution when a background job has finished.
For the theoretically-inclined, this is an implementation of the Promise Model of asynchrony.
More Examples
The following examples demonstrate various ways you can write async code in C#. They cover a few different
scenarios you may come across.
Extracting Data from a Network
This snippet downloads the HTML from www.dotnetfoundation.org and counts the number of times the string
".NET" occurs in the HTML. It uses ASP.NET MVC to define a web controller method which performs this task,
returning the number.
NOTE
If you plan on doing HTML parsing in production code, don't use regular expressions. Use a parsing library instead.
[HttpGet]
[Route("DotNetCount")]
public async Task<int> GetDotNetCountAsync()
{
// Suspends GetDotNetCountAsync() to allow the caller (the web server)
// to accept another request, rather than blocking on this one.
var html = await _httpClient.DownloadStringAsync("http://dotnetfoundation.org");
Here's the same scenario written for a Universal Windows App, which performs the same task when a Button is
pressed:
private readonly HttpClient _httpClient = new HttpClient();
// Any other work on the UI thread can be done here, such as enabling a Progress Bar.
// This is important to do here, before the "await" call, so that the user
// sees the progress bar before execution of this method is yielded.
NetworkProgressBar.IsEnabled = true;
NetworkProgressBar.Visibility = Visibility.Visible;
NetworkProgressBar.IsEnabled = false;
NetworkProgressBar.Visbility = Visibility.Collapsed;
}
Here's another way to write this a bit more succinctly, using LINQ:
public async Task<User> GetUser(int userId)
{
// Code omitted:
//
// Given a user Id {userId}, retrieves a User object corresponding
// to the entry in the database with {userId} as its Id.
}
Although it's less code, take care when mixing LINQ with asynchronous code. Because LINQ uses deferred (lazy)
execution, async calls won't happen immediately as they do in a foreach() loop unless you force the generated
sequence to iterate with a call to .ToList() or .ToArray() .
This is important to keep in mind. If await is not used in the body of an async method, the C# compiler will
generate a warning, but the code will compile and run as if it were a normal method. Note that this would also be
incredibly inefficient, as the state machine generated by the C# compiler for the async method would not be
accomplishing anything.
You should add "Async" as the suffix of every async method name you write.
This is the convention used in .NET to more-easily differentiate synchronous and asynchronous methods. Note that
certain methods which aren’t explicitly called by your code (such as event handlers or web controller methods)
don’t necessarily apply. Because these are not explicitly called by your code, being explicit about their naming isn’t
as important.
async void should only be used for event handlers.
async void is the only way to allow asynchronous event handlers to work because events do not have return
types (thus cannot make use of Task and Task<T> ). Any other use of async void does not follow the TAP model
and can be challenging to use, such as:
Exceptions thrown in an async void method can’t be caught outside of that method.
async void methods are very difficult to test.
async void methods can cause bad side effects if the caller isn’t expecting them to be async.
Other Resources
Async in-depth provides more information about how Tasks work.
Lucian Wischik's Six Essential Tips for Async are a wonderful resource for async programming
Pattern Matching
7/29/2017 • 11 min to read • Edit Online
Patterns test that a value has a certain shape, and can extract information from the value when it has the matching
shape. Pattern matching provides more concise syntax for algorithms you already use today. You already create
pattern matching algorithms using existing syntax. You write if or switch statements that test values. Then,
when those statements match, you extract and use information from that value. The new syntax elements are
extensions to statements you are already familiar with: is and switch . These new extensions combine testing a
value and extracting that information.
In this topic, we'll look at the new syntax to show you how it enables readable, concise code. Pattern matching
enables idioms where data and the code are separated, unlike object oriented designs where data and the methods
that manipulate them are tightly coupled.
To illustrate these new idioms, let's work with structures that represent geometric shapes using pattern matching
statements. You are probably familiar with building class hierarchies and creating virtual methods and overridden
methods to customize object behavior based on the runtime type of the object.
Those techniques aren't possible for data that isn't structured in a class hierarchy. When data and methods are
separate, you need other tools. The new pattern matching constructs enable cleaner syntax to examine data and
manipulate control flow based on any condition of that data. You already write if statements and switch that
test a variable's value. You write is statements that test a variable's type. Pattern matching adds new capabilities
to those statements.
In this topic, you'll build a method that computes the area of different geometric shapes. But, you'll do it without
resorting to object oriented techniques and building a class hierarchy for the different shapes. You'll use pattern
matching instead. To further emphasize that we're not using inheritance, you'll make each shape a struct instead
of a class. Note that different struct types cannot specify a common user defined base type, so inheritance is not
a possible design. As you go through this sample, contrast this code with how it would be structured as an object
hierarchy. When the data you must query and manipulate is not a class hierarchy, pattern matching enables very
elegant designs.
Rather than starting with an abstract shape definition and adding different specific shape classes, let's start instead
with simple data only definitions for each of the geometric shapes:
public class Square
{
public double Side { get; }
From these structures, let's write a method that computes the area of some shape.
That code above is a classic expression of the type pattern: You're testing a variable to determine its type and
taking a different action based on that type.
This code becomes simpler using extensions to the is expression to assign a variable if the test succeeds:
In this updated version, the is expression both tests the variable and assigns it to a new variable of the proper
type. Also, notice that this version includes the Rectangle type, which is a struct . The new is expression works
with value types as well as reference types.
Language rules for pattern matching expressions help you avoid misusing the results of a match expression. In the
example above, the variables s , c , and r are only in scope and definitely assigned when the respective pattern
match expressions have true results. If you try to use either variable in another location, your code generates
compiler errors.
Let's examine both of those rules in detail, beginning with scope. The variable c is in scope only in the else
branch of the first if statement. The variable s is in scope in the method ComputeArea . That's because each
branch of an if statement establishes a separate scope for variables. However, the if statement itself does not.
That means variables declared in the if statement are in the same scope as the if statement (the method in this
case.) This behavior is not specific to pattern matching, but is the defined behavior for variable scopes and if and
else statements.
The variables c and s are assigned when the respective if statements are true because of the definitely
assigned when true mechanism.
TIP
The samples in this topic use the recommended construct where a pattern match is expression definitely assigns the
match variable in the true branch of the if statement. You could reverse the logic by saying
if (!(shape is Square s)) and the variable s would be definitely assigned only in the false branch. While this is
valid C#, it is not recommended because it is more confusing to follow the logic.
These rules mean that you are unlikely to accidentally access the result of a pattern match expression when that
pattern was not met.
The only pattern supported by the switch statement was the constant pattern. It was further limited to numeric
types and the string type. Those restrictions have been removed, and you can now write a switch statement
using the type pattern:
The pattern matching switch statement uses familiar syntax to developers who have used the traditional C-style
switch statement. Each case is evaluated and the code beneath the condition that matches the input variable is
executed. Code execution cannot "fall through" from one case expression to the next; the syntax of the case
statement requires that each case end with a break , return , or goto .
NOTE
The goto statements to jump to another label are valid only for the constant pattern, the classic switch statement.
There are important new rules governing the switch statement. The restrictions on the type of the variable in the
switch expression have been removed. Any type, such as object in this example, may be used. The case
expressions are no longer limited to constant values. Removing that limitation means that reordering switch
sections may change a program's behavior.
When limited to constant values, no more than one case label could match the value of the switch expression.
Combine that with the rule that every switch section must not fall through to the next section, and it followed that
the switch sections could be rearranged in any order without affecting behavior. Now, with more generalized
switch expressions, the order of each section matters. The switch expressions are evaluated in textual order.
Execution transfers to the first switch label that matches the switch expression.
Note that the default case will only be executed if no other case labels match. The default case is evaluated last,
regardless of its textual order. If there is no default case, and none of the other case statements match, execution
continues at the statement following the switch statement. None of the case labels code is executed.
case Square s:
return s.Side * s.Side;
case Circle c:
return c.Radius * c.Radius * Math.PI;
default:
throw new ArgumentException(
message: "shape is not a recognized shape",
paramName: nameof(shape));
}
}
This change demonstrates a few important points about the new syntax. First, multiple case labels can be applied
to one switch section. The statement block is executed when any of those labels is true . In this instance, if the
switch expression is either a circle or a square with 0 area, the method returns the constant 0.
This example introduces two different variables in the two case labels for the first switch block. Notice that the
statements in this switch block do not use either the variables c (for the circle) or s (for the square). Neither of
those variables is definitely assigned in this switch block. If either of these cases match, clearly one of the
variables has been assigned. However, it is impossible to tell which has been assigned at compile-time, because
either case could match at runtime. For that reason, most times when you use multiple case labels for the same
block, you won't introduce a new variable in the case statement, or you will only use the variable in the when
clause.
Having added those shapes with 0 area, let's add a couple more shape types: a rectangle and a triangle:
case Square s:
return s.Side * s.Side;
case Circle c:
return c.Radius * c.Radius * Math.PI;
case Triangle t:
return t.Base * t.Height * 2;
case Rectangle r:
return r.Length * r.Height;
default:
throw new ArgumentException(
message: "shape is not a recognized shape",
paramName: nameof(shape));
}
}
This set of changes adds case labels for the degenerate case, and labels and blocks for each of the new shapes.
Finally, you can add a null case to ensure the argument is not null :
case Square s:
return s.Side * s.Side;
case Circle c:
return c.Radius * c.Radius * Math.PI;
case Triangle t:
return t.Base * t.Height * 2;
case Rectangle r:
return r.Length * r.Height;
case null:
throw new ArgumentNullException(paramName: nameof(shape), message: "Shape must not be null");
default:
throw new ArgumentException(
message: "shape is not a recognized shape",
paramName: nameof(shape));
}
}
The special behavior for the null pattern is interesting because the constant null in the pattern does not have a
type but can be converted to any reference type or nullable type. Rather than convert a null to any type, the
language defines that a null value will not match any type pattern, regardless of the compile-time type of the
variable. This behavior makes the new switch based type pattern consistent with the is statement: is
statements always return false when the value being checked is null . It's also simpler: once you have checked
the type, you don't need an additional null check. You can see that from the fact that there are no null checks in any
of the case blocks of the samples above: they are not necessary, since matching the type pattern guarantees a non-
null value.
Conclusions
Pattern Matching constructs enable you to easily manage control flow among different variables and types that are
not related by an inheritance hierarchy. You can also control logic to use any condition you test on the variable. It
enables patterns and idioms that you'll need more often as you build more distributed applications, where data
and the methods that manipulate that data are separate. You'll notice that the shape structs used in this sample do
not contain any methods, just read-only properties. Pattern Matching works with any data type. You write
expressions that examine the object, and make control flow decisions based on those conditions.
Compare the code from this sample with the design that would follow from creating a class hierarchy for an
abstract Shape and specific derived shapes each with their own implementation of a virtual method to calculate
the area. You'll often find that pattern matching expressions can be a very useful tool when you are working with
data and want to separate the data storage concerns from the behavior concerns.
Expression Trees
7/29/2017 • 2 min to read • Edit Online
If you have used LINQ, you have experience with a rich library where the Func types are part of the API set. (If you
are not familiar with LINQ, you probably want to read the LINQ tutorial and the tutorial on lambda expressions
before this one.) Expression Trees provide richer interaction with the arguments that are functions.
You write function arguments, typically using Lambda Expressions, when you create LINQ queries. In a typical
LINQ query, those function arguments are transformed into a delegate the compiler creates.
When you want to have a richer interaction, you need to use Expression Trees. Expression Trees represent code as
a structure that you can examine, modify, or execute. These tools give you the power to manipulate code during
run time. You can write code that examines running algorithms, or injects new capabilities. In more advanced
scenarios, you can modify running algorithms, and even translate C# expressions into another form for execution
in another environment.
You've likely already written code that uses Expression Trees. Entity Framework's LINQ APIs accept Expression
Trees as the arguments for the LINQ Query Expression Pattern. That enables Entity Framework to translate the
query you wrote in C# into SQL that executes in the database engine. Another example is Moq, which is a popular
mocking framework for .NET.
The remaining sections of this tutorial will explore what Expression Trees are, examine the framework classes that
support expression trees, and show you how to work with expression trees. You'll learn how to read expression
trees, how to create expression trees, how to create modified expression trees, and how to execute the code
represented by expression trees. After reading, you will be ready to use these structures to create rich adaptive
algorithms.
1. Expression Trees Explained
Understand the structure and concepts behind Expression Trees.
2. Framework Types Supporting Expression Trees
Learn about the structures and classes that define and manipulate expression trees.
3. Executing Expressions
Learn how to convert an expression tree represented as a Lambda Expression into a delegate and execute
the resulting delegate.
4. Interpreting Expressions
Learn how to traverse and examine expression trees to understand what code the expression tree
represents.
5. Building Expressions
Learn how to construct the nodes for an expression tree and build expression trees.
6. Translating Expressions
Learn how to build a modified copy of an expression tree, or translate an expression tree into a different
format.
7. Summing up
Review the information on expression trees.
Expression Trees Explained
7/29/2017 • 4 min to read • Edit Online
Previous -- Overview
An Expression Tree is a data structure that defines code. They are based on the same structures that a compiler uses
to analyze code and generate the compiled output. As you read through this tutorial, you will notice quite a bit of
similarity between Expression Trees and the types used in the Roslyn APIs to build Analyzers and CodeFixes.
(Analyzers and CodeFixes are NuGet packages that perform static analysis on code and can suggest potential fixes
for a developer.) The concepts are similar, and the end result is a data structure that allows examination of the
source code in a meaningful way. However, Expression Trees are based on a totally different set of classes and APIs
than the Roslyn APIs.
Let's look at a simple example. Here's a line of code:
var sum = 1 + 2;
If you were to analyze this as an expression tree, the tree contains several nodes. The outermost node is a variable
declaration statement with assignment ( var sum = 1 + 2; ) That outermost node contains several child nodes: a
variable declaration, an assignment operator, and an expression representing the right hand side of the equals sign.
That expression is further subdivided into expressions that represent the addition operation, and left and right
operands of the addition.
Let's drill down a bit more into the expressions that make up the right side of the equals sign. The expression is
1 + 2 . That's a binary expression. More specifically, it's a binary addition expression. A binary addition expression
has two children, representing the left and right nodes of the addition expression. Here, both nodes are constant
expressions: The left operand is the value 1 , and the right operand is the value 2 .
Visually, the entire statement is a tree: You could start at the root node, and travel to each node in the tree to see
the code that makes up the statement:
Variable declaration statement with assignment ( var sum = 1 + 2; )
Implicit variable type declaration ( var sum )
Implicit var keyword ( var )
Variable name declaration ( sum )
Assignment operator ( = )
Binary addition expression ( 1 + 2 )
Left operand ( 1 )
Addition operator ( + )
Right operand ( 2 )
This may look complicated, but it is very powerful. Following the same process, you can decompose much more
complicated expressions. Consider this expression:
if (addFive.NodeType == ExpressionType.Lambda)
{
var lambdaExp = (LambdaExpression)addFive;
Console.WriteLine(parameter.Name);
Console.WriteLine(parameter.Type);
}
Optionally, you can also provide a DebugInfoGenerator that will receive the symbol debugging information for the
generated delegate object. This enables you to convert the expression tree into a delegate object, and have full
debugging information about the generated delegate.
You would convert an expression into a delegate using the following code:
Notice that the delegate type is based on the expression type. You must know the return type and the argument list
if you want to use the delegate object in a strongly typed manner. The LambdaExpression.Compile() method returns
the Delegate type. You will have to cast it to the correct delegate type to have any compile-time tools check the
argument list of return type.
Caveats
Compiling a lambda expression to a delegate and invoking that delegate is one of the simplest operations you can
perform with an expression tree. However, even with this simple operation, there are caveats you must be aware
of.
Lambda Expressions create closures over any local variables that are referenced in the expression. You must
guarantee that any variables that would be part of the delegate are usable at the location where you call Compile ,
and when you execute the resulting delegate.
In general, the compiler will ensure that this is true. However, if your expression accesses a variable that
implements IDisposable , it's possible that your code might dispose of the object while it is still held by the
expression tree.
For example, this code works fine, because int does not implement IDisposable :
The delegate has captured a reference to the local variable constant . That variable is accessed at any time later,
when the function returned by CreateBoundFunc executes.
However, consider this (rather contrived) class that implements IDisposable :
The delegate returned from this method has closed over the constant object, which has been disposed of. (It's
been disposed, because it was declared in a using statement.)
Now, when you execute the delegate returned from this method, you'll have a ObjecctDisposedException thrown at
the point of execution.
It does seem strange to have a runtime error representing a compile-time construct, but that's the world we enter
when we work with expression trees.
There are a lot of permutations of this problem, so it's hard to offer general guidance to avoid it. Be careful about
accessing local variables when defining expressions, and be careful about accessing state in the current object
(represented by this ) when creating an expression tree that can be returned by a public API.
The code in your expression may reference methods or properties in other assemblies. That assembly must be
accessible when the expression is defined, and when it is compiled, and when the resulting delegate is invoked.
You'll be met with a ReferencedAssemblyNotFoundException in cases where it is not present.
Summary
Expression Trees that represent lambda expressions can be compiled to create a delegate that you can execute. This
provides one mechanism to execute the code represented by an expression tree.
The Expression Tree does represent the code that would execute for any given construct you create. As long as the
environment where you compile and execute the code matches the environment where you create the expression,
everything works as expected. When that doesn't happen, the errors are very predictable, and they will be caught in
your first tests of any code using the expression trees.
Next -- Interpreting Expressions
Interpreting Expressions
7/29/2017 • 14 min to read • Edit Online
Now, let's write the code that would examine this expression and write out some important properties about it.
Here's that code:
I'm not using var to declare this expression tree, as it is not possible because the right-hand side of the
assignment is implicitly typed. To understand this more deeply, read here.
The root node is a LambdaExpression . In order to get the interesting code on the right hand side of the =>
operator, you need to find one of the children of the LambdaExpression . We'll do that with all the expressions in this
section. The parent node does help us find the return type of the LambdaExpression .
To examine each node in this expression, we'll need to recursively visit a number of nodes. Here's a simple first
implementation:
Expression<Func<int, int, int>> addition = (a, b) => a + b;
You'll notice a lot of repetition in the code sample above. Let's clean that up and build a more general purpose
expression node visitor. That's going to require us to write a recursive algorithm. Any node could be of a type that
might have children. Any node that has children requires us to visit those children and determine what that node is.
Here's the cleaned up version that utilizes recursion to visit the addition operations:
// Lambda Visitor
public class LambdaVisitor : Visitor
{
private readonly LambdaExpression node;
public LambdaVisitor(LambdaExpression node) : base(node)
{
this.node = node;
}
// Parameter visitor:
public class ParameterVisitor : Visitor
{
private readonly ParameterExpression node;
public ParameterVisitor(ParameterExpression node) : base(node)
{
this.node = node;
}
// Constant visitor:
public class ConstantVisitor : Visitor
{
private readonly ConstantExpression node;
public ConstantVisitor(ConstantExpression node) : base(node)
{
this.node = node;
}
This algorithm is the basis of an algorithm that can visit any arbitrary LambdaExpression . There are a lot of holes,
namely that the code I created only looks for a very small sample of the possible sets of expression tree nodes that
it may encounter. However, you can still learn quite a bit from what it produces. (The default case in the
Visitor.CreateFromExpression method prints a message to the error console when a new node type is
encountered. That way, you know to add a new expression type.)
When you run this visitor on the addition expression shown above, you get the following output:
Now that you've built a more general visitor implementation, you can visit and process many more different types
of expressions.
Before you run this on the visitor algorithm, try a thought exercise to work out what the output might be.
Remember that the + operator is a binary operator: it must have two children, representing the left and right
operands. There are several possible ways to construct a tree that could be correct:
Expression<Func<int>> sum1 = () => 1 + (2 + (3 + 4));
Expression<Func<int>> sum2 = () => ((1 + 2) + 3) + 4;
You can see the separation into two possible answers to highlight the most promising. The first represents right
associative expressions. The second represent left associative expressions. The advantage of both of those two
formats is that the format scales to any arbitrary number of addition expressions.
If you do run this expression through the visitor, you will see this this output, verifying that the simple addition
expression is left associative.
In order to run this sample, and see the full expression tree, I had to make one change to the source expression
tree. When the expression tree contains all constants, the resulting tree simply contains the constant value of 10 .
The compiler performs all the addition and reduces the expression to its simplest form. Simply adding one variable
in the expression is sufficient to see the original tree:
Create a visitor for this sum and run the visitor you'll see this output:
You can also run any of the other samples through the visitor code and see what tree it represents. Here's an
example of the sum3 expression above (with an additional parameter to prevent the compiler from computing the
constant):
Notice that the parentheses are not part of the output. There are no nodes in the expression tree that represent the
parentheses in the input expression. The structure of the expression tree contains all the information necessary to
communicate the precedence.
This code represents one possible implementation for the mathematical factorial function. The way I've written this
code highlights two limitiations of building expression trees by assigning lambda expressions to Expressions. First,
statement lambdas are not allowed. That means I can't use loops, blocks, if / else statements, and other control
structures common in C#. I'm limited to using expressions. Second, I can't recursively call the same expression. I
could if it were already a delegate, but I can't call it in its expression tree form. In the section on building expression
trees you'll learn techniques to overcome these limitations.
In this expression, you'll encounter nodes of all these types:
1. Equal (binary expression)
2. Multiply (binary expression)
3. Conditional (the ? : expression)
4. Method Call Expression (calling Range() and Aggregate() )
One way to modify the visitor algorithm is to keep executing it, and write the node type every time you reach your
default clause. After a few iterations, you'll have seen each of the potential nodes. Then, you have all you need.
The result would be something like this:
Creating Nodes
Let's start relatively simply again. We'll use the addition expression I've been working with throughout these
sections:
To construct that expression tree, you must construct the leaf nodes. The leaf nodes are constants, so you can use
the Expression.Constant method to create the nodes:
Once you've got the addition expression, you can create the lambda expression:
This is a very simple LambdaExpression, because it contains no arguments. Later in this section, you'll see how to
map arguments to parameters and build more complicated expressions.
For expressions that are as simple as this one, you may combine all the calls into a single statement:
Creating the multiplication and addition expressions follows the pattern you've already seen:
Next, you need to create a method call expression for the call to Math.Sqrt .
And then finally, you put the method call into a lambda expression, and make sure to define the arguments to the
lambda expression:
In this more complicated example, you see a couple more techniques that you will often need to create expression
trees.
First, you need to create the objects that represent parameters or local variables before you use them. Once you've
created those objects, you can use them in your expression tree wherever you need.
Second, you need to use a subset of the Reflection APIs to create a MethodInfo object so that you can create an
expression tree to access that method. You must limit yourself to the subset of the Reflection APIs that are
available on the .NET Core platform. Again, these techniques will extend to other expression trees.
Notice above that I did not build the expression tree, but simply the delegate. Using the Expression class, you
can't build statement lambdas. Here's the code that is required to build the same functionality. It's complicated by
the fact that there isn't an API to build a while loop, instead you need to build a loop that contains a conditional
test, and a label target to break out of the loop.
The code to build the expression tree for the factorial function is quite a bit longer, more complicated, and it's
riddled with labels and break statements and other elements we'd like to avoid in our everyday coding tasks.
For this section, I've also updated the visitor code to visit every node in this expression tree and write out
information about the nodes that are created in this sample. You can view or download the sample code at the
dotnet/docs GitHub repository. Experiment for yourself by building and running the samples. For download
instructions, see Samples and Tutorials.
Translating is Visiting
The code you build to translate an expression tree is an extension of what you've already seen to visit all the nodes
in a tree. When you translate an expression tree, you visit all the nodes, and while visiting them, build the new tree.
The new tree may contain references to the original nodes, or new nodes that you have placed in the tree.
Let's see this in action by visiting an expression tree, and creating a new tree with some replacement nodes. In this
example, let's replace any constant with a constant that is ten times larger. Otherwise, we'll leave the expression
tree intact. Rather than reading the value of the constant, and replacing it with a new constant, we'll make this
replacement by replacing the constant node with a new node that performs the multiplication.
Here, once you find a constant node, you create a new multiplication node whose children are the original constant,
and the constant 10 :
By replacing the original node with the substitute, a new tree is formed that contains our modifications. We can
verify that by compiling and executing the replaced tree.
There's quite a bit of code here, but the concepts are very approachable. This code visits children in a depth first
search. When it encounters a constant node, the visitor returns the value of the constant. After the visitor has
visited both children, those children will have computed the sum computed for that sub-tree. The addition node
can now compute its sum. Once all the nodes in the expression tree have been visited, the sum will have been
computed. You can trace the execution by running the sample in the debugger and tracing the execution.
Let's make it easier to trace how the nodes are analyzed and how the sum is computed by travsersing the tree.
Here's an updated version of the Aggregate method that includes quite a bit of tracing information:
private static int Aggregate(Expression exp)
{
if (exp.NodeType == ExpressionType.Constant)
{
var constantExp = (ConstantExpression)exp;
Console.Error.WriteLine($"Found Constant: {constantExp.Value}");
return (int)constantExp.Value;
}
else if (exp.NodeType == ExpressionType.Add)
{
var addExp = (BinaryExpression)exp;
Console.Error.WriteLine("Found Addition Expression");
Console.Error.WriteLine("Computing Left node");
var leftOperand = Aggregate(addExp.Left);
Console.Error.WriteLine($"Left is: {leftOperand}");
Console.Error.WriteLine("Computing Right node");
var rightOperand = Aggregate(addExp.Right);
Console.Error.WriteLine($"Right is: {rightOperand}");
var sum = leftOperand + rightOperand;
Console.Error.WriteLine($"Computed sum: {sum}");
return sum;
}
else throw new NotSupportedException("Haven't written this yet");
}
10
Found Addition Expression
Computing Left node
Found Addition Expression
Computing Left node
Found Constant: 1
Left is: 1
Computing Right node
Found Constant: 2
Right is: 2
Computed sum: 3
Left is: 3
Computing Right node
Found Addition Expression
Computing Left node
Found Constant: 3
Left is: 3
Computing Right node
Found Constant: 4
Right is: 4
Computed sum: 7
Right is: 7
Computed sum: 10
10
Trace the output and follow along in the code above. You should be able to work out how the code visits each node
and computes the sum as it goes through the tree and finds the sum.
Now, let's look at a different run, with the expression given by sum1 :
While the final answer is the same, the tree traversal is completely different. The nodes are traveled in a different
order, because the tree was constructed with different operations occurring first.
Learning More
This sample shows a small subset of the code you would build to traverse and interpret the algorithms represented
by an expression tree. For a complete discussion of all the work necessary to build a general purpose library that
translates expression trees into another language, please read this series by Matt Warren. It goes into great detail
on how to translate any of the code you might find in an expression tree.
I hope you've now seen the true power of expression trees. You can examine a set of code, make any changes
you'd like to that code, and execute the changed version. Because the expression trees are immutable, you can
create new trees by using the components of existing trees. This minimizes the amount of memory needed to
create modified expression trees.
Next -- Summing up
Expression Trees Summary
7/29/2017 • 1 min to read • Edit Online
Limitations
There are some newer C# language elements that don't translate well into expression trees. Expression trees
cannot contain await expressions, or async lambda expressions. Many of the features added in the C# 6 release
don't appear exactly as written in expression trees. Instead, newer features will be exposed in expressions trees in
the equivalent, earlier syntax. This may not be as much of a limitation as you might think. In fact, it means that your
code that interprets expression trees will likely still work the same when new language features are introduced.
Even with these limitations, expression trees do enable you to create dynamic algorithms that rely on interpreting
and modifying code that is represetned as a data structure. It's a powerful tool, and it's one of the features of the
.NET ecosystem that enables rich libraries such as Entity Framework to accomplish what they do.
Interoperability (C# Programming Guide)
7/29/2017 • 1 min to read • Edit Online
Interoperability enables you to preserve and take advantage of existing investments in unmanaged code. Code that
runs under the control of the common language runtime (CLR) is called managed code, and code that runs outside
the CLR is called unmanaged code. COM, COM+, C++ components, ActiveX components, and Microsoft Win32 API
are examples of unmanaged code.
The .NET Framework enables interoperability with unmanaged code through platform invoke services, the
System.Runtime.InteropServices namespace, C++ interoperability, and COM interoperability (COM interop).
In This Section
Interoperability Overview
Describes methods to interoperate between C# managed code and unmanaged code.
How to: Access Office Interop Objects by Using Visual C# Features
Describes features that are introduced in Visual C# to facilitate Office programming.
How to: Use Indexed Properties in COM Interop Programming
Describes how to use indexed properties to access COM properties that have parameters.
How to: Use Platform Invoke to Play a Wave File
Describes how to use platform invoke services to play a .wav sound file on the Windows operating system.
Walkthrough: Office Programming
Shows how to create an Excel workbook and a Word document that contains a link to the workbook.
Example COM Class
Demonstrates how to expose a C# class as a COM object.
C# Language Specification
For more information, see the C# Language Specification. The language specification is the definitive source for C#
syntax and usage.
See Also
System.Runtime.InteropServices.Marshal.ReleaseComObject
C# Programming Guide
Interoperating with Unmanaged Code
Walkthrough: Office Programming
Documenting your code with XML comments
7/29/2017 • 28 min to read • Edit Online
XML documentation comments are a special kind of comment, added above the definition of any user-defined type
or member. They are special because they can be processed by the compiler to generate an XML documentation file
at compile time. The compiler generated XML file can be distributed alongside your .NET assembly so that Visual
Studio and other IDEs can use IntelliSense to show quick information about types or members. Additionally, the
XML file can be run through tools like DocFX and Sandcastle to generate API reference websites.
XML documentation comments, like all other comments, are ignored by the compiler.
You can generate the XML file at compile time by doing one of the following:
If you are developing an application with .NET Core from the command line, you can add a
DocumentationFile element to the <PropertyGroup> section of your .csproj project file. The following
example generates an XML file in the project directory with the same root filename as the project:
<DocumentationFile>$(MSBuildProjectName).xml</DocumentationFile>
You can also specify the exact absolute or relative path and name of the XML file. The following example
generates the XML file in the same directory as the debug version of an application:
<DocumentationFile>bin\Debug\netcoreapp1.0\App.xml</DocumentationFile>
If you are developing an application using Visual Studio, right-click on the project and select Properties. In
the properties dialog, select the Build tab, and check XML documentation file. You can also change the
location to which the compiler writes the file.
If you are compiling a .NET Framework application from the command line, add the /doc compiler option
when compiling.
XML documentation comments use triple forward slashes ( /// ) and an XML formatted comment body. For
example:
/// <summary>
/// This class does something.
/// </summary>
public class SomeClass
{
Walkthrough
Let's walk through documenting a very basic math library to make it easy for new developers to
understand/contribute and for third party developers to use.
Here's code for the simple math library:
/*
The main Math class
Contains all methods for performing basic math functions
*/
public class Math
{
// Adds two integers and returns the result
public static int Add(int a, int b)
{
// If any parameter is equal to the max value of an integer
// and the other is greater than zero
if ((a == int.MaxValue && b > 0) || (b == int.MaxValue && a > 0))
throw new System.OverflowException();
return a + b;
}
return a + b;
}
The sample library supports four major arithmetic operations add , subtract , multiply and divide on int and
double data types.
Now you want to be able to create an API reference document from your code for third party developers who use
your library but don't have access to the source code. As mentioned earlier XML documentation tags can be used to
achieve this, You will now be introduced to the standard XML tags the C# compiler supports.
<summary>
The <summary> tag adds brief information about a type or member. I'll demonstrate its use by adding it to the
Math class definition and the first Add method. Feel free to apply it to the rest of your code.
/*
The main Math class
Contains all methods for performing basic math functions
*/
/// <summary>
/// The main Math class.
/// Contains all methods for performing basic math functions.
/// </summary>
public class Math
{
// Adds two integers and returns the result
/// <summary>
/// Adds two integers and returns the result.
/// </summary>
public static int Add(int a, int b)
{
// If any parameter is equal to the max value of an integer
// and the other is greater than zero
if ((a == int.MaxValue && b > 0) || (b == int.MaxValue && a > 0))
throw new System.OverflowException();
return a + b;
}
}
The <summary> tag is very important, and we recommend that you include it because its content is the primary
source of type or member information in IntelliSense or an API reference document.
<remarks>
The <remarks> tag supplements the information about types or members that the <summary> tag provides. In this
example, you'll just add it to the class.
/*
The main Math class
Contains all methods for performing basic math functions
*/
/// <summary>
/// The main Math class.
/// Contains all methods for performing basic math functions.
/// </summary>
/// <remarks>
/// This class can add, subtract, multiply and divide.
/// </remarks>
public class Math
{
<returns>
The <returns> tag describes the return value of a method declaration. As before, the following example illustrates
the <returns> tag on the first Add method. You can do the same on other methods.
// Adds two integers and returns the result
/// <summary>
/// Adds two integers and returns the result.
/// </summary>
/// <returns>
/// The sum of two integers.
/// </returns>
public static int Add(int a, int b)
{
// If any parameter is equal to the max value of an integer
// and the other is greater than zero
if ((a == int.MaxValue && b > 0) || (b == int.MaxValue && a > 0))
throw new System.OverflowException();
return a + b;
}
<value>
The <value> tag is similar to the <returns> tag, except that you use it for properties. Assuming your Math library
had a static property called PI , here's how you'd use this tag:
/*
The main Math class
Contains all methods for performing basic math functions
*/
/// <summary>
/// The main Math class.
/// Contains all methods for performing basic math functions.
/// </summary>
/// <remarks>
/// This class can add, subtract, multiply and divide.
/// These operations can be performed on both integers and doubles
/// </remarks>
public class Math
{
/// <value>Gets the value of PI.</value>
public static double PI { get; }
}
<example>
You use the <example> tag to include an example in your XML documentation. This involves using the child <code>
tag.
// Adds two integers and returns the result
/// <summary>
/// Adds two integers and returns the result.
/// </summary>
/// <returns>
/// The sum of two integers.
/// </returns>
/// <example>
/// <code>
/// int c = Math.Add(4, 5);
/// if (c > 10)
/// {
/// Console.WriteLine(c);
/// }
/// </code>
/// </example>
public static int Add(int a, int b)
{
// If any parameter is equal to the max value of an integer
// and the other is greater than zero
if ((a == int.MaxValue && b > 0) || (b == int.MaxValue && a > 0))
throw new System.OverflowException();
return a + b;
}
The code tag preserves line breaks and indentation for longer examples.
<para>
You use the <para> tag to format the content within its parent tag. <para> is usually used inside a tag, such as
<remarks> or <returns> , to divide text into paragraphs. You can format the contents of the <remarks> tag for your
class definition.
/*
The main Math class
Contains all methods for performing basic math functions
*/
/// <summary>
/// The main Math class.
/// Contains all methods for performing basic math functions.
/// </summary>
/// <remarks>
/// <para>This class can add, subtract, multiply and divide.</para>
/// <para>These operations can be performed on both integers and doubles.</para>
/// </remarks>
public class Math
{
<c>
Still on the topic of formatting, you use the <c> tag for marking part of text as code. It's like the <code> tag but
inline. It's useful when you want to show a quick code example as part of a tag's content. Let's update the
documentation for the Math class.
/*
The main Math class
Contains all methods for performing basic math functions
*/
/// <summary>
/// The main <c>Math</c> class.
/// Contains all methods for performing basic math functions.
/// </summary>
public class Math
{
<exception>
By using the <exception> tag, you let your developers know that a method can throw specific exceptions. Looking
at your Math library, you can see that both Add methods throw an exception if a certain condition is met. Not so
obvious, though, is that integer Divide method throws as well if the b parameter is zero. Now add exception
documentation to this method.
/*
The main Math class
Contains all methods for performing basic math functions
*/
/// <summary>
/// The main <c>Math</c> class.
/// Contains all methods for performing basic math functions.
/// </summary>
public class Math
{
/// <summary>
/// Adds two integers and returns the result.
/// </summary>
/// <returns>
/// The sum of two integers.
/// </returns>
/// <example>
/// <code>
/// int c = Math.Add(4, 5);
/// if (c > 10)
/// {
/// Console.WriteLine(c);
/// }
/// </code>
/// </example>
/// <exception cref="System.OverflowException">Thrown when one parameter is max
/// and the other is greater than 0.</exception>
public static int Add(int a, int b)
{
if ((a == int.MaxValue && b > 0) || (b == int.MaxValue && a > 0))
throw new System.OverflowException();
return a + b;
}
/// <summary>
/// Adds two doubles and returns the result.
/// </summary>
/// <returns>
/// The sum of two doubles.
/// </returns>
/// <exception cref="System.OverflowException">Thrown when one parameter is max
/// and the other is greater than zero.</exception>
public static double Add(double a, double b)
{
if ((a == double.MaxValue && b > 0) || (b == double.MaxValue && a > 0))
if ((a == double.MaxValue && b > 0) || (b == double.MaxValue && a > 0))
throw new System.OverflowException();
return a + b;
}
/// <summary>
/// Divides an integer by another and returns the result.
/// </summary>
/// <returns>
/// The division of two integers.
/// </returns>
/// <exception cref="System.DivideByZeroException">Thrown when a division by zero occurs.</exception>
public static int Divide(int a, int b)
{
return a / b;
}
/// <summary>
/// Divides a double by another and returns the result.
/// </summary>
/// <returns>
/// The division of two doubles.
/// </returns>
/// <exception cref="System.DivideByZeroException">Thrown when a division by zero occurs.</exception>
public static double Divide(double a, double b)
{
return a / b;
}
}
The cref attribute represents a reference to an exception that is available from the current compilation
environment. This can be any type defined in the project or a referenced assembly. The compiler will issue a
warning if its value cannot be resolved.
<see>
The <see> tag lets you create a clickable link to a documentation page for another code element. In our next
example, we'll create a clickable link between the two Add methods.
/*
The main Math class
Contains all methods for performing basic math functions
*/
/// <summary>
/// The main <c>Math</c> class.
/// Contains all methods for performing basic math functions.
/// </summary>
public class Math
{
/// <summary>
/// Adds two integers and returns the result.
/// </summary>
/// <returns>
/// The sum of two integers.
/// </returns>
/// <example>
/// <code>
/// int c = Math.Add(4, 5);
/// if (c > 10)
/// {
/// Console.WriteLine(c);
/// }
/// </code>
/// </example>
/// <exception cref="System.OverflowException">Thrown when one parameter is max
/// and the other is greater than 0.</exception>
/// See <see cref="Math.Add(double, double)"/> to add doubles.
public static int Add(int a, int b)
{
if ((a == int.MaxValue && b > 0) || (b == int.MaxValue && a > 0))
throw new System.OverflowException();
return a + b;
}
/// <summary>
/// Adds two doubles and returns the result.
/// </summary>
/// <returns>
/// The sum of two doubles.
/// </returns>
/// <exception cref="System.OverflowException">Thrown when one parameter is max
/// and the other is greater than zero.</exception>
/// See <see cref="Math.Add(int, int)"/> to add integers.
public static double Add(double a, double b)
{
if ((a == double.MaxValue && b > 0) || (b == double.MaxValue && a > 0))
throw new System.OverflowException();
return a + b;
}
}
The cref is a required attribute that represents a reference to a type or its member that is available from the
current compilation environment. This can be any type defined in the project or a referenced assembly.
<seealso>
You use the <seealso> tag in the same way you do the <see> tag. The only difference is that its content is typically
placed in a "See Also" section. Here we'll add a seealso tag on the integer Add method to reference other
methods in the class that accept integer parameters:
/*
The main Math class
Contains all methods for performing basic math functions
*/
/// <summary>
/// The main <c>Math</c> class.
/// Contains all methods for performing basic math functions.
/// </summary>
public class Math
{
/// <summary>
/// Adds two integers and returns the result.
/// </summary>
/// <returns>
/// The sum of two integers.
/// </returns>
/// <example>
/// <code>
/// int c = Math.Add(4, 5);
/// if (c > 10)
/// {
/// Console.WriteLine(c);
/// }
/// </code>
/// </example>
/// <exception cref="System.OverflowException">Thrown when one parameter is max
/// and the other is greater than 0.</exception>
/// See <see cref="Math.Add(double, double)"/> to add doubles.
/// <seealso cref="Math.Subtract(int, int)"/>
/// <seealso cref="Math.Multiply(int, int)"/>
/// <seealso cref="Math.Divide(int, int)"/>
public static int Add(int a, int b)
{
if ((a == int.MaxValue && b > 0) || (b == int.MaxValue && a > 0))
throw new System.OverflowException();
return a + b;
}
}
The cref attribute represents a reference to a type or its member that is available from the current compilation
environment. This can be any type defined in the project or a referenced assembly.
<param>
You use the <param> tag to describe a method's parameters. Here's an example on the double Add method: The
parameter the tag describes is specified in the required name attribute.
/*
The main Math class
Contains all methods for performing basic math functions
*/
/// <summary>
/// The main <c>Math</c> class.
/// Contains all methods for performing basic math functions.
/// </summary>
public class Math
{
/// <summary>
/// Adds two doubles and returns the result.
/// </summary>
/// <returns>
/// The sum of two doubles.
/// </returns>
/// <exception cref="System.OverflowException">Thrown when one parameter is max
/// and the other is greater than zero.</exception>
/// See <see cref="Math.Add(int, int)"/> to add integers.
/// <param name="a">A double precision number.</param>
/// <param name="b">A double precision number.</param>
public static double Add(double a, double b)
{
if ((a == double.MaxValue && b > 0) || (b == double.MaxValue && a > 0))
throw new System.OverflowException();
return a + b;
}
}
<typeparam>
You use <typeparam> tag just like the <param> tag but for generic type or method declarations to describe a
generic parameter. Add a quick generic method to your Math class to check if one quantity is greater than another.
/*
The main Math class
Contains all methods for performing basic math functions
*/
/// <summary>
/// The main <c>Math</c> class.
/// Contains all methods for performing basic math functions.
/// </summary>
public class Math
{
/// <summary>
/// Checks if an IComparable is greater than another.
/// </summary>
/// <typeparam name="T">A type that inherits from the IComparable interface.</typeparam>
public static bool GreaterThan<T>(T a, T b) where T : IComparable
{
return a.CompareTo(b) > 0;
}
}
<paramref>
Sometimes you might be in the middle of describing what a method does in what could be a <summary> tag, and
you might want to make a reference to a parameter. The <paramref> tag is great for just this. Let's update the
summary of our double based Add method. Like the <param> tag the parameter name is specified in the required
name attribute.
/*
The main Math class
Contains all methods for performing basic math functions
*/
/// <summary>
/// The main <c>Math</c> class.
/// Contains all methods for performing basic math functions.
/// </summary>
public class Math
{
/// <summary>
/// Adds two doubles <paramref name="a"/> and <paramref name="b"/> and returns the result.
/// </summary>
/// <returns>
/// The sum of two doubles.
/// </returns>
/// <exception cref="System.OverflowException">Thrown when one parameter is max
/// and the other is greater than zero.</exception>
/// See <see cref="Math.Add(int, int)"/> to add integers.
/// <param name="a">A double precision number.</param>
/// <param name="b">A double precision number.</param>
public static double Add(double a, double b)
{
if ((a == double.MaxValue && b > 0) || (b == double.MaxValue && a > 0))
throw new System.OverflowException();
return a + b;
}
}
<typeparamref>
You use <typeparamref> tag just like the <paramref> tag but for generic type or method declarations to describe a
generic parameter. You can use the same generic method you previously created.
/*
The main Math class
Contains all methods for performing basic math functions
*/
/// <summary>
/// The main <c>Math</c> class.
/// Contains all methods for performing basic math functions.
/// </summary>
public class Math
{
/// <summary>
/// Checks if an IComparable <typeparamref name="T"/> is greater than another.
/// </summary>
/// <typeparam name="T">A type that inherits from the IComparable interface.</typeparam>
public static bool GreaterThan<T>(T a, T b) where T : IComparable
{
return a.CompareTo(b) > 0;
}
}
<list>
You use the <list> tag to format documentation information as an ordered list, unordered list or table. Make an
unordered list of every math operation your Math library supports.
/*
The main Math class
Contains all methods for performing basic math functions
*/
/// <summary>
/// The main <c>Math</c> class.
/// Contains all methods for performing basic math functions.
/// <list type="bullet">
/// <item>
/// <term>Add</term>
/// <description>Addition Operation</description>
/// </item>
/// <item>
/// <term>Subtract</term>
/// <description>Subtraction Operation</description>
/// </item>
/// <item>
/// <term>Multiply</term>
/// <description>Multiplication Operation</description>
/// </item>
/// <item>
/// <term>Divide</term>
/// <description>Division Operation</description>
/// </item>
/// </list>
/// </summary>
public class Math
{
You can make an ordered list or table by changing the type attribute to number or table , respectively.
Putting it all together
If you've followed this tutorial and applied the tags to your code where necessary, your code should now look
similar to the following:
/*
The main Math class
Contains all methods for performing basic math functions
*/
/// <summary>
/// The main <c>Math</c> class.
/// Contains all methods for performing basic math functions.
/// <list type="bullet">
/// <item>
/// <term>Add</term>
/// <description>Addition Operation</description>
/// </item>
/// <item>
/// <term>Subtract</term>
/// <description>Subtraction Operation</description>
/// </item>
/// <item>
/// <term>Multiply</term>
/// <description>Multiplication Operation</description>
/// </item>
/// <item>
/// <term>Divide</term>
/// <description>Division Operation</description>
/// </item>
/// </list>
/// </summary>
/// <remarks>
/// <para>This class can add, subtract, multiply and divide.</para>
/// <para>These operations can be performed on both integers and doubles.</para>
/// </remarks>
public class Math
{
// Adds two integers and returns the result
/// <summary>
/// Adds two integers <paramref name="a"/> and <paramref name="b"/> and returns the result.
/// </summary>
/// <returns>
/// The sum of two integers.
/// </returns>
/// <example>
/// <code>
/// int c = Math.Add(4, 5);
/// if (c > 10)
/// {
/// Console.WriteLine(c);
/// }
/// </code>
/// </example>
/// <exception cref="System.OverflowException">Thrown when one parameter is max
/// and the other is greater than 0.</exception>
/// See <see cref="Math.Add(double, double)"/> to add doubles.
/// <seealso cref="Math.Subtract(int, int)"/>
/// <seealso cref="Math.Multiply(int, int)"/>
/// <seealso cref="Math.Divide(int, int)"/>
/// <param name="a">An integer.</param>
/// <param name="b">An integer.</param>
public static int Add(int a, int b)
{
// If any parameter is equal to the max value of an integer
// and the other is greater than zero
if ((a == int.MaxValue && b > 0) || (b == int.MaxValue && a > 0))
throw new System.OverflowException();
return a + b;
}
From your code, you can generate a detailed documentation website complete with clickable cross-references. But
you're faced with another problem: your code has become hard to read. There's so much information to sift
through that this is going to be a nightmare for any developer who wants to contribute to this code. Thankfully
there's an XML tag that can help you deal with this:
<include>
The <include> tag lets you refer to comments in a separate XML file that describe the types and members in your
source code, as opposed to placing documentation comments directly in your source code file.
Now you're going to move all your XML tags into a separate XML file named docs.xml . Feel free to name the file
whatever you want.
<docs>
<members name="math">
<Math>
<summary>
The main <c>Math</c> class.
Contains all methods for performing basic math functions.
</summary>
<remarks>
<para>This class can add, subtract, multiply and divide.</para>
<para>These operations can be performed on both integers and doubles.</para>
</remarks>
</Math>
<AddInt>
<summary>
Adds two integers <paramref name="a"/> and <paramref name="b"/> and returns the result.
</summary>
<returns>
The sum of two integers.
</returns>
<example>
<example>
<code>
int c = Math.Add(4, 5);
if (c > 10)
{
Console.WriteLine(c);
}
</code>
</example>
<exception cref="System.OverflowException">Thrown when one parameter is max
and the other is greater than 0.</exception>
See <see cref="Math.Add(double, double)"/> to add doubles.
<seealso cref="Math.Subtract(int, int)"/>
<seealso cref="Math.Multiply(int, int)"/>
<seealso cref="Math.Divide(int, int)"/>
<param name="a">An integer.</param>
<param name="b">An integer.</param>
</AddInt>
<AddDouble>
<summary>
Adds two doubles <paramref name="a"/> and <paramref name="b"/> and returns the result.
</summary>
<returns>
The sum of two doubles.
</returns>
<example>
<code>
double c = Math.Add(4.5, 5.4);
if (c > 10)
{
Console.WriteLine(c);
}
</code>
</example>
<exception cref="System.OverflowException">Thrown when one parameter is max
and the other is greater than 0.</exception>
See <see cref="Math.Add(int, int)"/> to add integers.
<seealso cref="Math.Subtract(double, double)"/>
<seealso cref="Math.Multiply(double, double)"/>
<seealso cref="Math.Divide(double, double)"/>
<param name="a">A double precision number.</param>
<param name="b">A double precision number.</param>
</AddDouble>
<SubtractInt>
<summary>
Subtracts <paramref name="b"/> from <paramref name="a"/> and returns the result.
</summary>
<returns>
The difference between two integers.
</returns>
<example>
<code>
int c = Math.Subtract(4, 5);
if (c > 1)
{
Console.WriteLine(c);
}
</code>
</example>
See <see cref="Math.Subtract(double, double)"/> to subtract doubles.
<seealso cref="Math.Add(int, int)"/>
<seealso cref="Math.Multiply(int, int)"/>
<seealso cref="Math.Divide(int, int)"/>
<param name="a">An integer.</param>
<param name="b">An integer.</param>
</SubtractInt>
<SubtractDouble>
<summary>
Subtracts a double <paramref name="b"/> from another double <paramref name="a"/> and returns the
result.
</summary>
<returns>
The difference between two doubles.
</returns>
<example>
<code>
double c = Math.Subtract(4.5, 5.4);
if (c > 1)
{
Console.WriteLine(c);
}
</code>
</example>
See <see cref="Math.Subtract(int, int)"/> to subtract integers.
<seealso cref="Math.Add(double, double)"/>
<seealso cref="Math.Multiply(double, double)"/>
<seealso cref="Math.Divide(double, double)"/>
<param name="a">A double precision number.</param>
<param name="b">A double precision number.</param>
</SubtractDouble>
<MultiplyInt>
<summary>
Multiplies two integers <paramref name="a"/> and <paramref name="b"/> and returns the result.
</summary>
<returns>
The product of two integers.
</returns>
<example>
<code>
int c = Math.Multiply(4, 5);
if (c > 100)
{
Console.WriteLine(c);
}
</code>
</example>
See <see cref="Math.Multiply(double, double)"/> to multiply doubles.
<seealso cref="Math.Add(int, int)"/>
<seealso cref="Math.Subtract(int, int)"/>
<seealso cref="Math.Divide(int, int)"/>
<param name="a">An integer.</param>
<param name="b">An integer.</param>
</MultiplyInt>
<MultiplyDouble>
<summary>
Multiplies two doubles <paramref name="a"/> and <paramref name="b"/> and returns the result.
</summary>
<returns>
The product of two doubles.
</returns>
<example>
<code>
double c = Math.Multiply(4.5, 5.4);
if (c > 100.0)
{
Console.WriteLine(c);
}
</code>
</example>
See <see cref="Math.Multiply(int, int)"/> to multiply integers.
<seealso cref="Math.Add(double, double)"/>
<seealso cref="Math.Subtract(double, double)"/>
<seealso cref="Math.Divide(double, double)"/>
<param name="a">A double precision number.</param>
<param name="b">A double precision number.</param>
</MultiplyDouble>
<DivideInt>
<summary>
Divides an integer <paramref name="a"/> by another integer <paramref name="b"/> and returns the
result.
</summary>
<returns>
The quotient of two integers.
</returns>
<example>
<code>
int c = Math.Divide(4, 5);
if (c > 1)
{
Console.WriteLine(c);
}
</code>
</example>
<exception cref="System.DivideByZeroException">Thrown when <paramref name="b"/> is equal to 0.
</exception>
See <see cref="Math.Divide(double, double)"/> to divide doubles.
<seealso cref="Math.Add(int, int)"/>
<seealso cref="Math.Subtract(int, int)"/>
<seealso cref="Math.Multiply(int, int)"/>
<param name="a">An integer dividend.</param>
<param name="b">An integer divisor.</param>
</DivideInt>
<DivideDouble>
<summary>
Divides a double <paramref name="a"/> by another double <paramref name="b"/> and returns the
result.
</summary>
<returns>
The quotient of two doubles.
</returns>
<example>
<code>
double c = Math.Divide(4.5, 5.4);
if (c > 1.0)
{
Console.WriteLine(c);
}
</code>
</example>
<exception cref="System.DivideByZeroException">Thrown when <paramref name="b"/> is equal to 0.
</exception>
See <see cref="Math.Divide(int, int)"/> to divide integers.
<seealso cref="Math.Add(double, double)"/>
<seealso cref="Math.Subtract(double, double)"/>
<seealso cref="Math.Multiply(double, double)"/>
<param name="a">A double precision dividend.</param>
<param name="b">A double precision divisor.</param>
</DivideDouble>
</members>
</docs>
In the above XML, each member's documentation comments appear directly inside a tag named after what they do.
You can choose your own strategy. Now that you have your XML comments in a separate file, let's see how your
code can be made more readable by using the <include> tag:
/*
The main Math class
Contains all methods for performing basic math functions
*/
/// <include file='docs.xml' path='docs/members[@name="math"]/Math/*'/>
public class Math
{
// Adds two integers and returns the result
/// <include file='docs.xml' path='docs/members[@name="math"]/AddInt/*'/>
public static int Add(int a, int b)
public static int Add(int a, int b)
{
// If any parameter is equal to the max value of an integer
// and the other is greater than zero
if ((a == int.MaxValue && b > 0) || (b == int.MaxValue && a > 0))
throw new System.OverflowException();
return a + b;
}
return a + b;
}
And there you have it: our code is back to being readable, and no documentation information has been lost.
The filename attribute represents the name of the XML file containing the documentation.
The path attribute represents an XPath query to the tag name present in the specified filename .
The name attribute represents the name specifier in the tag that precedes the comments.
The id attribute which can be used in place of name represents the ID for the tag that precedes the comments.
User Defined Tags
All the tags outlined above represent those that are recognized by the C# compiler. However, a user is free to define
their own tags. Tools like Sandcastle bring support for extra tags like <event> , <note> and even support
documenting namespaces. Custom or in-house documentation generation tools can also be used with the standard
tags and multiple output formats from HTML to PDF can be supported.
Recommendations
Documenting code is recommended for many reasons. What follows are some best practices, general use case
scenarios, and things that you should know when using XML documentation tags in your C# code.
For the sake of consistency, all publicly visible types and their members should be documented. If you must do
it, do it all.
Private members can also be documented using XML comments. However, this exposes the inner (potentially
confidential) workings of your library.
At a bare minimum, types and their members should have a <summary> tag because its content is needed for
IntelliSense.
Documentation text should be written using complete sentences ending with full stops.
Partial classes are fully supported, and documentation information will be concatenated into a single entry for
that type.
The compiler verifies the syntax of the <exception> , <include> , <param> , <see> , <seealso> and <typeparam>
tags.
The compiler validates the parameters that contain file paths and references to other parts of the code.
See also
XML Documentation Comments (C# Programming Guide)
Recommended Tags for Documentation Comments (C# Programming Guide)
Versioning in C#
7/29/2017 • 5 min to read • Edit Online
In this tutorial you'll learn what versioning means in .NET. You'll also learn the factors to consider when versioning
your library as well as upgrading to a new version of the a library.
Authoring Libraries
As a developer who has created .NET libraries for public use, you've most likely been in situations where you have
to roll out new updates. How you go about this process matters a lot as you need to ensure that there's a seamless
transition of existing code to the new version of your library. Here are several things to consider when creating a
new release:
Semantic Versioning
Semantic versioning (SemVer for short) is a naming convention applied to versions of your library to signify
specific milestone events. Ideally, the version information you give your library should help developers determine
the compatibility with their projects that make use of older versions of that same library.
The most basic approach to SemVer is the 3 component format MAJOR.MINOR.PATCH , where:
MAJOR is incremented when you make incompatible API changes
MINOR is incremented when you add functionality in a backwards-compatible manner
PATCH is incremented when you make backwards-compatible bug fixes
There are also ways to specify other scenarios like pre-release versions etc. when applying version information to
your .NET library.
Backwards Compatibility
As you release new versions of your library, backwards compatibility with previous versions will most likely be one
of your major concerns. A new version of your library is source compatible with a previous version if code that
depends on the previous version can, when recompiled, work with the new version. A new version of your library is
binary compatible if an application that depended on the old version can, without recompilation, work with the new
version.
Here are some things to consider when trying to maintain backwards compatibility with older versions of your
library:
Virtual methods: When you make a virtual method non-virtual in your new version it means that projects that
override that method will have to be updated. This is a huge breaking change and is strongly discouraged.
Method signatures: When updating a method behaviour requires you to change its signature as well, you should
instead create an overload so that code calling into that method will still work. You can always manipulate the
old method signature to call into the new method signature so that implementation remains consistent.
Obsolete attribute: You can use this attribute in your code to specify classes or class members that are
deprecated and likely to be removed in future versions. This ensures developers utilizing your library are better
prepared for breaking changes.
Optional Method Arguments: When you make previously optional method arguments compulsory or change
their default value then all code that does not supply those arguments will need to be updated.
NOTE
Making compulsory arguments optional should have very little effect especially if it doesn't change the method's behaviour.
The easier you make it for your users to upgrade to the new version of your library, the more likely that they will
upgrade sooner.
Application Configuration File
As a .NET developer there's a very high chance you've encountered the app.config file present in most project
types. This simple configuration file can go a long way into improving the rollout of new updates. You should
generally design your libraries in such a way that information that is likely to change regularly is stored in the
app.config file, this way when such information is updated the config file of older versions just needs to be
replaced with the new one without the need for recompilation of the library.
Consuming Libraries
As a developer that consumes .NET libraries built by other developers you're most likely aware that a new version
of a library might not be fully compatible with your project and you might often find yourself having to update
your code to work with those changes.
Lucky for you C# and the .NET ecosystem comes with features and techniques that allow us to easily update our
app to work with new versions of libraries that might introduce breaking changes.
Assembly Binding Redirection
You can use the app.config file to update the version of a library your app uses. By adding what is called a binding
redirect your can use the new library version without having to recompile your app. The following example shows
how you would update your app's app.config file to use the 1.0.1 patch version of ReferencedLibrary instead of
the 1.0.0 version it was originally compiled with.
<dependentAssembly>
<assemblyIdentity name="ReferencedLibrary" publicKeyToken="32ab4ba45e0a69a1" culture="en-us" />
<bindingRedirect oldVersion="1.0.0" newVersion="1.0.1" />
</dependentAssembly>
NOTE
This approach will only work if the new version of ReferencedLibrary is binary compatible with your app. See the
Backwards Compatibility section above for changes to look out for when determining compatibility.
new
You use the new modifier to hide inherited members of a base class. This is one way derived classes can respond
to updates in base classes.
Take the following example:
public class BaseClass
{
public void MyMethod()
{
Console.WriteLine("A base method");
}
}
b.MyMethod();
d.MyMethod();
}
Output
A base method
A derived method
From the example above you can see how DerivedClass hides the MyMethod method present in BaseClass . This
means that when a base class in the new version of a library adds a member that already exists in your derived
class, you can simply use the new modifier on your derived class member to hide the base class member.
When no new modifier is specified, a derived class will by default hide conflicting members in a base class,
although a compiler warning will be generated the code will still compile. This means that simply adding new
members to an existing class makes that new version of your library both source and binary compatible with code
that depends on it.
override
The override modifier means a derived implementation extends the implementation of a base class member
rather than hides it. The base class member needs to have the virtual modifier applied to it.
public class MyBaseClass
{
public virtual string MethodOne()
{
return "Method One";
}
}
Output
The override modifier is evaluated at compile time and the compiler will throw an error if it doesn't find a virtual
member to override.
Your knowledge of the discussed techniques as well as your understanding of what situations to use them will go a
long way to boost the ease of transition between versions of a library.
C# programming guide
7/29/2017 • 1 min to read • Edit Online
This section provides detailed information on key C# language features and features accessible to C# through the
.NET Framework.
Most of this section assumes that you already know something about C# and general programming concepts. If
you are a complete beginner with programming or with C#, you might want to visit the Getting Started with C#
interactive tutorial, where no prior programming knowledge is required.
For information about specific keywords, operators and preprocessor directives, see C# Reference. For information
about the C# Language Specification, see C# Language Specification.
Program sections
Inside a C# Program
Main() and Command-Line Arguments
Language Sections
Statements, Expressions, and Operators
Types
Classes and Structs
Interfaces
Enumeration Types
Delegates
Arrays
Strings
Properties
Indexers
Events
Generics
Iterators
LINQ Query Expressions
Lambda Expressions
Namespaces
Nullable Types
Unsafe Code and Pointers
XML Documentation Comments
Platform Sections
Application Domains (C# and Visual Basic)
Assemblies and the Global Assembly Cache
Attributes
Collections
Exceptions and Exception Handling
File System and the Registry (C# Programming Guide)
Interoperability
Reflection
See Also
C# Reference
C#
C# Reference
7/29/2017 • 1 min to read • Edit Online
This section provides reference material about C# keywords, operators, special characters, preprocessor directives,
compiler options, and compiler errors and warnings.
In This Section
C# Keywords
Provides links to information about C# keywords and syntax.
C# Operators
Provides links to information about C# operators and syntax.
C# Special Characters
Provides links to information about special contextual characters in C# and their usage.
C# Preprocessor Directives
Provides links to information about compiler commands for embedding in C# source code.
C# Compiler Options
Includes information about compiler options and how to use them.
C# Compiler Errors
Includes code snippets that demonstrate the cause and correction of C# compiler errors and warnings.
C# Language Specification
Provides pointers to the latest version of the C# Language Specification in Microsoft Word format.
Related Sections
C# KB articles in the Microsoft Knowledge Base
Opens a Microsoft search page for Knowledge Base articles that are available on MSDN.
C#
Provides a portal to Visual C# documentation.
Using the Visual Studio Development Environment for C#
Provides links to conceptual and task topics that describe the IDE and Editor.
C# Programming Guide
Includes information about how to use the C# programming language.
C# Walkthroughs
7/29/2017 • 2 min to read • Edit Online
Walkthroughs give step-by-step instructions for common scenarios, which makes them a good place to start
learning about the product or a particular feature area.
This section contains links to C# programming walkthroughs.
In This Section
Accessing the Web by Using Async and Await
Shows how to create an asynchronous solution by using async and await.
Creating a Windows Runtime Component in C# or Visual Basic and Calling it from JavaScript
Shows how to create a Windows Runtime type, package it in a Windows Runtime component, and then call the
component from a Windows 8.x Store app that's built for Windows by using JavaScript.
Office Programming (C# and Visual Basic)
Shows how to create an Excel workbook and a Word document by using C# and Visual Basic.
Creating and Using Dynamic Objects (C# and Visual Basic)
Shows how to create a custom object that dynamically exposes the contents of a text file, and how to create a
project that uses the IronPython library.
Authoring a Composite Control with Visual C#
Demonstrates creating a simple composite control and extending its functionality through inheritance.
Creating a Windows Forms Control that Takes Advantage of Visual Studio Design-Time Features
Illustrates how to create a custom designer for a custom control.
Inheriting from a Windows Forms Control with Visual C#
Demonstrates creating a simple inherited button control. This button inherits functionality from the standard
Windows Forms button and exposes a custom member.
Debugging Custom Windows Forms Controls at Design Time
Describes how to debug the design-time behavior of your custom control.
Performing Common Tasks Using Smart Tags on Windows Forms Controls
Demonstrates some of the commonly performed tasks such as adding or removing a tab on a TabControl , docking
a control to its parent, and changing the orientation of a SplitContainer control.
Writing Queries in C# (LINQ)
Demonstrates the C# language features that are used to write LINQ query expressions.
Manipulating Data (C#) (LINQ to SQL)
Describes a LINQ to SQL scenario for adding, modifying, and deleting data in a database.
Simple Object Model and Query (C#) (LINQ to SQL)
Demonstrates how to create an entity class and a simple query to filter the entity class.
Using Only Stored Procedures (C#) (LINQ to SQL)
Demonstrates how to use LINQ to SQL to access data by executing only stored procedures.
Querying Across Relationships (C#) (LINQ to SQL)
Demonstrates the use of LINQ to SQL associations to represent foreign-key relationships in a database.
Writing a Visualizer in C#
Shows how to write a simple visualizer by using C#.
Related Sections
Deployment Samples and Walkthroughs
Provides step-by-step examples of common deployment scenarios.
See Also
C# Programming Guide
Visual Studio Samples
F# Guide
7/29/2017 • 1 min to read • Edit Online
F# is a cross-platform, open source programming language for .NET which provides first-class support for
functional programming, along with support of object-oriented and imperative programming. The Visual F#
compiler and tooling are Microsoft's implementation and tooling for the F# programming language, making F# a
first-class member of .NET.
If You're New to F#
If you're new to F#, begin with the Tour of F# to get an overview of the language.
It's also recommended that you go through the Functions as First-Class Values to learn Functional Programming
concepts which are essential to working with F#.
The Tutorials also have step-by-step guides for various skill levels and features of the language.
Documentation
Tutorials
Functions as First-Class Values
Language Reference
F# Core Library Reference
The best way to learn about F# is to read and write F# code. This article will act as a tour through some of the key
features of the F# language and give you some code snippets that you can execute on your machine. To learn
about setting up a development environment, check out Getting Started.
There are two primary concepts in F#: functions and types. This tour will emphasize features of the language
which fall into these two concepts.
The quickest way to run these code samples is to use F# Interactive. Just copy/paste the code samples and run
them there. Alternatively you can set up a project to compile and run the code as a Console Application. See the
Get Started section to learn more.
/// You use 'let' to define a function. This one accepts an integer argument and returns an integer.
/// Parentheses are optional for function arguments, except for when you use an explicit type annotation.
let sampleFunction1 x = x*x + 3
/// Apply the function, naming the function return result using 'let'.
/// The variable type is inferred from the function return type.
let result1 = sampleFunction1 4573
// This line uses '%d' to print the result as an integer. This is type-safe.
// If 'result1' were not of type 'int', then the line would fail to compile.
printfn "The result of squaring the integer 4573 and adding 3 is %d" result1
/// When needed, annotate the type of a parameter name using '(argument:type)'. Parentheses are
required.
let sampleFunction2 (x:int) = 2*x*x - x/5 + 3
// This line uses '%f' to print the result as a float. As with '%d' above, this is type-safe.
printfn "The result of applying the 2nd sample function to (6.5 + 4.5) is %f" result3
let bindings are also how you bind a value to a name, similar to a variable in other languages. let bindings are
immutable by default, which means that once a value or function is bound to a name, it cannot be changed in-
place. This is in contrast to variables in other languages, which are mutable, meaning their values can be changed
at any point in time. If you require a mutable binding, you can use let mutable ... syntax.
module Immutability =
/// A mutable binding. This is required to be able to mutate the value of 'otherNumber'.
let mutable otherNumber = 2
module IntegersAndNumbers =
/// This computed a new number by some arithmetic. Numeric types are converted using
/// functions 'int', 'double' and so on.
let sampleInteger2 = (sampleInteger/4 + 5 - 7) * 4 + int sampleDouble
/// This is a list of all tuples containing all the numbers from 0 to 99 and their squares.
let sampleTableOfSquares = [ for i in 0 .. 99 -> (i, i*i) ]
// The next line prints a list that includes tuples, using '%A' for generic printing.
printfn "The table of squares from 0 to 99 is:\n%A" sampleTableOfSquares
Here's what Boolean values and performing basic conditional logic looks like:
module Booleans =
/// Substrings use the indexer notation. This line extracts the first 7 characters as a substring.
/// Note that like many languages, Strings are zero-indexed in F#.
let substring = helloWorld.[0..6]
printfn "%s" substring
Tuples
Tuples are a big deal in F#. They are a grouping of unnamed, but ordered values, that can be treated as values
themselves. Think of them as values which are aggregated from other values. They have many uses, such as
conveniently returning multiple values from a function, or grouping values for some ad-hoc convenience.
module Tuples =
As of F# 4.1, you can also create struct tuples. These also interoperate fully with C#7/Visual Basic 15 tuples,
which are also struct tuples:
/// Tuples are normally objects, but they can also be represented as structs.
///
/// These interoperate completely with structs in C# and Visual Basic.NET; however,
/// struct tuples are not implicitly convertible with object tuples (often called reference tuples).
///
/// The second line below will fail to compile because of this. Uncomment it to see what happens.
let sampleStructTuple = struct (1, 2)
//let thisWillNotCompile: (int*int) = struct (1, 2)
printfn "Struct Tuple: %A\nReference tuple made from the Struct Tuple: %A" sampleStructTuple
(sampleStructTuple |> convertFromStructTuple)
It's important to note that because struct tuples are value types, they cannot be implicitly converted to reference
tuples, or vice versa. You must explicitly convert between a reference and struct tuple.
module PipelinesAndComposition =
/// You can shorten 'squareOddValuesAndAddOnePipeline' by moving the second `List.map` call
/// into the first, using a Lambda Function.
///
/// Note that pipelines are also being used inside the lambda function. F# pipe operators
/// can be used for single values as well. This makes them very powerful for processing data.
let squareOddValuesAndAddOneShorterPipeline values =
values
|> List.filter isOdd
|> List.map(fun x -> x |> square |> addOne)
/// Lastly, you can eliminate the need to explicitly take 'values' in as a parameter by using '>>'
/// to compose the two core operations: filtering out even numbers, then squaring and adding one.
/// Likewise, the 'fun x -> ...' bit of the lambda expression is also not needed, because 'x' is simply
/// being defined in that scope so that it can be passed to a functional pipeline. Thus, '>>' can be
used
/// there as well.
///
/// The result of 'squareOddValuesAndAddOneComposition' is itself another function which takes a
/// list of integers as its input. If you execute 'squareOddValuesAndAddOneComposition' with a list
/// of integers, you'll notice that it produces the same results as previous functions.
///
/// This is using what is known as function composition. This is possible because functions in F#
/// use Partial Application and the input and output types of each data processing operation match
/// the signatures of the functions we're using.
let squareOddValuesAndAddOneComposition =
List.filter isOdd >> List.map (square >> addOne)
The above sample made use of many features of F#, including list processing functions, first-class functions, and
partial application. Although a deep understanding of each of those concepts can become somewhat advanced, it
should be clear how easily functions can be used to process data when building pipelines.
/// This is a list with 3 elements. ';' is used to separate elements on the same line.
let list2 = [ 1; 2; 3 ]
/// You can also separate elements by placing them on their own lines.
let list3 = [
1
2
3
]
/// Computations can include conditionals. This is a list containing the tuples
/// which are the coordinates of the black squares on a chess board.
let blackSquares =
[ for i in 0 .. 7 do
for j in 0 .. 7 do
if (i+j) % 2 = 1 then
yield (i, j) ]
/// Lists can be transformed using 'List.map' and other functional programming combinators.
/// This definition produces a new list by squaring the numbers in numberList, using the pipeline
/// operator to pass an argument to List.map.
let squares =
numberList
|> List.map (fun x -> x*x)
/// There are many other list combinations. The following computes the sum of the squares of the
/// numbers divisible by 3.
let sumOfSquares =
numberList
|> List.filter (fun x -> x % 3 = 0)
|> List.sumBy (fun x -> x * x)
printfn "The sum of the squares of numbers up to 1000 that are divisible by 3 is: %d" sumOfSquares
Arrays are fixed-size, mutable collections of elements of the same type. They support fast random access of
elements, and are faster than F# lists because they are just contiguous blocks of memory.
module Arrays =
/// This is The empty array. Note that the syntax is similar to that of Lists, but uses `[| ... |]`
instead.
let array1 = [| |]
/// Arrays are specified using the same range of constructs as lists.
let array2 = [| "hello"; "world"; "and"; "hello"; "world"; "again" |]
/// This is an array containing only the words "hello" and "world".
let array4 =
[| for word in array2 do
if word.Contains("l") then
yield word |]
/// This is an array initialized by index and containing the even numbers from 0 to 2000.
let evenNumbers = Array.init 1001 (fun n -> n * 2)
/// You can loop over arrays and lists using 'for' loops.
for word in array4 do
printfn "word: %s" word
// You can modify the contents of an an array element by using the left arrow assignment operator.
//
// To learn more about this operator, see: https://docs.microsoft.com/dotnet/fsharp/language-
reference/values/index#mutable-variables
array2.[1] <- "WORLD!"
/// You can transform arrays using 'Array.map' and other functional programming operations.
/// The following calculates the sum of the lengths of the words that start with 'h'.
let sumOfLengthsOfWords =
array2
|> Array.filter (fun x -> x.StartsWith "h")
|> Array.sumBy (fun x -> x.Length)
printfn "The sum of the lengths of the words in Array 2 is: %d" sumOfLengthsOfWords
Sequences are a logical series of elements, all of the same type. These are a more general type than Lists and
Arrays, capable of being your "view" into any logical series of elements. They also stand out because they can be
lazy, which means that elements can be computed only when they are needed.
module Sequences =
/// This example shows the first 100 elements of the random walk.
let first100ValuesOfRandomWalk =
randomWalk 5.0
|> Seq.truncate 100
|> Seq.toList
Recursive Functions
Processing collections or sequences of elements is typically done with recursion in F#. Although F# has support
for loops and imperative programming, recursion is preferred because it is easier to guarantee correctness.
NOTE
The following example makes use of the pattern matching via the match expression. This fundamental construct is covered
later in this article.
module RecursiveFunctions =
/// This example shows a recursive function that computes the factorial of an
/// integer. It uses 'let rec' to define a recursive function.
let rec factorial n =
if n = 0 then 1 else n * factorial (n-1)
printfn "The Greatest Common Factor of 300 and 620 is %d" (greatestCommonFactor 300 620)
/// This example computes the sum of a list of integers using recursion.
let rec sumList xs =
match xs with
| [] -> 0
| y::ys -> y + sumList ys
/// This makes 'sumList' tail recursive, using a helper function with a result accumulator.
let rec private sumListTailRecHelper accumulator xs =
match xs with
| [] -> accumulator
| y::ys -> sumListTailRecHelper (accumulator+y) ys
/// This invokes the tail recursive helper function, providing '0' as a seed accumulator.
/// An approach like this is common in F#.
let sumListTailRecursive xs = sumListTailRecHelper 0 xs
F# also has full support for Tail Call Optimization, which is a way to optimize recursive calls so that they are just as
fast as a loop construct.
/// You can also do this on the same line with ';' separators.
let contactOnSameLine = { Name = "Alf"; Phone = "(206) 555-0157"; Verified = false }
/// This example shows how to use "copy-and-update" on record values. It creates
/// a new record value that is a copy of contact1, but has different values for
/// the 'Phone' and 'Verified' fields.
///
/// To learn more, see: https://docs.microsoft.com/dotnet/fsharp/language-reference/copy-and-update-
record-expressions
let contact2 =
{ contact1 with
Phone = "(206) 555-0112"
Verified = true }
/// This example shows how to write a function that processes a record value.
/// It converts a 'ContactCard' object to a string.
let showContactCard (c: ContactCard) =
c.Name + " Phone: " + c.Phone + (if not c.Verified then " (unverified)" else "")
let contactAlternate =
{ Name = "Alf"
Phone = "(206) 555-0157"
Verified = false
Address = "111 Alf Street" }
As of F# 4.1, you can also represent Records as struct s. This is done with the [<Struct>] attribute:
/// Records can also be represented as structs via the 'Struct' attribute.
/// This is helpful in situations where the performance of structs outweighs
/// the flexibility of reference types.
[<Struct>]
type ContactCardStruct =
{ Name : string
Phone : string
Verified : bool }
Discriminated Unions (DUs) are values which could be a number of named forms or cases. Data stored in the type
can be one of several distinct values.
module DiscriminatedUnions =
/// A Discriminated Union can also be used to represent the rank of a playing card.
type Rank =
/// Represents the rank of cards 2 .. 10
| Value of int
| Ace
| King
| Queen
| Jack
/// This computes a list representing all the cards in the deck.
let fullDeck =
[ for suit in [ Hearts; Diamonds; Clubs; Spades] do
for rank in Rank.GetAllRanks() do
yield { Suit=suit; Rank=rank } ]
You can also use DUs as Single-Case Discriminated Unions, to help with domain modeling over primitive types.
Often times, strings and other primitive types are used to represent something, and are thus given a particular
meaning. However, using only the primitive representation of the data can result in mistakenly assigning an
incorrect value! Representing each type of information as a distinct single-case union can enforce correctness in
this scenario.
// Single-case DUs are often used for domain modeling. This can buy you extra type safety
// over primitive types such as strings and ints.
//
// Single-case DUs cannot be implicitly converted to or from the type they wrap.
// For example, a function which takes in an Address cannot accept a string as that input,
// or vice versa.
type Address = Address of string
type Name = Name of string
type SSN = SSN of int
/// When you need the value, you can unwrap the underlying value with a simple function.
let unwrapAddress (Address a) = a
let unwrapName (Name n) = n
let unwrapSSN (SSN s) = s
As the above sample demonstrates, to get the underlying value in a single-case Discriminated Union, you must
explicitly unwrap it.
Additionally, DUs also support recursive definitions, allowing you to easily represent trees and inherently
recursive data. For example, here's how you can represent a Binary Search Tree with exists and insert
functions.
Because DUs allow you to represent the recursive structure of the tree in the data type, operating on this recursive
structure is straightforward and guarantees correctness. It is also supported in pattern matching, as shown below.
Additionally, you can represent DUs as struct s with the [<Struct>] attribute:
/// Discriminated Unions can also be represented as structs via the 'Struct' attribute.
/// This is helpful in situations where the performance of structs outweighs
/// the flexibility of reference types.
///
/// However, there are two important things to know when doing this:
/// 1. A struct DU cannot be recursively-defined.
/// 2. A struct DU must have unique names for each of its cases.
[<Struct>]
type Shape =
| Circle of radius: float
| Square of side: float
| Triangle of height: float * width: float
However, there are two key things to keep in mind when doing so:
1. A struct DU cannot be recursively-defined.
2. A struct DU must have unique names for each of its cases.
Failure to follow the above will result in a compilation error.
Pattern Matching
Pattern Matching is the F# language feature which enables correctness for operating on F# types. In the above
samples, you probably noticed quite a bit of match x with ... syntax. This construct allows the compiler, which
can understand the "shape" of data types, to force you to account for all possible cases when using a data type
through what is known as Exhaustive Pattern Matching. This is incredibly powerful for correctness, and can be
cleverly used to "lift" what would normally be a runtime concern into compile-time.
module PatternMatching =
/// Find all managers/executives named "Dave" who do not have any reports.
/// This uses the 'function' shorthand to as a lambda expression.
let rec findDaveWithOpenPosition(emps : List<Employee>) =
emps
|> List.filter(function
| Manager({First = "Dave"}, []) -> true // [] matches an empty list.
| Executive({First = "Dave"}, [], _) -> true
| _ -> false) // '_' is a wildcard pattern that matches anything.
// This handles the "or else" case.
You can also use the shorthand function construct for pattern matching, which is useful when you're writing
functions which make use of Partial Application:
open System
/// You can also use the shorthand function construct for pattern matching,
/// which is useful when you're writing functions which make use of Partial Application.
let private parseHelper f = f >> function
| (true, item) -> Some item
| (false, _) -> None
// Define some more functions which parse with the helper function.
let parseInt = parseHelper Int32.TryParse
let parseDouble = parseHelper Double.TryParse
let parseTimeSpan = parseHelper TimeSpan.TryParse
Something you may have noticed is the use of the _ pattern. This is known as the Wildcard Pattern, which is a
way of saying "I don't care what something is". Although convenient, you can accidentally bypass Exhaustive
Pattern Matching and no longer benefit from compile-time enforcements if you aren't careful in using _ . It is
best used when you don't care about certain pieces of a decomposed type when pattern matching, or the final
clause when you have enumerated all meaningful cases in a pattern matching expression.
Active Patterns are another powerful construct to use with pattern matching. They allow you to partition input
data into custom forms, decomposing them at the pattern match call site. They can also be parameterized, thus
allowing to define the partition as a function. Expanding the previous example to support Active Patterns looks
something like this:
// Active Patterns are another powerful construct to use with pattern matching.
// They allow you to partition input data into custom forms, decomposing them at the pattern match call site.
//
// To learn more, see: https://docs.microsoft.com/dotnet/fsharp/language-reference/active-patterns
let (|Int|_|) = parseInt
let (|Double|_|) = parseDouble
let (|Date|_|) = parseDateTimeOffset
let (|TimeSpan|_|) = parseTimeSpan
/// Pattern Matching via 'function' keyword and Active Patterns often looks like this.
let printParseResult = function
| Int x -> printfn "%d" x
| Double x -> printfn "%f" x
| Date d -> printfn "%s" (d.ToString())
| TimeSpan t -> printfn "%s" (t.ToString())
| _ -> printfn "Nothing was parse-able!"
Optional Types
One special case of Discriminated Union types is the Option Type, which is so useful that it's a part of the F# core
library.
The Option Type is a type which represents one of two cases: a value, or nothing at all. It is used in any scenario
where a value may or may not result from a particular operation. This then forces you to account for both cases,
making it a compile-time concern rather than a runtime concern. These are often used in APIs where null is used
to represent "nothing" instead, thus eliminating the need to worry about NullReferenceException in many
circumstances.
module OptionValues =
/// First, define a zip code defined via Single-case Discriminated Union.
type ZipCode = ZipCode of string
/// Next, define an interface type the represents an object to compute the shipping zone for the
customer's zip code,
/// given implementations for the 'getState' and 'getShippingZone' abstract methods.
type IShippingCalculator =
abstract GetState : ZipCode -> string option
abstract GetShippingZone : string -> int
/// Next, calculate a shipping zone for a customer using a calculator instance.
/// This uses combinators in the Option module to allow a functional pipeline for
/// transforming data with Optionals.
let CustomerShippingZone (calculator: IShippingCalculator, customer: Customer) =
customer.ZipCode
|> Option.bind calculator.GetState
|> Option.map calculator.GetShippingZone
Units of Measure
One unique feature of F#'s type system is the ability to provide context for numeric literals through Units of
Measure.
Units of Measure allow you to associate a numeric type to a unit, such as Meters, and have functions perform
work on units rather than numeric literals. This enables the compiler to verify that the types of numeric literals
passed in make sense under a certain context, thus eliminating runtime errors associated with that kind of work.
module UnitsOfMeasure =
// Values using Units of Measure can be used just like the primitive numeric type for things like
printing.
printfn "After a %f race I would walk %f miles which would be %f meters" sampleValue1 sampleValue2
sampleValue3
The F# Core library defines many SI unit types and unit conversions. To learn more, check out the
Microsoft.FSharp.Data.UnitSystems.SI Namespace.
module DefiningClasses =
/// This internal field stores the length of the vector, computed when the
/// object is constructed
let length = sqrt (dx*dx + dy*dy)
member this.DY = dy
/// Get a new scaled vector object, without modifying the original object.
let vector2 = vector1.Scale(10.0)
module DefiningGenericClasses =
/// An 'int' instance of the state tracker class. Note that the type parameter is inferred.
let tracker = StateTracker 10
// Add a state
tracker.UpdateState 17
To implement an Interface, you can use either interface ... with syntax or an Object Expression.
module ImplementingInterfaces =
Next Steps
Now that you've seen some of the primary features of the language, you should be ready to write your first F#
programs! Check out Getting Started to learn how to set up your development environment and write some code.
The next steps for learning more can be whatever you like, but we recommend Functions as First-Class Values to
get comfortable with core Functional Programming concepts. These will be essential in building robust programs
in F#.
Also, check out the F# Language Reference to see a comprehensive collection of conceptual content on F#.
Getting Started with F#
7/29/2017 • 1 min to read • Edit Online
There are multiple ways to get started with F#. We have multiple articles written to provide a guide for each major
way. You can use the following table to help in making a decision.
OS PREFER VISUAL STUDIO PREFER VISUAL STUDIO CODE PREFER A COMMAND LINE
Windows Get started with Visual Get started with VSCode Get started with the .NET
Studio and Ionide Core CLI
macOS Get started with VS for Mac Get started with VSCode Get started with the .NET
and Ionide Core CLI
Linux N/A Get started with VSCode Get started with the .NET
and Ionide Core CLI
In general, there is no specific way to get started which is better than the rest. We recommend trying all ways to
use F# on your machine to see what you like the best!
Get started with F# in Visual Studio
8/14/2017 • 5 min to read • Edit Online
F# and the Visual F# tooling are supported in the Visual Studio IDE. To begin, you should download Visual Studio,
if you haven't already. This article uses the Visual Studio 2017 Community Edition, but you can use F# with the
version of your choice.
Installing F#
If you're downloading Visual Studio for the first time, it will first install the Visual Studio installer. Install any
version of Visual Studio 2017 from the installer. If you already have it installed, click Modify.
You'll next see a list of Workloads. You can install F# through any of the following workloads:
WORKLOAD ACTION
.NET desktop development Select F# language support from the right-hand side
ASP.NET and web development Select F# language support from the right-hand side
Data storage and processing Select F# language support from the right-hand side
Alternatively, you can select Individual components and install F# language support from there. Feel free to
select as many Workloads or Individual Components as you like.
Finally, click Modify in the lower right-hand side. This will install everything you have selected. You can then open
Visual Studio 2017 with F# language support by clicking Launch.
let square x = x * x
[<EntryPoint>]
let main argv =
printfn "%d squared is: %d!" 12 (square 12)
0 // Return an integer exit code
In the previous code sample, a function square has been defined which takes an input named x and multiplies it
by itself. Because F# uses Type Inference, the type of x doesn't need to be specified. The F# compiler understands
the types where multiplication is valid, and will assign a type to x based on how square is called. If you hover
over square , you should see the following:
This is what is known as the function's type signature. It can be read like this: "Square is a function which takes an
integer named x and produces an integer". Note that the compiler gave square the int type for now - this is
because multiplication is not generic across all types, but rather is generic across a closed set of types. The F#
compiler picked int at this point, but it will adjust the type signature if you call square with a different input type,
such as a float .
Another function, main , is defined, which is decorated with the EntryPoint attribute to tell the F# compiler that
program execution should start there. It follows the same convention as other C-style programming languages,
where command-line arguments can be passed to this function, and an integer code is returned (typically 0 ).
It is in this function that we call the square function with an argument of 12 . The F# compiler then assigns the
type of square to be int -> int (that is, a function which takes an int and produces an int ). The call to
printfn is a formatted printing function which uses a format string, similar to C-style programming languages,
parameters which correspond to those specified in the format string, and then prints the result and a new line.
12 squared is 144!
Congratulations! You've created your first F# project in Visual Studio, written an F# function printed the results of
calling that function, and run the project to see some results.
Using F# Interactive
One of the best features of the Visual F# tooling in Visual Studio is the F# Interactive Window. It allows you to send
code over to a process where you can call that code and see the result interactively.
To begin using it, highlight the square function defined in your code. Next, hold the Alt key and press Enter. This
executes the code in the F# Interactive Window. You should see the F# Interactive Window appear with the
following in it:
>
>
This shows the same function signature for the square function, which you saw earlier when you hovered over the
function. Because square is now defined in the F# Interactive process, you can call it with different values:
This executes the function, binds the result to a new name it , and displays the type and value of it . Note that
you must terminate each line with ;; . This is how F# Interactive knows when your function call is finished. You
can also define new functions in F# Interactive:
The above defines a new function, isOdd , which takes an int and checks to see if it's odd! You can call this
function to see what it returns with different inputs. You can call functions within function calls:
You can also use the pipe-forward operator to pipeline the value into the two functions:
Next steps
If you haven't already, check out the Tour of F#, which covers some of the core features of the F# language. It will
give you an overview of some of the capabilities of F#, and provide ample code samples that you can copy into
Visual Studio and run. There are also some great external resources you can use, showcased in the F# Guide.
See also
Visual F#
Tour of F#
F# language reference
Type inference
Symbol and operator reference
Get started with F# in Visual Studio for Mac
8/14/2017 • 5 min to read • Edit Online
F# and the Visual F# tooling are supported in the Visual Studio for Mac IDE. To begin, you should download Visual
Studio for Mac, if you haven't already. This article uses the Visual Studio Community 2017 for Mac, but you can use
F# with the version of your choice.
Installing F#
After downloading Visual Studio for Mac, it will prompt you to choose what you want to install. For the purposes of
this article we will be leaving the defaults. In contrast to Visual Studio for Windows, you do not need to specifically
install F# support. Press "Install" to proceed.
After the install completes, choose "Start Visual Studio". You can also launch it through Finder on macOS.
module HelloSquare
let square x = x * x
[<EntryPoint>]
let main argv =
printfn "%d squared is: %d!" 12 (square 12)
0 // Return an integer exit code
In the previous code sample, a function square has been defined which takes an input named x and multiplies it
by itself. Because F# uses Type Inference, the type of x doesn't need to be specified. The F# compiler understands
the types where multiplication is valid, and will assign a type to x based on how square is called. If you hover
over square , you should see the following:
val square: x:int -> int
This is what is known as the function's type signature. It can be read like this: "Square is a function which takes an
integer named x and produces an integer". Note that the compiler gave square the int type for now - this is
because multiplication is not generic across all types, but rather is generic across a closed set of types. The F#
compiler picked int at this point, but it will adjust the type signature if you call square with a different input type,
such as a float .
Another function, main , is defined, which is decorated with the EntryPoint attribute to tell the F# compiler that
program execution should start there. It follows the same convention as other C-style programming languages,
where command-line arguments can be passed to this function, and an integer code is returned (typically 0 ).
It is in this function that we call the square function with an argument of 12 . The F# compiler then assigns the
type of square to be int -> int (that is, a function which takes an int and produces an int ). The call to
printfn is a formatted printing function which uses a format string, similar to C-style programming languages,
parameters which correspond to those specified in the format string, and then prints the result and a new line.
12 squared is 144!
Congratulations! You've created your first F# project in Visual Studio for Mac, written an F# function printed the
results of calling that function, and run the project to see some results.
Using F# Interactive
One of the best features of the Visual F# tooling in Visual Studio for Mac is the F# Interactive Window. It allows you
to send code over to a process where you can call that code and see the result interactively.
To begin using it, highlight the square function defined in your code. Next, click on Edit from the top level menu.
Next select Send selection to F# Interactive. This executes the code in the F# Interactive Window. Alternatively,
you can right click on the selection and choose Send selection to F# Interactive. You should see the F#
Interactive Window appear with the following in it:
>
>
This shows the same function signature for the square function, which you saw earlier when you hovered over the
function. Because square is now defined in the F# Interactive process, you can call it with different values:
The above defines a new function, isOdd , which takes an int and checks to see if it's odd! You can call this
function to see what it returns with different inputs. You can call functions within function calls:
You can also use the pipe-forward operator to pipeline the value into the two functions:
Next steps
If you haven't already, check out the Tour of F#, which covers some of the core features of the F# language. It will
give you an overview of some of the capabilities of F#, and provide ample code samples that you can copy into
Visual Studio for Mac and run. There are also some great external resources you can use, showcased in the F#
Guide.
See also
Visual F#
Tour of F#
F# language reference
Type inference
Symbol and operator reference
Getting Started with F# in Visual Studio Code with
Ionide
7/29/2017 • 10 min to read • Edit Online
You can write F# in Visual Studio Code with the Ionide plugin, to get a great cross-platform, lightweight IDE
experience with IntelliSense and basic code refactorings. Visit Ionide.io to learn more about the plugin suite.
Prerequisites
F# 4.0 or higher must be installed on your machine to use Ionide.
You must also have git installed and available on your PATH to make use of project templates in Ionide. You can
verify that it is installed correctly by typing git at a command prompt.and pressing Enter.
Windows
If you're on Windows, you have two options for installing F#.
If you've already installed Visual Studio and don't have F#, you can Install the Visual F# Tools. This will install all
the necessary components to write, compile, and execute F# code.
If you prefer not to install Visual Studio, use the following instructions:
1. Install .NET Framework 4.5 or higher if you're running Windows 7. If you're using Windows 8 or higher, you
do not need to do this.
2. Install the Windows SDK for your OS:
Windows 10 SDK
Windows 8.1 SDK
Windows 8 SDK
Windows 7 SDK
3. Install the Microsoft Build Tools 2015. You may also need to install Microsoft Build Tools 2013.
4. Install the Visual F# Tools.
On 64-bit Windows, the compiler and tools are located here:
Ionide automatically detects the compiler and tools, but if it doesn't for some reason (for example, the Visual F#
Tools were installed to a different directory), you can manually add the containing folder (
...\Microsoft SDKs\F#\4.0 ) to your PATH.
macOS
On macOS, Ionide uses Mono. The easiest way to install Mono on macOS is via Homebrew. Simply type the
following into your terminal:
Linux
On Linux, Ionide also uses Mono. If you're on Debian or Ubuntu, you can use the following:
The only plugin required for F# support in Visual Studio Code is Ionide-fsharp. However, you can also install
Ionide-FAKE and to get FAKE support and Ionide-Paket to get Paket support. FAKE and Paket are additonal F#
community tools for building projects and managing dependencies, respectively.
This is powered by the FORGE project. You should see something like this:
NOTE
If you don't see the above, try refreshing templates by running the following command in the Command Palette:
>F#: Refresh Project Templates .
Select "F#: New Project" by hitting Enter, which will take you to this step:
This will select a template for a specific type of project. There are quite a few options here, such as an FsLab
template for Data Science or Suave template for Web Programming. This article uses the classlib template, so
highlight that and hit Enter. You will then reach the following step:
This lets you create the project in a different directory, if you like. Leave it blank for now. It will create the project in
the current directory. Once you press Enter, you will reach the following step:
This lets you name your project. F# uses Pascal case for project names. This article uses ClassLibraryDemo as the
name. Once you've entered the name you want for your project, hit Enter.
If you followed the previous step steps, you should get the Visual Studio Code Workspace on the left-hand side to
look something like this:
This template generates a few things you'll find useful:
1. The F# project itself, underneath the ClassLibraryDemo folder.
2. The correct directory structure for adding packages via Paket .
3. A cross-platform build script with FAKE .
4. The paket.exe executable which can fetch packages and resolve dependencies for you.
5. A .gitignore file if you wish to add this project to Git-based source control.
Open Script.fsx , and add the following code at the end of it:
This function converts a word to a form of Pig Latin. The next step is to evaluate it using F# Interactive (FSI).
Highlight the entire function (it should be 11 lines long). Once it is highlighted, hold the Alt key and hit Enter.
You'll notice a window pop up below, and it should show something like this:
This did three things:
1. It started the FSI process.
2. It sent the code you highlighted over the FSI process.
3. The FSI process evaluated the code you sent over.
Because what you sent over was a function, you can now call that function with FSI! In the interactive window, type
the following:
toPigLatin "banana";;
Now, let's try with a vowel as the first letter. Enter the following:
toPigLatin "apple";;
The function appears to be working as expected. Congratulations, you just wrote your first F# function in Visual
Studio Code and evaluated it with FSI!
NOTE
As you may have noticed, the lines in FSI are terminated with ;; . This is because FSI allows you to enter multiple lines. The
;; at the end lets FSI know when the code is finished.
This states that toPigLatin is a function which takes in a string as input (called word ), and returns another
string . This is known as the type signature of the function, a fundamental piece of F# that's key to understanding
F# code. You'll also notice this if you hover over the function in Visual Studio Code.
In the body of the function, you'll notice two distinct parts:
1. An inner function, called isVowel , which determines if a given character ( c ) is a vowel by checking if it
matches one of the provided patterns via Pattern Matching:
2. An if..then..else expression which checks if the first character is a vowel, and constructs a return value
out of the input characters based on if the first character was a vowel or not:
module PigLatin =
let toPigLatin (word: string) =
let isVowel (c: char) =
match c with
| 'a' | 'e' | 'i' |'o' |'u'
| 'A' | 'E' | 'I' | 'O' | 'U' -> true
|_ -> false
This is one of the many ways you can organize functions in F# code, and a common approach if you also want to
call your code from C# or Visual Basic projects.
Next, open the Script.fsx file again, and delete the entire toPigLatin function, but make sure to keep the
following two lines in the file:
#load "ClassLibraryDemo.fs"
open ClassLibraryDemo
The first line is needed for FSI scripting to load ClassLibraryDemo.fs . The second line is a convenience: omitting it
is optional, but you will need to type open ClassLibraryDemo in an FSI window if you wish to bring the ToPigLatin
module into scope.
Next, in the FSI window, call the function with the PigLatin module that you defined earlier:
Success! You get the same results as before, but now loaded from an F# implementation file. The major difference
here is that F# source files are compiled into assemblies which can be executed anywhere, not just in FSI.
Summary
In this article, you've learned:
1. How to set up Visual Studio Code with Ionide.
2. How to create your first F# project with Ionide.
3. How to use F# Scripting to write your first F# function in Ionide and then execute it in FSI.
4. How to migrate your script code to F# source and then call that code from FSI.
You're now equipped to write much more F# code using Visual Studio Code and Ionide.
Troubleshooting
Here are a few ways you can troubleshoot certain problems that you might run into:
1. To get the code editing features of Ionide, your F# files need to be saved to disk and inside of a folder that is
open in the Visual Studio Code workspace.
2. If you've made changes to your system or installed Ionide prerequisites with Visual Studio Code open, restart
Visual Studio Code.
3. Check that you can use the F# compiler and F# interactive from the command line without a fully-qualified
path. You can do so by typing fsc in a command line for the F# compiler, and fsi or fsharpi for the Visual
F# tools on Windows and Mono on Mac/Linux, respectively.
4. If you have invalid characters in your project directories, Ionide might not work. Rename your project
directories if this is the case.
5. If none of the Ionide commands are working, check your Visual Studio Code keybindings to see if you're
overriding them by accident.
6. If Ionide is broken on your machine and none of the above has fixed your problem, try removing the
ionide-fsharp directory on your machine and reinstall the plugin suite.
Ionide is an open source project built and maintained by members of the F# community. Please report issues and
feel free to contribute at the Ionide-VSCode: FSharp GitHub repository.
If you have an issue to report, please follow the instructions for getting logs to use when reporting an issue.
You can also ask for further help from the Ionide developers and F# community in the Ionide Gitter channel.
Next steps
To learn more about F# and the features of the language, check out Tour of F#.
See also
Tour of F#
F# Language Reference
Functions
Modules
Namespaces
Ionide-VSCode: FSharp
Get started with F# with the .NET Core CLI
7/29/2017 • 2 min to read • Edit Online
This article covers how you can get started with using F# on .NET Core. It will go through building a multi-project
solution with a Class Library that is called by a Console Application.
Prerequisites
To begin, you must install the .NET Core SDK 1.0 or later. There is no need to uninstall a previous version of the
.NET Core SDK, as it supports side-by-side installations.
This article assumes that you know how to use a command line and have a preferred text editor. If you don't
already use it, Visual Studio Code is a great option as a text editor for F#. To get awesome features like IntelliSense,
better syntax highlighting, and more, you can download the Ionide Extension.
FSNetCore
├── FSNetCore.sln
Change directories to FSNetCore and start adding projects to the solution folder.
Writing a Class library
Use the dotnet new command, create a Class Library project in the src folder named Library.
└── FSNetCore
├── FSNetCore.sln
└── src
└── Library
├── Library.fs
└── Library.fsproj
open Newtonsoft.Json
Add the Library project to the FSNetCore solution using the dotnet sln add command:
Restore the NuGet dependencies, dotnet restore and run dotnet build to build the project.
Writing a Console Application which Consumes the Class Library
Use the dotnet new command, create a Console app in the src folder named App.
└── FSNetCore
├── FSNetCore.sln
└── src
├── App
│ ├── App.fsproj
│ ├── Program.fs
└── Library
├── Library.fs
└── Library.fsproj
open System
open Library
[<EntryPoint>]
let main argv =
printfn "Nice command-line arguments! Here's what JSON.NET has to say about them:"
argv
|> Array.map getJsonNetJson
|> Array.iter (printfn "%s")
Add the App project to the FSNetCore solution using the dotnet sln add command:
dotnet sln add src/App/App.fsproj
Restore the NuGet dependencies, dotnet restore and run dotnet build to build the project.
Change directory to the src/App console project and run the project passing Hello World as arguments.
cd src/App
dotnet run Hello World
Nice command-line arguments! Here's what JSON.NET has to say about them:
NOTE
This article currently describes the experience for Windows only. It will be rewritten.
NOTE
The API reference link will take you to MSDN. The docs.microsoft.com API reference is not complete.
F# Interactive (fsi.exe) is used to run F# code interactively at the console, or to execute F# scripts. In other words,
F# interactive executes a REPL (Read, Evaluate, Print Loop) for the F# language.
To run F# Interactive from the console, run fsi.exe. You will find fsi.exe in "c:\Program Files (x86)\Microsoft
SDKs\F#<version>\Framework<version>\". For information about command line options available, see F#
Interactive Options.
To run F# Interactive through Visual Studio, you can click the appropriate toolbar button labeled F# Interactive, or
use the keys Ctrl+Alt+F. Doing this will open the interactive window, a tool window running an F# Interactive
session. You can also select some code that you want to run in the interactive window and hit the key combination
ALT+ENTER. F# Interactive starts in a tool window labeled F# Interactive. When you use this key combination,
make sure that the editor window has the focus.
Whether you are using the console or Visual Studio, a command prompt appears and the interpreter awaits your
input. You can enter code just as you would in a code file. To compile and execute the code, enter two semicolons
(;;) to terminate a line or several lines of input.
F# Interactive attempts to compile the code and, if successful, it executes the code and prints the signature of the
types and values that it compiled. If errors occur, the interpreter prints the error messages.
Code entered in the same session has access to any constructs entered previously, so you can build up programs.
An extensive buffer in the tool window allows you to copy the code into a file if needed.
When run in Visual Studio, F# Interactive runs independently of your project, so, for example, you cannot use
constructs defined in your project in F# Interactive unless you copy the code for the function into the interactive
window.
If you have a project open that references some libraries, you can reference these in F# Interactive through
Solution Explorer. To reference a library in F# Interactive, expand the References node, open the shortcut menu
for the library, and choose Send to F# Interactive.
You can control the F# Interactive command line arguments (options) by adjusting the settings. On the Tools
menu, select Options..., and then expand F# Tools. The two settings that you can change are the F# Interactive
options and the 64-bit F# Interactive setting, which is relevant only if you are running F# Interactive on a 64-bit
machine. This setting determines whether you want to run the dedicated 64-bit version of fsi.exe or fsianycpu.exe,
which uses the machine architecture to determine whether to run as a 32-bit or 64-bit process.
Scripting with F#
Scripts use the file extension .fsx or .fsscript. Instead of compiling source code and then later running the
compiled assembly, you can just run fsi.exe and specify the filename of the script of F# source code, and F#
interactive reads the code and executes it in real time.
DIRECTIVE DESCRIPTION
#r References an assembly.
When you specify files or paths in F# Interactive, a string literal is expected. Therefore, files and paths must be in
quotation marks, and the usual escape characters apply. Also, you can use the @ character to cause F# Interactive
to interpret a string that contains a path as a verbatim string. This causes F# Interactive to ignore any escape
characters.
One of the differences between compiled and interactive mode is the way you access command line arguments. In
compiled mode, use System.Environment.GetCommandLineArgs. In scripts, use fsi.CommandLineArgs.
The following code illustrates how to create a function that reads the command line arguments in a script and also
demonstrates how to reference another assembly from a script. The first code file, MyAssembly.fs, is the code for
the assembly being referenced. Compile this file with the command line: fsc -a MyAssembly.fs and then execute
the second file as a script with the command line: fsi --exec file1.fsx test
// MyAssembly.fs
module MyAssembly
let myFunction x y = x + 2 * y
// file1.fsx
#r "MyAssembly.dll"
Related Topics
TITLE DESCRIPTION
F# Interactive Options Describes command line syntax and options for the F#
Interactive, fsi.exe.
F# Interactive Library Reference Describes library functionality available when executing code
in F# interactive.
F# Interactive Options
7/29/2017 • 3 min to read • Edit Online
NOTE
This article currently describes the experience for Windows only. It will be rewritten.
This topic describes the command-line options supported by F# Interactive, fsi.exe . F# Interactive accepts many
of the same command line options as the F# compiler, but also accepts some additional options.
OPTION DESCRIPTION
-g[+|-]
-g:[full|pdbonly]
OPTION DESCRIPTION
--load:<filename> Compiles the given source code at startup and loads the
compiled F# constructs into the session. If the target source
contains scripting directives such as #use or #load, then you
must use --use or #use instead of --load or #load.
--use:<filename> Tells the interpreter to use the given file on startup as initial
input.
--utf8output Same as the fsc.exe compiler option. For more information, see
Compiler Options.
Related Topics
TITLE DESCRIPTION
Compiler Options Describes command line options available for the F# compiler,
fsc.exe.
Type Providers
7/29/2017 • 3 min to read • Edit Online
NOTE
This guide was written from F# 3.0 and will be updated. See FSharp.Data for up-to-date, cross-platform type providers.
An F# type provider is a component that provides types, properties, and methods for use in your program. Type
providers are a significant part of F# 3.0 support for information-rich programming. The key to information-rich
programming is to eliminate barriers to working with diverse information sources found on the Internet and in
modern enterprise environments. One significant barrier to including a source of information into a program is
the need to represent that information as types, properties, and methods for use in a programming language
environment. Writing these types manually is very time-consuming and difficult to maintain. A common
alternative is to use a code generator which adds files to your project; however, the conventional types of code
generation do not integrate well into exploratory modes of programming supported by F# because the generated
code must be replaced each time a service reference is adjusted.
The types provided by F# type providers are usually based on external information sources. For example, an F#
type provider for SQL will provide the types, properties, and methods you need to work directly with the tables of
any SQL database you have access to. Similarly, a type provider for WSDL web services will provide the types,
properties, and methods you need to work directly with any WSDL web service.
The set of types, properties, and methods provided by an F# type provider can depend on parameters given in
program code. For example, a type provider can provide different types depending on a connection string or a
service URL. In this way, the information space available by means of a connection string or URL is directly
integrated into your program. A type provider can also ensure that groups of types are only expanded on
demand; that is, they are expanded if the types are actually referenced by your program. This allows for the direct,
on-demand integration of large-scale information spaces such as online data markets in a strongly typed way.
F# contains several built-in type providers for commonly used Internet and enterprise data services. These type
providers give simple and regular access to SQL relational databases and network-based OData and WSDL
services and support the use of F# LINQ queries against these data sources.
Where necessary, you can create your own custom type providers, or reference type providers that have been
created by others. For example, assume your organization has a data service providing a large and growing
number of named data sets, each with its own stable data schema. You may choose to create a type provider that
reads the schemas and presents the latest available data sets to the programmer in a strongly typed way.
Related Topics
TITLE DESCRIPTION
Walkthrough: Accessing a SQL Database by Using Type Explains how to use the SqlDataConnection type provider to
Providers access the tables and stored procedures of a SQL database
based on a connection string for a direct connection to a
database. The access uses a LINQ to SQL mapping.
TITLE DESCRIPTION
Walkthrough: Accessing a SQL Database by Using Type Explains how to use the SqlEntityConnection type provider to
Providers and Entities access the tables and stored procedures of a SQL database,
based on a connection string for a direct connection to a
database. The access uses a LINQ to Entities mapping. This
method works with any database but the example
demonstrated is SQL Server.
Walkthrough: Accessing an OData Service by Using Type Explains how to use the ODataService type provider to access
Providers an OData service in a strongly typed way based on a service
URL.
Walkthrough: Accessing a Web Service by Using Type Explains how to use the WsdlService type provider to access a
Providers WSDL web service in a strongly typed way based on a service
URL.
Walkthrough: Generating F# Types from a DBML File Explains how to use the DbmlFile type provider to access the
tables and stored procedures of a SQLdatabase, based on a
DBML file giving a Linq to SQL database schema specification.
Walkthrough: Generating F# Types from an EDMX Schema Explains how to use the EdmxFile type provider to access the
File tables and stored procedures of a SQL database, based on an
EDMX file giving an Entity Framework schema specification.
Tutorial: Creating a Type Provider Provides information on writing your own custom type
providers.
Troubleshooting Type Providers Provides information about common problems that can arise
when working with type providers and includes suggestions
for solutions.
See Also
F# Language Reference
Visual F#
Walkthrough: Accessing a SQL Database by Using
Type Providers
7/29/2017 • 15 min to read • Edit Online
NOTE
This guide was written for F# 3.0 and will be updated. See FSharp.Data for up-to-date, cross-platform type providers.
NOTE
The API reference links will take you to MSDN. The docs.microsoft.com API reference is not complete.
This walkthrough explains how to use the SqlDataConnection (LINQ to SQL) type provider that is available in F#
3.0 to generate types for data in a SQL database when you have a live connection to a database. If you do not have
a live connection to a database, but you do have a LINQ to SQL schema file (DBML file), see Walkthrough:
Generating F# Types from a DBML File.
This walkthrough illustrates the following tasks. These tasks must be performed in this order for the walkthrough
to succeed:
Preparing a test database
Creating the project
Setting up a type provider
Querying the data
Working with nullable fields
Calling a stored procedure
Updating the database
Executing Transact-SQL code
Using the full data context
Deleting data
Create a test database (as needed)
open System
open System.Data
open System.Data.Linq
open Microsoft.FSharp.Data.TypeProviders
open Microsoft.FSharp.Linq
4. As with most F# programs, you can execute the code in this walkthrough as a compiled program, or you can
run it interactively as a script. If you prefer to use scripts, open the shortcut menu for the project node, select
Add New Item, add an F# script file, and add the code in each step to the script. You will need to add the
following lines at the top of the file to load the assembly references.
#r "System.Data.dll"
#r "FSharp.Data.TypeProviders.dll"
#r "System.Data.Linq.dll"
You can then select each block of code as you add it and press Alt+Enter to run it in F# Interactive.
Now you have a type, dbSchema , which is a parent type that contains all the generated types that represent
database tables. You also have an object, db , which has as its members all the tables in the database. The table
names are properties, and the type of these properties is generated by the F# compiler. The types themselves
appear as nested types under dbSchema.ServiceTypes . Therefore, any data retrieved for rows of these tables is an
instance of the appropriate type that was generated for that table. The name of the type is ServiceTypes.Table1 .
To familiarize yourself with how the F# language interprets queries into SQL queries, review the line that sets the
Log property on the data context.
To further explore the types created by the type provider, add the following code.
Hover over table1 to see its type. Its type is System.Data.Linq.Table<dbSchema.ServiceTypes.Table1> and the
generic argument implies that the type of each row is the generated type, dbSchema.ServiceTypes.Table1 . The
compiler creates a similar type for each table in the database.
let query1 =
query {
for row in db.Table1 do
select row
}
query1 |> Seq.iter (fun row -> printfn "%s %d" row.Name row.TestData1)
The appearance of the word query indicates that this is a query expression, a type of computation expression that
generates a collection of results similar of a typical database query. If you hover over query, you will see that it is
an instance of Linq.QueryBuilder Class, a type that defines the query computation expression. If you hover over
query1 , you will see that it is an instance of System.Linq.IQueryable . As the name suggests,
System.Linq.IQueryable represents data that may be queried, not the result of a query. A query is subject to lazy
evaluation, which means that the database is only queried when the query is evaluated. The final line passes the
query through Seq.iter . Queries are enumerable and may be iterated like sequences. For more information, see
Query Expressions.
2. Now add a query operator to the query. There are a number of query operators available that you can use to
construct more complex queries. This example also shows that you can eliminate the query variable and use a
pipeline operator instead.
query {
for row in db.Table1 do
where (row.TestData1 > 2)
select row
} |> Seq.iter (fun row -> printfn "%d %s" row.TestData1 row.Name)
4. In real-world code, the parameters in your query are usually values or variables, not compile-time constants.
Add the following code that wraps a query in a function that takes a parameter, and then calls that function with
the value 10.
findData 10 |> Seq.iter (fun row -> printfn "Found row: %d %d %f %s" row.Id row.TestData1 row.TestData2
row.Name)
query {
for row in db.Table2 do
// Use a nullable operator ?>
where (row.TestData1 ?> 2)
select row
} |> Seq.iter (fun row -> printfn "%d %s" (row.TestData1.GetValueOrDefault()) row.Name)
let callProcedure1 a b =
let results = testdb.Procedure1(nullable a, nullable b)
for result in results do
printfn "%d" (result.TestData1.GetValueOrDefault())
results.ReturnValue :?> int
let newValues =
[ for i in [1 .. 10] ->
new dbSchema.ServiceTypes.Table3(Id = 700 + i,
Name = "Testing" + i.ToString(),
Data = i) ]
try
db.DataContext.SubmitChanges()
printfn "Successfully inserted new rows."
with
| exn -> printfn "Exception:\n%s" exn.Message
try
db.DataContext.SubmitChanges()
printfn "Successfully deleted all pending rows."
with
| exn -> printfn "Exception:\n%s" exn.Message
try
db.DataContext.ExecuteCommand("INSERT INTO Table3 (Id, Name, Data) VALUES (102, 'Testing', 55)") |> ignore
with
| exn -> printfn "Exception:\n%s" exn.Message
dbConnection.Open()
try
let result1 = fullContext.ExecuteCommand("INSERT INTO Table3 (Id, Name, Data) VALUES (102, 'A', 55)")
printfn "ExecuteCommand Result: %d" result1
let result2 = fullContext.ExecuteCommand("INSERT INTO Table3 (Id, Name, Data) VALUES (103, 'B', -2)")
printfn "ExecuteCommand Result: %d" result2
if (result1 <> 1 || result2 <> 1) then
transaction.Rollback()
printfn "Rolled back creation of two new rows."
else
transaction.Commit()
printfn "Successfully committed two new rows."
with
| exn ->
transaction.Rollback()
printfn "Rolled back creation of two new rows due to exception:\n%s" exn.Message
dbConnection.Close()
Deleting data
This step shows you how to delete rows from a data table.
To delete rows from the database
Now, clean up any added rows by writing a function that deletes rows from a specified table, an instance of the
System.Data.Linq.Table class. Then write a query to find all the rows that you want to delete, and pipe the results
of the query into the deleteRows function. This code takes advantage of the ability to provide partial application of
function arguments.
let deleteRowsFrom (table:Table<_>) rows =
table.DeleteAllOnSubmit(rows)
query {
for rows in db.Table3 do
where (rows.Id > 10)
select rows
} |> deleteRowsFrom db.Table3
db.DataContext.SubmitChanges()
printfn "Successfully deleted rows with Id greater than 10 in Table3."
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
USE [master];
GO
USE MyDatabase;
GO
USE MyDatabase
See Also
Type Providers
SqlDataConnection Type Provider
Walkthrough: Generating F# Types from a DBML File
Query Expressions
LINQ to SQL
SqlMetal.exe (Code Generation Tool)
Walkthrough: Accessing a SQL Database by Using
Type Providers and Entities
7/29/2017 • 6 min to read • Edit Online
NOTE
This guide was written for F# 3.0 and will be updated. See FSharp.Data for up-to-date, cross-platform type providers.
NOTE
The API reference links will take you to MSDN. The docs.microsoft.com API reference is not complete.
This walkthrough for F# 3.0 shows you how to access typed data for a SQL database based on the ADO.NET Entity
Data Model. This walkthrough shows you how to set up the F# SqlEntityConnection type provider for use with a
SQL database, how to write queries against the data, how to call stored procedures on the database, as well as how
to use some of the ADO.NET Entity Framework types and methods to update the database.
This walkthrough illustrates the following tasks, which you should perform in this order for the walkthrough to
succeed:
Create the School database
Create and configure an F# project
Configure the type provider and connect to the Entity Data Model
Query the database
Updating the database
Prerequisites
You must have access to a server that's running SQL Server where you can create a database to complete these
steps.
open System.Data.Linq
open System.Data.Entity
open Microsoft.FSharp.Data.TypeProviders
6. To run the code in this walkthrough interactively as a script instead of as a compiled program, open the shortcut
menu for the project node, choose Add New Item, add an F# script file, and then add the code in each step to
the script. To load the assembly references, add the following lines.
#r "System.Data.Entity.dll"
#r "FSharp.Data.TypeProviders.dll"
#r "System.Data.Linq.dll"
7. Highlight each block of code as you add it, and choose the Alt + Enter keys to run it in F# Interactive.
Configure the type provider, and connect to the Entity Data Model
In this step, you set up a type provider with a data connection and obtain a data context that allows you to work
with data.
To configure the type provider, and connect to the Entity Data Model
1. Enter the following code to configure the SqlEntityConnection type provider that generates F# types based on
the Entity Data Model that you created previously. Instead of the full EDMX connection string, use only the SQL
connection string.
This action sets up a type provider with the database connection that you created earlier. The property
MultipleActiveResultSets is needed when you use the ADO.NET Entity Framework because this property allows
multiple commands to execute asynchronously on the database in one connection, which can occur frequently in
ADO.NET Entity Framework code. For more information, see Multiple Active Result Sets (MARS).
2. Get the data context, which is an object that contains the database tables as properties and the database stored
procedures and functions as methods.
query {
for course in context.Courses do
select course
} |> Seq.iter (fun course -> printfn "%s" course.Title)
query {
for person in context.People do
select person
} |> Seq.iter (fun person -> printfn "%s %s" person.FirstName person.LastName)
// A helper function.
let nullable value = new System.Nullable<_>(value)
fullContext.AddObject("OfficeAssignments", newOffice)
fullContext.CommandTimeout <- nullable 1000
fullContext.SaveChanges() |> printfn "Saved changes: %d object(s) modified."
fullContext.DeleteObject(person))
deleteInstructor("Parker", "Darren")
WARNING
When you use a query expression, you must remember that the query is subject to lazy evaluation. Therefore, the database is
still open for reading during any chained evaluations, such as in the lambda expression blocks after each query expression.
Any database operation that explicitly or implicitly uses a transaction must occur after the read operations have completed.
Next Steps
Explore other query options by reviewing the query operators available in Query Expressions, and also review the
ADO.NET Entity Framework to understand what functionality is available to you when you use this type provider.
See Also
Type Providers
SqlEntityConnection Type Provider
Walkthrough: Generating F# Types from an EDMX Schema File
ADO.NET Entity Framework
.edmx File Overview
EDM Generator (EdmGen.exe)
Walkthrough: Accessing an OData Service by Using
Type Providers
7/29/2017 • 5 min to read • Edit Online
NOTE
This guide was written for F# 3.0 and will be updated. See FSharp.Data for up-to-date, cross-platform type providers.
NOTE
The API reference links will take you to MSDN. The docs.microsoft.com API reference is not complete.
OData, meaning Open Data Protocol, is a protocol for transferring data over the Internet. Many data providers
expose access to their data by publishing an OData web service. You can access data from any OData source in F#
3.0 using data types that are automatically generated by the ODataService type provider. For more information
about OData, see https://msdn.microsoft.com/library/da3380cc-f6da-4c6c-bdb2-bb86afa59d62.
This walkthrough shows you how to use the F# ODataService type provider to generate client types for an OData
service and query data feeds that the service provides.
This walkthrough illustrates the following tasks, which you should perform in this order for the walkthrough to
succeed:
Configuring a client project for an OData service
Accessing OData types
Querying an OData service
Verifying the OData requests
let db = Northwind.GetDataContext()
let fullContext = Northwind.ServiceTypes.NorthwindEntities()
In this example, you have invoked the F# type provider and instructed it to create a set of types that are based on
the OData URI that you specified. Two objects are available that contain information about the data; one is a
simplified data context, db in the example. This object contains only the data types that are associated with the
database, which include types for tables or feeds. The other object, fullContext in this example, is an instance of
System.Data.Linq.DataContext and contains many additional properties, methods, and events.
query {
for customer in db.Customers do
select customer
} |> Seq.iter (fun customer ->
printfn "ID: %s\nCompany: %s" customer.CustomerID customer.CompanyName
printfn "Contact: %s\nAddress: %s" customer.ContactName customer.Address
printfn " %s, %s %s" customer.City customer.Region customer.PostalCode
printfn "%s\n" customer.Phone)
2. Specify the fields or columns that you want by using a tuple after the select keyword.
query {
for cat in db.Categories do
select (cat.CategoryID, cat.CategoryName, cat.Description)
} |> Seq.iter (fun (id, name, description) ->
printfn "ID: %d\nCategory: %s\nDescription: %s\n" id name description)
4. Specify a substring condition to the query by using the System.String.Contains(System.String) method. The
following query returns all products that have "Chef" in their names. Also notice the use of
System.Nullable<'T>.GetValueOrDefault() . The UnitPrice is a nullable value, so you must either get the value by
using the Value property, or you must call System.Nullable<'T>.GetValueOrDefault() .
query {
for product in db.Products do
where (product.ProductName.Contains("Chef"))
select product
} |> Seq.iter (fun product ->
printfn "ID: %d Product: %s" product.ProductID product.ProductName
printfn "Price: %M\n" (product.UnitPrice.GetValueOrDefault()))
5. Use the System.String.EndsWith(System.String) method to specify that a string ends with a certain substring.
query {
for product in db.Products do
where (product.ProductName.EndsWith("u"))
select product
} |> Seq.iter (fun product ->
printfn "ID: %d Product: %s" product.ProductID product.ProductName
printfn "Price: %M\n" (product.UnitPrice.GetValueOrDefault()))
// Open this module to use the nullable operators ?> and ?<.
open Microsoft.FSharp.Linq.NullableOperators
salesIn1997
|> Seq.iter (fun sales ->
printfn "Category: %s Sales: %M" sales.CategoryName (sales.CategorySales.GetValueOrDefault()))
The operators ?> and ?< are nullable operators. You can use a full set of nullable equality and comparison
operators. For more information, see Linq.NullableOperators Module.
7. Use the sortBy query operator to specify ordering, and use thenBy to specify another level of ordering. Notice
also the use of a tuple in the select part of the query. Therefore, the query has a tuple as an element type.
printfn "Freight for some orders: "
query {
for order in db.Orders do
sortBy (order.OrderDate.Value)
thenBy (order.OrderID)
select (order.OrderDate, order.OrderID, order.Customer.CompanyName)
} |> Seq.iter (fun (orderDate, orderID, company) ->
printfn "OrderDate: %s" (orderDate.GetValueOrDefault().ToString())
printfn "OrderID: %d Company: %s\n" orderID company)
8. Ignore a specified number of records by using the skip operator, and use the take operator to specify a number
of records to return. In this way, you can implement paging on data feeds.
query {
for employee in db.Employees do
take 2
select employee
} |> Seq.iter (fun employee ->
printfn "Name: %s ID: %d" (employee.FirstName + " " + employee.LastName)
(employee.EmployeeID))
query {
for employee in db.Employees do
skip 2
take 2
select employee
} |> Seq.iter (fun employee ->
printfn "Name: %s ID: %d" (employee.FirstName + " " + employee.LastName)
(employee.EmployeeID))
See Also
Query Expressions
LINQ Considerations (WCF Data Services)
ODataService Type Provider (F#)
Walkthrough: Accessing a Web Service by Using Type
Providers
7/29/2017 • 3 min to read • Edit Online
NOTE
This guide was written for F# 3.0 and will be updated. See FSharp.Data for up-to-date, cross-platform type providers.
NOTE
The API reference links will take you to MSDN. The docs.microsoft.com API reference is not complete.
This walkthrough shows you how to use the Web Services Description Language (WSDL) type provider that is
available in F# 3.0 to access a WSDL service. In other .NET languages, you generate the code to access the web
service by calling svcutil.exe, or by adding a web reference in, for example, a C# project to get Visual Studio to call
svcutil.exe for you. In F#, you have the additional option of using the WSDL type provider, so as soon as you write
the code that creates the WsdlService type, the types are generated and become available. This process relies on the
service being available when you are writing the code.
This walkthrough illustrates the following tasks. You must complete them in this order for the walkthrough to
succeed:
Creating the project
Configuring the type provider
Calling the web service, and processing the results
open System
open System.ServiceModel
open Microsoft.FSharp.Linq
open Microsoft.FSharp.Data.TypeProviders
2. Add the following line of code to invoke the type provider with a web service. In this example, use the
TerraServer web service.
A red squiggle appears under this line of code if the service URI is misspelled or if the service itself is down or isn’t
performing. If you point to the code, an error message describes the problem. You can find the same information in
the Error List window or in the Output Window after you build.
There are two ways to specify configuration settings for a WSDL connection, by using the app.config file for the
project, or by using the static type parameters in the type provider declaration. You can use svcutil.exe to generate
appropriate configuration file elements. For more information about using svcutil.exe to generate configuration
information for a web service, see ServiceModel Metadata Utility Tool (Svcutil.exe). For a full description of the
static type parameters for the WSDL type provider, see WsdlService Type Provider.
try
let terraClient = TerraService.GetTerraServiceSoap ()
let myPlace = new TerraService.ServiceTypes.msrmaps.com.Place(City = "Redmond", State = "Washington", Country
= "United States")
let myLocation = terraClient.ConvertPlaceToLonLatPt(myPlace)
printfn "Redmond Latitude: %f Longitude: %f" (myLocation.Lat) (myLocation.Lon)
with
| :? ServerTooBusyException as exn ->
let innerMessage =
match (exn.InnerException) with
| null -> ""
| innerExn -> innerExn.Message
printfn "An exception occurred:\n %s\n %s" exn.Message innerMessage
| exn -> printfn "An exception occurred: %s" exn.Message
Notice that you create the data types that are needed for the web service, such as Place and Location, as nested
types under the WsdlService type TerraService.
See Also
WsdlService Type Provider
Type Providers
Walkthrough: Generating F# Types from a DBML File
7/29/2017 • 4 min to read • Edit Online
NOTE
This guide was written for F# 3.0 and will be updated. See FSharp.Data for up-to-date, cross-platform type providers.
NOTE
The API reference links will take you to MSDN. The docs.microsoft.com API reference is not complete.
This walkthrough for F# 3.0 describes how to create types for data from a database when you have schema
information encoded in a .dbml file. LINQ to SQL uses this file format to represent database schema. You can
generate a LINQ to SQL schema file in Visual Studio by using the Object Relational (O/R) Designer. For more
information, see O/R Designer Overview and Code Generation in LINQ to SQL.
The Database Markup Language (DBML) type provider allows you to write code that uses types based on a
database schema without requiring you to specify a static connection string at compile time. That can be useful if
you need to allow for the possibility that the final application will use a different database, different credentials, or
a different connection string than the one you use to develop the application. If you have a direct database
connection that you can use at compile time and this is the same database and credentials that you will eventually
use in your built application, you can also use the SQLDataConnection type provider. For more information, see
Walkthrough: Accessing a SQL Database by Using Type Providers.
This walkthrough illustrates the following tasks. They should be completed in this order for the walkthrough to
succeed:
Creating a .dbml file
Creating and setting up an F# project
Configuring the type provider and generating the types
Querying the database
Prerequisites
Creating a .dbml file
If you do not have a database to test on, create one by following the instructions at the bottom of Walkthrough:
Accessing a SQL Database by Using Type Providers. If you follow these instructions, you will create a database
called MyDatabase that contains a few simple tables and stored procedures on your SQL Server.
If you already have a .dbml file, you can skip to the section, Create and Set Up an F# Project. Otherwise, you can
create a .dbml file given an existing SQL database and by using the command-line tool SqlMetal.exe.
To create a .dbml file by using SqlMetal.exe
1. Open a Developer Command Prompt.
2. Ensure that you have access to SqlMetal.exe by entering SqlMetal.exe /? at the command prompt.
SqlMetal.exe is typically installed under the Microsoft SDKs folder in Program Files or Program Files
(x86).
3. Run SqlMetal.exe with the following command-line options. Substitute an appropriate path in place of
c:\destpath to create the .dbml file, and insert appropriate values for the database server, instance name,
and database name.
NOTE
If SqlMetal.exe has trouble creating the file due to permissions issues, change the current directory to a folder that you have
write access to.
4. You can also look at the other available command-line options. For example, there are options you can use if
you want views and SQL functions included in the generated types. For more information, see SqlMetal.exe
(Code Generation Tool).
open Microsoft.FSharp.Data.TypeProviders
open Microsoft.FSharp.Data.TypeProviders
query {
for row in db.Table1 do
where (row.TestData1 > 2)
select row
} |> Seq.iter (fun row -> printfn "%d %s" row.TestData1 row.Name)
Next Steps
You can proceed to use other query expressions, or get a database connection from the data context and perform
normal ADO.NET data operations. For additional steps, see the sections after "Query the Data" in Walkthrough:
Accessing a SQL Database by Using Type Providers.
See Also
DbmlFile Type Provider
Type Providers
Walkthrough: Accessing a SQL Database by Using Type Providers
SqlMetal.exe (Code Generation Tool)
Query Expressions
Walkthrough: Generating F# Types from an EDMX
Schema File
7/29/2017 • 8 min to read • Edit Online
NOTE
This guide was written for F# 3.0 and will be updated. See FSharp.Data for up-to-date, cross-platform type providers.
NOTE
The API reference links will take you to MSDN. The docs.microsoft.com API reference is not complete.
This walkthrough for F# 3.0 shows you how to create types for data that is represented by the Entity Data Model
(EDM), the schema for which is specified in an .edmx file. This walkthrough also shows how to use the EdmxFile
type provider. Before you begin, consider whether a SqlEntityConnection type provider is a more appropriate type
provider option. The SqlEntityConnection type provider works best for scenarios where you have a live database
that you can connect to during the development phase of your project, and you do not mind specifying the
connection string at compile time. However, this type provider is also limited in that it doesn't expose as much
database functionality as the EdmxFile type provider. Also, if you don't have a live database connection for a
database project that uses the Entity Data Model, you can use the .edmx file to code against the database. When
you use the EdmxFile type provider, the F# compiler runs EdmGen.exe to generate the types that it provides.
This walkthrough illustrates the following tasks, which you must perform in this order for the walkthrough to
succeed:
Creating an EDMX file
Creating the project
Finding or creating the entity data model connection string
Configuring the type provider
Querying the data
Calling a stored procedure
Prerequisites
Creating an EDMX file
If you already have an EDMX file, you can skip this step.
To create an EDMX file
If you don't already have an EDMX file, you can follow the instructions at the end of this walkthrough in the step
Configuring the Entity Data Model.
open System.Data.Linq
open System.Data.Entity
open Microsoft.FSharp.Data.TypeProviders
Finding or creating the connection string for the Entity Data Model
The connection string for the Entity Data Model (EDMX connection string) includes not only the connection string
for the database provider but also additional information. For example, EDMX connection string for a simple SQL
Server database resembles the following code.
For more information about EDMX connection strings, see Connection Strings.
To find or create the connection string for the Entity Data Model
1. EDMX connection strings can be difficult to generate by hand, so you can save time by generating it
programmatically. If you know your EDMX connection string, you can bypass this step and simply use that
string in the next step. If not, use the following code to generate the EDMX connection string from a database
connection string that you provide.
open System
open System.Data
open System.Data.SqlClient
open System.Data.EntityClient
open System.Data.Metadata.Edm
let getEDMConnection(dbConnectionString) =
let dbConnection = new SqlConnection(dbConnectionString)
let resourceArray = [| "res://*/" |]
let assemblyList = [| System.Reflection.Assembly.GetCallingAssembly() |]
let metaData = MetadataWorkspace(resourceArray, assemblyList)
new EntityConnection(metaData, dbConnection)
use edmConnection =
getEDMConnection("Data Source=SERVER\instance;Initial Catalog=School;Integrated Security=true;")
use context = new edmx.SchoolModel.SchoolEntities(edmConnection)
query {
for course in context.Courses do
select course
} |> Seq.iter (fun course -> printfn "%s" course.Title)
query {
for person in context.Person do
select person
} |> Seq.iter (fun person -> printfn "%s %s" person.FirstName person.LastName)
query {
for person in context.People do
where (person.LastName = lastName &&
person.FirstName = firstName)
exactlyOne
} |> (fun person ->
context.UpdatePerson(nullable person.PersonID, person.LastName, person.FirstName, nullable
hireDate, person.EnrollmentDate))
The result is 1 if you succeed. Notice that exactlyOne is used in the query expression to ensure that only one result
is returned; otherwise, an exception is thrown. Also, to work with nullable values more easily, you can use the
simple nullable function that's defined in this code to create a nullable value out of an ordinary value.
Next Steps
Explore other queries by looking at the available query operators as listed in Query Expressions.
See Also
Type Providers
EdmxFile Type Provider
Walkthrough: Accessing a SQL Database by Using Type Providers and Entities
Entity Framework
.edmx File Overview
EDM Generator (EdmGen.exe)
Tutorial: Creating a Type Provider
7/29/2017 • 36 min to read • Edit Online
NOTE
This guide was written for F# 3.0 and will be updated.
The type provider mechanism in F# 3.0 is a significant part of its support for information rich programming. This
tutorial explains how to create your own type providers by walking you through the development of several simple
type providers to illustrate the basic concepts. For more information about the type provider mechanism in F#, see
Type Providers.
F# 3.0 contains several built-in type providers for commonly used Internet and enterprise data services. These type
providers give simple and regular access to SQL relational databases and network-based OData and WSDL
services. These providers also support the use of F# LINQ queries against these data sources.
Where necessary, you can create custom type providers, or you can reference type providers that others have
created. For example, your organization could have a data service that provides a large and growing number of
named data sets, each with its own stable data schema. You can create a type provider that reads the schemas and
presents the current data sets to the programmer in a strongly typed way.
namespace Samples.HelloWorldTypeProvider
type Type1 =
/// This is a static property.
static member StaticProperty : string
type Type2 =
…
…
type Type100 =
…
Note that the set of types and members provided is statically known. This example doesn't leverage the ability of
providers to provide types that depend on a schema. The implementation of the type provider is outlined in the
following code, and the details are covered in later sections of this topic.
WARNING
There may be some small naming differences between this code and the online samples.
namespace Samples.FSharp.HelloWorldTypeProvider
open System
open System.Reflection
open Samples.FSharp.ProvidedTypes
open Microsoft.FSharp.Core.CompilerServices
open Microsoft.FSharp.Quotations
// This type defines the type provider. When compiled to a DLL, it can be added
// as a reference to an F# command-line compilation, script, or project.
[<TypeProvider>]
type SampleTypeProvider(config: TypeProviderConfig) as this =
[<assembly:TypeProviderAssembly>]
do()
To use this provider, open a separate instance of Visual Studio 2012, create an F# script, and then add a reference
to the provider from your script by using #r as the following code shows:
#r @".\bin\Debug\Samples.HelloWorldTypeProvider.dll"
obj1.InstanceProperty
obj2.InstanceProperty
Then look for the types under the Samples.HelloWorldTypeProvider namespace that the type provider generated.
Before you recompile the provider, make sure that you have closed all instances of Visual Studio and F# Interactive
that are using the provider DLL. Otherwise, a build error will occur because the output DLL will be locked.
To debug this provider by using print statements, make a script that exposes a problem with the provider, and then
use the following code:
To debug this provider by using Visual Studio, open the Visual Studio command prompt with administrative
credentials, and run the following command:
devenv.exe /debugexe fsc.exe -r:bin\Debug\HelloWorldTypeProvider.dll script.fsx
As an alternative, open Visual Studio, open the Debug menu, choose Debug/Attach to process… , and attach to
another devenv process where you’re editing your script. By using this method, you can more easily target
particular logic in the type provider by interactively typing expressions into the second instance (with full
IntelliSense and other features).
You can disable Just My Code debugging to better identify errors in generated code. For information about how to
enable or disable this feature, see Navigating through Code with the Debugger. Also, you can also set first-chance
exception catching by opening the Debug menu and then choosing Exceptions or by choosing the Ctrl+Alt+E keys
to open the Exceptions dialog box. In that dialog box, under Common Language Runtime Exceptions , select the
Thrown check box.
[<TypeProvider>]
type SampleTypeProvider(config: TypeProviderConfig) as this =
This type must be public, and you must mark it with the TypeProvider attribute so that the compiler will recognize
the type provider when a separate F# project references the assembly that contains the type. The config parameter
is optional, and, if present, contains contextual configuration information for the type provider instance that the F#
compiler creates.
Next, you implement the ITypeProvider interface. In this case, you use the TypeProviderForNamespaces type from the
ProvidedTypes API as a base type. This helper type can provide a finite collection of eagerly provided namespaces,
each of which directly contains a finite number of fixed, eagerly provided types. In this context, the provider eagerly
generates types even if they aren't needed or used.
inherit TypeProviderForNamespaces()
Next, define local private values that specify the namespace for the provided types, and find the type provider
assembly itself. This assembly is used later as the logical parent type of the erased types that are provided.
Next, create a function to provide each of the types Type1…Type100. This function is explained in more detail later
in this topic.
Finally, add an assembly attribute that indicates that you are creating a type provider DLL:
[<assembly:TypeProviderAssembly>]
do()
This step explains the implementation of this function. First, create the provided type (for example, Type1, when n =
1, or Type57, when n = 57).
// This is the provided type. It is an erased provided type and, in compiled code,
// will appear as type 'obj'.
let t = ProvidedTypeDefinition(thisAssembly,namespaceName,
"Type" + string n,
baseType = Some typeof<obj>)
t.AddXmlDocDelayed (fun () -> sprintf "This provided type %s" ("Type" + string n))
Getting this property will always evaluate to the string "Hello!". The GetterCode for the property uses an F#
quotation, which represents the code that the host compiler generates for getting the property. For more
information about quotations, see Code Quotations (F#).
Add XML documentation to the property.
Now attach the provided property to the provided type. You must attach a provided member to one and only one
type. Otherwise, the member will never be accessible.
t.AddMember staticProp
The InvokeCode for the constructor returns an F# quotation, which represents the code that the host compiler
generates when the constructor is called. For example, you can use the following constructor:
new Type10()
An instance of the provided type will be created with underlying data "The object data". The quoted code includes a
conversion to obj because that type is the erasure of this provided type (as you specified when you declared the
provided type).
Add XML documentation to the constructor, and add the provided constructor to the provided type:
t.AddMember ctor
let ctor2 =
ProvidedConstructor(parameters = [ ProvidedParameter("data",typeof<string>) ],
InvokeCode= (fun args -> <@@ (%%(args.[0]) : string) :> obj @@>))
The InvokeCode for the constructor again returns an F# quotation, which represents the code that the host compiler
generated for a call to the method. For example, you can use the following constructor:
new Type10("ten")
An instance of the provided type is created with underlying data "ten". You may have already noticed that the
InvokeCode function returns a quotation. The input to this function is a list of expressions, one per constructor
parameter. In this case, an expression that represents the single parameter value is available in args.[0] . The code
for a call to the constructor coerces the return value to the erased type obj . After you add the second provided
constructor to the type, you create a provided instance property:
let instanceProp =
ProvidedProperty(propertyName = "InstanceProperty",
propertyType = typeof<int>,
GetterCode= (fun args ->
<@@ ((%%(args.[0]) : obj) :?> string).Length @@>))
instanceProp.AddXmlDocDelayed(fun () -> "This is an instance property")
t.AddMember instanceProp
Getting this property will return the length of the string, which is the representation object. The GetterCode
property returns an F# quotation that specifies the code that the host compiler generates to get the property. Like
InvokeCode , the GetterCode function returns a quotation. The host compiler calls this function with a list of
arguments. In this case, the arguments include just the single expression that represents the instance upon which
the getter is being called, which you can access by using args.[0] .The implementation of GetterCode then splices
into the result quotation at the erased type obj , and a cast is used to satisfy the compiler's mechanism for
checking types that the object is a string. The next part of makeOneProvidedType provides an instance method with
one parameter.
let instanceMeth =
ProvidedMethod(methodName = "InstanceMethod",
parameters = [ProvidedParameter("x",typeof<int>)],
returnType = typeof<char>,
InvokeCode = (fun args ->
<@@ ((%%(args.[0]) : obj) :?> string).Chars(%%(args.[1]) : int) @@>))
Finally, create a nested type that contains 100 nested properties. The creation of this nested type and its properties
is delayed, that is, computed on-demand.
t.AddMembersDelayed(fun () ->
let nestedType = ProvidedTypeDefinition("NestedType",
Some typeof<obj>
p.AddXmlDocDelayed(fun () ->
sprintf "This is StaticProperty%d on NestedType" i)
yield p ]
staticPropsInNestedType)
[nestedType])
ProvidedConstructor(parameters = [],
InvokeCode= (fun args -> <@@ (new Dictionary<string,obj>()) :> obj @@>))
As an alternative, you may define a type in your type provider that will be used at runtime to form the
representation, along with one or more runtime operations:
type DataObject() =
let data = Dictionary<string,obj>()
member x.RuntimeOperation() = data.Count
Provided members can then construct instances of this object type:
ProvidedConstructor(parameters = [],
InvokeCode= (fun args -> <@@ (new DataObject()) :> obj @@>))
In this case, you may (optionally) use this type as the type erasure by specifying this type as the baseType when
constructing the ProvidedTypeDefinition :
Key Lessons
The previous section explained how to create a simple erasing type provider that provides a range of types,
properties, and methods. This section also explained the concept of type erasure, including some of the advantages
and disadvantages of providing erased types from a type provider, and discussed representations of erased types.
The following example shows how the type provider translates these calls:
The following code is the core of the logic to implement such a provider, and this example omits the addition of all
members to the provided type. For information about each added member, see the appropriate section later in this
topic. For the full code, download the sample from the F# 3.0 Sample Pack on the Codeplex website.
namespace Samples.FSharp.RegexTypeProvider
open System.Reflection
open Microsoft.FSharp.Core.CompilerServices
open Samples.FSharp.ProvidedTypes
open System.Text.RegularExpressions
[<TypeProvider>]
type public CheckedRegexProvider() as this =
inherit TypeProviderForNamespaces()
// Get the assembly and namespace used to house the provided types
let thisAssembly = Assembly.GetExecutingAssembly()
let rootNamespace = "Samples.FSharp.RegexTypeProvider"
let baseTy = typeof<obj>
let staticParams = [ProvidedStaticParameter("pattern", typeof<string>)]
do regexTy.DefineStaticParameters(
parameters=staticParams,
instantiationFunction=(fun typeName parameterValues ->
...
ty
| _ -> failwith "unexpected parameter values"))
do this.AddNamespace(rootNamespace, [regexTy])
[<TypeProviderAssembly>]
do ()
isMatch.AddXmlDoc "Indicates whether the regular expression finds a match in the specified input string."
ty.AddMember isMatch
The previous code defines a method IsMatch , which takes a string as input and returns a bool . The only tricky
part is the use of the args argument within the InvokeCode definition. In this example, args is a list of quotations
that represents the arguments to this method. If the method is an instance method, the first argument represents
the this argument. However, for a static method, the arguments are all just the explicit arguments to the method.
Note that the type of the quoted value should match the specified return type (in this case, bool ). Also note that
this code uses the AddXmlDoc method to make sure that the provided method also has useful documentation,
which you can supply through IntelliSense.
Next, add an instance Match method. However, this method should return a value of a provided Match type so that
the groups can be accessed in a strongly typed fashion. Thus, you first declare the Match type. Because this type
depends on the pattern that was supplied as a static argument, this type must be nested within the parameterized
type definition:
ty.AddMember matchTy
You then add one property to the Match type for each group. At runtime, a match is represented as a
System.Text.RegularExpressions.Match value, so the quotation that defines the property must use the
System.Text.RegularExpressions.Match.Groups indexed property to get the relevant group.
for group in r.GetGroupNames() do
// Ignore the group named 0, which represents all input.
if group <> "0" then
let prop = ProvidedProperty(
propertyName = group,
propertyType = typeof<Group>,
GetterCode = fun args -> <@@ ((%%args.[0]:obj) :?> Match).Groups.[group] @@>)
prop.AddXmlDoc(sprintf @"Gets the ""%s"" group from this match" group)
matchTy.AddMember prop
Again, note that you’re adding XML documentation to the provided property. Also note that a property can be read
if a GetterCode function is provided, and the property can be written if a SetterCode function is provided, so the
resulting property is read only.
Now you can create an instance method that returns a value of this Match type:
let matchMethod =
ProvidedMethod(
methodName = "Match",
parameters = [ProvidedParameter("input", typeof<string>)],
returnType = matchTy,
InvokeCode = fun args -> <@@ ((%%args.[0]:obj) :?> Regex).Match(%%args.[1]) :> obj @@>)
matchMeth.AddXmlDoc "Searches the specified input string for the first occurrence of this regular expression"
ty.AddMember matchMeth
Because you are creating an instance method, args.[0] represents the RegexTyped instance on which the method
is being called, and args.[1] is the input argument.
Finally, provide a constructor so that instances of the provided type can be created.
ty.AddMember ctor
The constructor merely erases to the creation of a standard .NET Regex instance, which is again boxed to an object
because obj is the erasure of the provided type. With that change, the sample API usage that specified earlier in
the topic works as expected. The following code is complete and final:
namespace Samples.FSharp.RegexTypeProvider
open System.Reflection
open Microsoft.FSharp.Core.CompilerServices
open Samples.FSharp.ProvidedTypes
open System.Text.RegularExpressions
[<TypeProvider>]
type public CheckedRegexProvider() as this =
inherit TypeProviderForNamespaces()
// Get the assembly and namespace used to house the provided types.
let thisAssembly = Assembly.GetExecutingAssembly()
let rootNamespace = "Samples.FSharp.RegexTypeProvider"
let baseTy = typeof<obj>
let staticParams = [ProvidedStaticParameter("pattern", typeof<string>)]
let r = System.Text.RegularExpressions.Regex(pattern)
let ty = ProvidedTypeDefinition(
thisAssembly,
rootNamespace,
typeName,
baseType = Some baseTy)
isMatch.AddXmlDoc "Indicates whether the regular expression finds a match in the specified input string"
ty.AddMember isMatch
ty.AddMember matchMeth
// Declare a constructor.
// Declare a constructor.
let ctor = ProvidedConstructor(
parameters = [],
InvokeCode = fun args -> <@@ Regex(pattern) :> obj @@>)
ty.AddMember ctor
ty
| _ -> failwith "unexpected parameter values"))
do this.AddNamespace(rootNamespace, [regexTy])
[<TypeProviderAssembly>]
do ()
Key Lessons
This section explained how to create a type provider that operates on its static parameters. The provider checks the
static parameter and provides operations based on its value.
50.0 3.7
100.0 5.2
150.0 6.4
This section shows how to provide a type that you can use to get rows with a Distance property of type
float<meter> and a Time property of type float<second> . For simplicity, the following assumptions are made:
Header names are either unit-less or have the form "Name (unit)" and don't contain commas.
Units are all Systeme International (SI) units as the Microsoft.FSharp.Data.UnitSystems.SI.UnitNames Module
(F#) module defines.
Units are all simple (for example, meter) rather than compound (for example, meter/second).
All columns contain floating point data.
A more complete provider would loosen these restrictions.
Again the first step is to consider how the API should look. Given an info.csv file with the contents from the
previous table (in comma-separated format), users of the provider should be able to write code that resembles the
following example:
let info = new MiniCsv<"info.csv">()
for row in info.Data do
let time = row.Time
printfn "%f" (float time)
In this case, the compiler should convert these calls into something like the following example:
The optimal translation will require the type provider to define a real CsvFile type in the type provider's assembly.
Type providers often rely on a few helper types and methods to wrap important logic. Because measures are erased
at runtime, you can use a float[] as the erased type for a row. The compiler will treat different columns as having
different measure types. For example, the first column in our example has type float<meter> , and the second has
float<second> . However, the erased representation can remain quite simple.
[<TypeProvider>]
type public MiniCsvProvider(cfg:TypeProviderConfig) as this =
inherit TypeProviderForNamespaces()
// Get the assembly and namespace used to house the provided types.
let asm = System.Reflection.Assembly.GetExecutingAssembly()
let ns = "Samples.FSharp.MiniCsvProvider"
else
// no units, just treat it as a normal float
headerText, typeof<float>
// Add metadata that defines the property's location in the referenced file.
prop.AddDefinitionLocation(1, headers.[i].Index + 1, filename)
rowTy.AddMember(prop)
// Add a parameterless constructor that loads the file that was used to define the schema.
let ctor0 = ProvidedConstructor([],
InvokeCode = fun [] -> <@@ CsvFile(resolvedFilename) @@>)
ty.AddMember ctor0
// Add a more strongly typed Data property, which uses the existing property at runtime.
let prop = ProvidedProperty("Data", typedefof<seq<_>>.MakeGenericType(rowTy),
GetterCode = fun [csvFile] -> <@@ (%%csvFile:CsvFile).Data @@>)
ty.AddMember prop
This section explained how to create a type provider for a local data source with a simple schema that's contained
in the data source itself.
Going Further
The following sections include suggestions for further study.
A Look at the Compiled Code for Erased Types
To give you some idea of how the use of the type provider corresponds to the code that's emitted, look at the
following function by using the HelloWorldTypeProvider that's used earlier in this topic.
let function1 () =
let obj1 = Samples.HelloWorldTypeProvider.Type1("some data")
obj1.InstanceProperty
As the example shows, all mentions of the type Type1 and the InstanceProperty property have been erased,
leaving only operations on the runtime types involved.
Design and Naming Conventions for Type Providers
Observe the following conventions when authoring type providers.
Providers for Connectivity Protocols
In general, names of most provider DLLs for data and service connectivity protocols, such as OData or SQL
connections, should end in TypeProvider or TypeProviders . For example, use a DLL name that resembles the
following string:
Fabrikam.Management.BasicTypeProviders.dll
Ensure that your provided types are members of the corresponding namespace, and indicate the connectivity
protocol that you implemented:
Fabrikam.Management.BasicTypeProviders.WmiConnection<…>
Fabrikam.Management.BasicTypeProviders.DataProtocolConnection<…>
Utility Providers for General Coding
For a utility type provider such as that for regular expressions, the type provider may be part of a base library, as
the following example shows:
#r "Fabrikam.Core.Text.Utilities.dll"
In this case, the provided type would appear at an appropriate point according to normal .NET design conventions:
open Fabrikam.Core.Text.RegexTyped
#r "Fabrikam.Data.Freebase.dll"
For more information, see the GetConnection design convention that's described later in this topic.
Design Patterns for Type Providers
The following sections describe design patterns you can use when authoring type providers.
The GetConnection Design Pattern
Most type providers should be written to use the GetConnection pattern that's used by the type providers in
FSharp.Data.TypeProviders.dll, as the following example shows:
#r "Fabrikam.Data.WebDataStore.dll"
type ProvidedType =
member AddMemberDelayed : (unit -> MemberInfo) -> unit
member AddMembersDelayed : (unit -> MemberInfo list) -> unit
System.IO.IOException
System.Exception
open Microsoft.FSharp.TypeProviders
The ProvidedTypes-0.2 helper code that is part of the F# 3.0 release has only limited support for providing
generated types. The following statements must be true for a generated type definition:
IsErased must be set to false .
The provider must have an assembly that has an actual backing .NET .dll file with a matching .dll file on disk.
You must also call ConvertToGenerated on a root provided type whose nested types form a closed set of generated
types. This call emits the given provided type definition and its nested type definitions into an assembly and adjusts
the Assembly property of all provided type definitions to return that assembly. The assembly is emitted only when
the Assembly property on the root type is accessed for the first time. The host F# compiler does access this
property when it processes a generative type declaration for the type.
Development Tips
You might find the following tips helpful during the development process.
Run Two Instances of Visual Studio. You can develop the type provider in one instance and test the
provider in the other because the test IDE will take a lock on the .dll file that prevents the type provider from
being rebuilt. Thus, you must close the second instance of Visual Studio while the provider is built in the first
instance, and then you must reopen the second instance after the provider is built.
Debug type providers by using invocations of fsc.exe. You can invoke type providers by using the
following tools:
fsc.exe (The F# command line compiler)
fsi.exe (The F# Interactive compiler)
devenv.exe (Visual Studio)
You can often debug type providers most easily by using fsc.exe on a test script file (for example, script.fsx).
You can launch a debugger from a command prompt.
See Also
Type Providers
Type Provider Security
7/29/2017 • 1 min to read • Edit Online
Type providers are assemblies (DLLs) referenced by your F# project or script that contain code to connect to
external data sources and surface this type information to the F# type environment. Typically, code in referenced
assemblies is only run when you compile and then execute the code (or in the case of a script, send the code to F#
Interactive). However, a type provider assembly will run inside Visual Studio when the code is merely browsed in
the editor. This happens because type providers need to run to add extra information to the editor, such as Quick
Info tooltips, IntelliSense completions, and so on. As a result, there are extra security considerations for type
provider assemblies, since they run automatically inside the Visual Studio process.
See Also
Type Providers
Troubleshooting Type Providers
7/29/2017 • 1 min to read • Edit Online
This topic describes and provides potential solutions for the problems that you are most likely to encounter when
you use type providers.
Schema Changes. Type providers work best when the data Clean or rebuild the project. To clean the project, choose
source schema is stable. If you add a data table or column or Build, Clean ProjectName on the menu bar. To rebuild the
make another change to that schema, the type provider project, choose Build, Rebuild ProjectName on the menu bar.
doesn’t automatically recognize these changes. These actions reset all type provider state and force the
provider to reconnect to the data source and obtain updated
schema information.
Connection Failure. The URL or connection string is incorrect, For a web service or OData service, you can try the URL in
the network is down, or the data source or service is Internet Explorer to verify whether the URL is correct and the
unavailable. service is available. For a database connection string, you can
use the data connection tools in Server Explorer to verify
whether the connection string is valid and the database is
available. After you restore your connection, you should then
clean or rebuild the project so that the type provider will
reconnect to the network.
Not Valid Credentials. You must have valid permissions for For a SQL connection, the username and the password that
the data source or web service. are specified in the connection string or configuration file must
be valid for the database. If you are using Windows
Authentication, you must have access to the database. The
database administrator can identify what permissions you
need for access to each database and each element within a
database.
Not Valid Path. A path to a file was not valid. Verify whether the path is correct and the file exists. In
addition, you must either quote any backlashes in the path
appropriately or use a verbatim string or triple-quoted string.
See Also
Type Providers
Functions as First-Class Values
7/29/2017 • 22 min to read • Edit Online
A defining characteristic of functional programming languages is the elevation of functions to first-class status.
You should be able to do with a function whatever you can do with values of the other built-in types, and be able
to do so with a comparable degree of effort.
Typical measures of first-class status include the following:
Can you bind functions to identifiers? That is, can you give them names?
Can you store functions in data structures, such as in a list?
Can you pass a function as an argument in a function call?
Can you return a function from a function call?
The last two measures define what are known as higher-order operations or higher-order functions. Higher-order
functions accept functions as arguments and return functions as the value of function calls. These operations
support such mainstays of functional programming as mapping functions and composition of functions.
You can name a function just as easily. The following example defines a function named squareIt by binding the
identifier squareIt to the lambda expression fun n -> n * n . Function squareIt has one parameter, n , and it
returns the square of that parameter.
F# provides the following more concise syntax to achieve the same result with less typing.
let squareIt2 n = n * n
The examples that follow mostly use the first style, let <function-name> = <lambda-expression> , to emphasize the
similarities between the declaration of functions and the declaration of other types of values. However, all the
named functions can also be written with the concise syntax. Some of the examples are written in both ways.
// Tuples.
To verify that a function name stored in a tuple does in fact evaluate to a function, the following example uses the
fst and snd operators to extract the first and second elements from tuple funAndArgTuple . The first element in
the tuple is squareIt and the second element is num . Identifier num is bound in a previous example to integer 10,
a valid argument for the squareIt function. The second expression applies the first element in the tuple to the
second element in the tuple: squareIt num .
// You can pull a function out of a tuple and apply it. Both squareIt and num
// were defined previously.
let funAndArgTuple = (squareIt, num)
Similarly, just as identifier num and integer 10 can be used interchangeably, so can identifier squareIt and
lambda expression fun n -> n * n .
// Make a list of values instead of identifiers.
let funAndArgTuple2 = ((fun n -> n * n), 10)
// String.
// Function repeatString concatenates a string with itself.
let repeatString = fun s -> s + s
If functions have first-class status, you must be able to pass them as arguments in the same way. Remember that
this is the first characteristic of higher-order functions.
In the following example, function applyIt has two parameters, op and arg . If you send in a function that has
one parameter for op and an appropriate argument for the function to arg , the function returns the result of
applying op to arg . In the following example, both the function argument and the integer argument are sent in
the same way, by using their names.
// Send squareIt for the function, op, and num for the argument you want to
// apply squareIt to, arg. Both squareIt and num are defined in previous
// examples. The result returned and displayed is 100.
System.Console.WriteLine(applyIt squareIt num)
// The following expression shows the concise syntax for the previous function
// definition.
let applyIt2 op arg = op arg
// The following line also displays 100.
System.Console.WriteLine(applyIt2 squareIt num)
The ability to send a function as an argument to another function underlies common abstractions in functional
programming languages, such as map or filter operations. A map operation, for example, is a higher-order
function that captures the computation shared by functions that step through a list, do something to each element,
and then return a list of the results. You might want to increment each element in a list of integers, or to square
each element, or to change each element in a list of strings to uppercase. The error-prone part of the computation
is the recursive process that steps through the list and builds a list of the results to return. That part is captured in
the mapping function. All you have to write for a particular application is the function that you want to apply to
each list element individually (adding, squaring, changing case). That function is sent as an argument to the
mapping function, just as squareIt is sent to applyIt in the previous example.
F# provides map methods for most collection types, including lists, arrays, and sequences. The following examples
use lists. The syntax is List.map <the function> <the list> .
// Or you can define the action to apply to each list element inline.
// For example, no function that tests for even integers has been defined,
// so the following expression defines the appropriate function inline.
// The function returns true if n is even; otherwise it returns false.
let evenOrNot = List.map (fun n -> n % 2 = 0) integerList
// The following line displays [false; true; false; true; false; true; false]
printfn "%A" evenOrNot
The following function call, declared inline, returns a Boolean value. The value displayed is True .
The ability to return a function as the value of a function call is the second characteristic of higher-order functions.
In the following example, checkFor is defined to be a function that takes one argument, item , and returns a new
function as its value. The returned function takes a list as its argument, lst , and searches for item in lst . If
item is present, the function returns true . If item is not present, the function returns false . As in the previous
section, the following code uses a provided list function, List.exists, to search the list.
let checkFor item =
let functionToReturn = fun lst ->
List.exists (fun a -> a = item) lst
functionToReturn
The following code uses checkFor to create a new function that takes one argument, a list, and searches for 7 in
the list.
The following example uses the first-class status of functions in F# to declare a function, compose , that returns a
composition of two function arguments.
NOTE
For an even shorter version, see the following section, "Curried Functions."
The following code sends two functions as arguments to compose , both of which take a single argument of the
same type. The return value is a new function that is a composition of the two function arguments.
// Functions squareIt and doubleIt were defined in a previous example.
let doubleAndSquare = compose squareIt doubleIt
// The following expression doubles 3, squares 6, and returns and
// displays 36.
System.Console.WriteLine(doubleAndSquare 3)
NOTE
F# provides two operators, << and >> , that compose functions. For example,
let squareAndDouble2 = doubleIt << squareIt is equivalent to let squareAndDouble = compose doubleIt squareIt
in the previous example.
The following example of returning a function as the value of a function call creates a simple guessing game. To
create a game, call makeGame with the value that you want someone to guess sent in for target . The return value
from function makeGame is a function that takes one argument (the guess) and reports whether the guess is
correct.
The following code calls makeGame , sending the value 7 for target . Identifier playGame is bound to the returned
lambda expression. Therefore, playGame is a function that takes as its one argument a value for guess .
// Output:
// Wrong. Try again.
// Wrong. Try again.
// You win!
// Output:
// Wrong. Try again.
// Wrong. Try again.
// Wrong. Try again.
// You win!
Curried Functions
Many of the examples in the previous section can be written more concisely by taking advantage of the implicit
currying in F# function declarations. Currying is a process that transforms a function that has more than one
parameter into a series of embedded functions, each of which has a single parameter. In F#, functions that have
more than one parameter are inherently curried. For example, compose from the previous section can be written
as shown in the following concise style, with three parameters.
However, the result is a function of one parameter that returns a function of one parameter that in turn returns
another function of one parameter, as shown in compose4curried .
let compose4curried =
fun op1 ->
fun op2 ->
fun n -> op1 (op2 n)
You can access this function in several ways. Each of the following examples returns and displays 18. You can
replace compose4 with compose4curried in any of the examples.
To verify that the function still works as it did before, try the original test cases again.
NOTE
You can restrict currying by enclosing parameters in tuples. For more information, see "Parameter Patterns" in Parameters
and Arguments.
The following example uses implicit currying to write a shorter version of makeGame . The details of how makeGame
constructs and returns the game function are less explicit in this format, but you can verify by using the original
test cases that the result is the same.
let makeGame2 target guess =
if guess = target then
System.Console.WriteLine("You win!")
else
System.Console.WriteLine("Wrong. Try again.")
For more information about currying, see "Partial Application of Arguments" in Functions.
// This example uses the names of the function argument and the integer
// argument. Identifier num is defined in a previous example.
//let num = 10
System.Console.WriteLine(applyIt isNegative num)
// This example substitutes the value that num is bound to for num, and the
// value that isNegative is bound to for isNegative.
System.Console.WriteLine(applyIt (fun n -> n < 0) 10)
To take it one step further, substitute the value that applyIt is bound to for applyIt .
Example
Description
The following code contains all the examples in this topic.
Code
let squareIt2 n = n * n
// Lists.
// Tuples.
// You can pull a function out of a tuple and apply it. Both squareIt and num
// were defined previously.
let funAndArgTuple = (squareIt, num)
// String.
// Function repeatString concatenates a string with itself.
let repeatString = fun s -> s + s
// Send squareIt for the function, op, and num for the argument you want to
// apply squareIt to, arg. Both squareIt and num are defined in previous
// apply squareIt to, arg. Both squareIt and num are defined in previous
// examples. The result returned and displayed is 100.
System.Console.WriteLine(applyIt squareIt num)
// The following expression shows the concise syntax for the previous function
// definition.
let applyIt2 op arg = op arg
// The following line also displays 100.
System.Console.WriteLine(applyIt2 squareIt num)
// Or you can define the action to apply to each list element inline.
// For example, no function that tests for even integers has been defined,
// so the following expression defines the appropriate function inline.
// The function returns true if n is even; otherwise it returns false.
let evenOrNot = List.map (fun n -> n % 2 = 0) integerList
// The following line displays [false; true; false; true; false; true; false]
printfn "%A" evenOrNot
// Output:
// Wrong. Try again.
// Wrong. Try again.
// You win!
// Output:
// Wrong. Try again.
// Wrong. Try again.
// Wrong. Try again.
// You win!
// ** CURRIED FUNCTIONS **
let compose4curried =
fun op1 ->
fun op2 ->
fun n -> op1 (op2 n)
// This example uses the names of the function argument and the integer
// argument. Identifier num is defined in a previous example.
//let num = 10
System.Console.WriteLine(applyIt isNegative num)
// This example substitutes the value that num is bound to for num, and the
// value that isNegative is bound to for isNegative.
System.Console.WriteLine(applyIt (fun n -> n < 0) 10)
See Also
Lists
Tuples
Functions
let Bindings
Lambda Expressions: The fun Keyword
Async Programming in F#
7/29/2017 • 6 min to read • Edit Online
NOTE
Some inaccuracies have been discovered in this article. It is being rewritten. See Issue #666 to learn about the changes.
Async programming in F# can be accomplished through a language-level programming model designed to be easy
to use and natural to the language.
The core of async programming in F# is Async<'T> , a representation of work that can be triggered to run in the
background, where 'T is either the type returned via the special return keyword or unit if the async workflow
has no result to return.
The key concept to understand is that an async expression’s type is Async<'T> , which is merely a specification of
work to be done in an asynchronous context. It is not executed until you explicitly start it with one of the starting
functions (such as Async.RunSynchronously ). Although this is a different way of thinking about doing work, it ends
up being quite simple in practice.
For example, say you wanted to download the HTML from dotnetfoundation.org without blocking the main thread.
You can accomplish it like this:
And that’s it! Aside from the use of async , let! , and return , this is just normal F# code.
There are a few syntactical constructs which are worth noting:
let! binds the result of an async expression (which runs on another context).
use! works just like let! , but disposes its bound resources when it goes out of scope.
do! will await an async workflow which doesn’t return anything.
return simply returns a result from an async expression.
return! executes another async workflow and returns its return value as a result.
Additionally, normal let , use , and do keywords can be used alongside the async versions just as they would in a
normal function.
2. Async.Start will start an async workflow on another thread, and will not await its result.
There are other ways to start an async workflow available for more specific scenarios. They are detailed in the
Async reference.
A Note on Threads
The phrase "on another thread" is mentioned above, but it is important to know that this does not mean that
async workflows are a facade for multithreading. The workflow actually "jumps" between threads, borrowing
them for a small amount of time to do useful work. When an async workflow is effectively "waiting" (for example,
waiting for a network call to return something), any thread it was borrowing at the time is freed up to go do useful
work on something else. This allows async workflows to utilize the system they run on as effectively as possible,
and makes them especially strong for high-volume I/O scenarios.
let getHtmlList =
Seq.map fetchHtmlAsync // Build an Async<'T> for each site
>> Async.Parallel // Returns an Async<'T []>
>> Async.RunSynchronously // Wait for the result of the parallel work
The three keywords can only be used within an async { } block, similar to how await can only be invoked inside
an async method. In short, let! is for when you want to capture and use a result, use! is the same but for
something whose resources should get cleaned after it’s used, and do! is for when you want to wait for an async
workflow with no return value to finish before moving on.
F# supports data-parallelism in a similar way.
Although it operates very differently, Async.Parallel corresponds to Task.WhenAll for the scenario of wanting the
results of a set of async jobs when they all complete.
Differences
Nested let! is not allowed, unlike nested await
Unlike await , which can be nested indefinitely, let! cannot and must have its result bound before using it inside
of another let! , do! , or use! .
Cancellation support is simpler in F# than in C#/VB.
Supporting cancellation of a task midway through its execution in C#/VB requires checking the
IsCancellationRequested property or calling ThrowIfCancellationRequested() on a CancellationToken object that’s
passed into the async method.
In contrast, F# async workflows are more naturally cancellable. Cancellation is a simple three-step process.
1. Create a new CancellationTokenSource .
2. Pass it into a starting function.
3. Call Cancel on the token.
Example:
Further resources:
Async Workflows on MSDN
Asynchronous Sequences for F#
F# Data HTTP Utilities
Visual F# Development Environment Features
8/14/2017 • 6 min to read • Edit Online
NOTE
This article is not up to date with the latest Visual Studio. It will be updated.
This topic includes information about which features of Visual Studio 2012 are supported in F#.
Project Features
The following table summarizes the templates that are available for use in F# projects. For information about
project and item templates, see NIB Creating Projects from Templates.
Item templates File types available in the Add New F# source file (.fs)
Item dialog box. F# script (.fsx)
F# signature file (.fsi)
Configuration file (.config)
SQL Database Connection
(LINQ-to-SQL type provider)
SQL Database Connection (LINQ
to Entities type provider)
OData Service Connection (LINQ
type provider)
WSDL Service Connection (type
provider)
XML file (.xml)
Text file
To create an application that can run as a standalone executable, choose the F# Application project type. To create a
library (that is, a managed assembly or .DLL file) for use on the Windows desktop platform, choose F# Library. To
create a portable library that can be used on any supported platform, choose F# Portable Library. F# Portable
Library projects reference a version of FSharp.Core.dll that is appropriate to create an F# library that can be used
with applications that run on platforms such as Windows Store apps, the .NET Framework 4.5, Xamarin.iOS and
Xamarin.Android.
For more information about the item templates for data access, see Type Providers.
The following table summarizes project-properties features supported and not supported in F#. For more
information, see Configuring Projects and Introduction to the Project Designer.
PROJECT SETTING SUPPORTED IN F#? NOTES
Multitargeting Yes
Finding and Replacing Text Enables you to search in a file, project, Yes
or solution, and potentially change text.
Go to definition for .NET Framework API When the cursor is positioned on a .NET No
Framework API, shows code generated
from .NET Framework metadata.
Go to definition for user-defined API When the cursor is on a program entity Yes
that you defined, moves the cursor to
the location in your code where the
entity is defined.
FEATURE DESCRIPTION SUPPORTED IN F#?
Quick Find. See Quick Find, Find and Enables you to search in a file or project. Yes, but only to find F# files, not to
Replace Window. search within files
IntelliSense Features
The following table summarizes IntelliSense features supported and not supported in F#. For general information
about IntelliSense, see Using IntelliSense.
Debugging Features
The following table summarizes features that are available when you debug F# code. For general information about
the Visual Studio debugger, see Debugging in Visual Studio.
Expression evaluator Evaluates and executes code at run No, but the C# expression evaluator can
time. be used, although you must use C#
syntax.
Additional Tools
The following table summarizes the support for F# in Visual Studio tools.
Object Browser Enables you to view the types in an F# types as they appear in compiled
assembly. assemblies do not appear exactly as you
author them. You can browse through
the compiled representation of F#
types, but you cannot view the types as
they appear from F#.
See Also
Get Started with F# in Visual Studio
Configuring Projects
Configuring Projects in Visual Studio
8/14/2017 • 2 min to read • Edit Online
NOTE
This article is not up to date with the latest Visual Studio. It will be updated.
This topic includes information about how to use the Project Designer when you work with F# projects. Working
with F# projects is not significantly different from working with Visual Basic or C# projects. You can often use the
general Visual Studio project documentation as your primary reference when you use F#. This topic provides links
to relevant information in the Visual Studio documentation for settings that are shared with the other Visual Studio
languages, and also describes the settings specific to F#.
Project Designer
The Project Designer and its general use are described fully in the topic Introduction to the Project Designer in
the Visual Studio documentation. The Project Designer consists of several pages grouped by related functionality.
The pages available for F# projects are mostly a subset of those available for other languages. The pages
supported in F# are described in the following table. The pages that are not available relate to features that are not
available in F#, or that are available only by changing a command-line option. The pages that are available in F#
resemble the C# pages most closely, so a link is provided to the relevant C# Project Designer page.
Application Application Page, Project Designer (C#) Enables you to specify application-level
settings and properties, such as
whether you are creating a library or an
executable file, what version of the .NET
Framework the application is targeting,
and information about where the
resource files that the application uses
are stored.
Build Build Page, Project Designer (C#) Enables you to control how the code is
compiled.
Build Events Build Events Page, Project Designer (C#) Enables you to specify commands to
run before or after a compilation.
Debug Debug Page, Project Designer Enables you to control how the
application runs during debugging. This
includes what command-line to use and
what your application's starting
directory is, and any special debugging
modes you want to enable, such as
native code and SQL.
Reference Paths Managing references in a project Enables you to specify where to search
for assemblies that the code depends
on.
F#-Specific Settings
The following table summarizes settings that are specific to F#:
Build Generate tail calls If selected, enables the use of the tail
Microsoft intermediate language (MSIL)
instruction. This causes the stack frame
to be reused for tail recursive functions.
Equivalent to the --tailcalls
compiler option.
See Also
Get Started with F# in Visual Studio
Compiler Options
Introduction to the Project Designer
Targeting Older Versions of .NET
7/29/2017 • 1 min to read • Edit Online
NOTE
This article is not up to date with the latest Visual Studio. It will be updated.
The following error might appear if you try to target the .NET Framework 2.0, 3.0, or 3.5 in an F# project when
Visual Studio is installed on Windows 8.1:
This project requires the 2.0 F# runtime, but that runtime is not installed.
See Also
Visual F#
Using F# on Azure
7/29/2017 • 4 min to read • Edit Online
F# is a superb language for cloud programming and is frequently used to write web applications, cloud services,
cloud-hosted microservices, and for scalable data processing.
In the following sections, you will find resources on how to use a range of Azure services with F#.
NOTE
If a particular Azure service isn't in this documentation set, please consult either the Azure Functions or .NET documentation
for that service. Some Azure services are language-independent and require no language-specific documentation and are not
listed here.
Other resources
Full documentation on all Azure services
Get started with Azure Blob storage using F#
7/29/2017 • 12 min to read • Edit Online
Azure Blob storage is a service that stores unstructured data in the cloud as objects/blobs. Blob storage can store
any type of text or binary data, such as a document, media file, or application installer. Blob storage is also referred
to as object storage.
This article shows you how to perform common tasks using Blob storage. The samples are written using F# using
the Azure Storage Client Library for .NET. The tasks covered include how to upload, list, download, and delete blobs.
For a conceptual overview of blob storage, see the .NET guide for blob storage.
Prerequisites
To use this guide, you must first create an Azure storage account. You also need your storage access key for this
account.
open System
open System.IO
open Microsoft.Azure // Namespace for CloudConfigurationManager
open Microsoft.WindowsAzure.Storage // Namespace for CloudStorageAccount
open Microsoft.WindowsAzure.Storage.Blob // Namespace for Blob storage types
However, this is not recommended for real projects. Your storage account key is similar to the root password for
your storage account. Always be careful to protect your storage account key. Avoid distributing it to other users,
hard-coding it, or saving it in a plain-text file that is accessible to others. You can regenerate your key using the
Azure Portal if you believe it may have been compromised.
For real applications, the best way to maintain your storage connection string is in a configuration file. To fetch the
connection string from a configuration file, you can do this:
// Parse the connection string and return a reference to the storage account.
let storageConnString =
CloudConfigurationManager.GetSetting("StorageConnectionString")
Using Azure Configuration Manager is optional. You can also use an API such as the .NET Framework's
ConfigurationManager type.
// Parse the connection string and return a reference to the storage account.
let storageAccount = CloudStorageAccount.Parse(storageConnString)
Now you are ready to write code that reads data from and writes data to Blob storage.
Create a container
This example shows how to create a container if it does not already exist:
By default, the new container is private, meaning that you must specify your storage access key to download blobs
from this container. If you want to make the files within the container available to everyone, you can set the
container to be public using the following code:
Anyone on the Internet can see blobs in a public container, but you can modify or delete them only if you have the
appropriate account access key or a shared access signature.
// Create or overwrite the "myblob.txt" blob with contents from the local file.
do blockBlob.UploadFromFile(localFile)
// Loop over items within the container and output the length and URI.
for item in container.ListBlobs(null, false) do
match item with
| :? CloudBlockBlob as blob ->
printfn "Block blob of length %d: %O" blob.Properties.Length blob.Uri
| _ ->
printfn "Unknown blob type: %O" (item.GetType())
You can also name blobs with path information in their names. This creates a virtual directory structure that you
can organize and traverse as you would a traditional file system. Note that the directory structure is virtual only -
the only resources available in Blob storage are containers and blobs. However, the storage client library offers a
CloudBlobDirectory object to refer to a virtual directory and simplify the process of working with blobs that are
organized in this way.
For example, consider the following set of block blobs in a container named photos :
photo1.jpg 2015/architecture/description.txt 2015/architecture/photo3.jpg 2015/architecture/photo4.jpg
2016/architecture/photo5.jpg 2016/architecture/photo6.jpg 2016/architecture/description.txt 2016/photo7.jpg
When you call ListBlobs on a container (as in the above sample), a hierarchical listing is returned. If it contains
both CloudBlobDirectory and CloudBlockBlob objects, representing the directories and blobs in the container,
respectively, then the resulting output looks similar to this:
Directory: https://<accountname>.blob.core.windows.net/photos/2015/
Directory: https://<accountname>.blob.core.windows.net/photos/2016/
Block blob of length 505623: https://<accountname>.blob.core.windows.net/photos/photo1.jpg
Optionally, you can set the UseFlatBlobListing parameter of the ListBlobs method to true . In this case, every
blob in the container is returned as a CloudBlockBlob object. The call to ListBlobs to return a flat listing looks like
this:
// Loop over items within the container and output the length and URI.
for item in container.ListBlobs(null, true) do
match item with
| :? CloudBlockBlob as blob ->
printfn "Block blob of length %d: %O" blob.Properties.Length blob.Uri
| _ ->
printfn "Unexpected blob type: %O" (item.GetType())
and, depending on the current contents of your container, the results look like this:
Download blobs
To download blobs, first retrieve a blob reference and then call the DownloadToStream method. The following
example uses the DownloadToStream method to transfer the blob contents to a stream object that you can then
persist to a local file.
You can also use the DownloadToStream method to download the contents of a blob as a text string.
let text =
use memoryStream = new MemoryStream()
blobToDownload.DownloadToStream(memoryStream)
Text.Encoding.UTF8.GetString(memoryStream.ToArray())
Delete blobs
To delete a blob, first get a blob reference and then call the Delete method on it.
The sample defines an asynchronous method, using an async block. The let! keyword suspends execution of the
sample method until the listing task completes.
let ListBlobsSegmentedInFlatListing(container:CloudBlobContainer) =
async {
printfn ""
We can now use this asynchronous routine as follows. First you upload some dummy data (using the local file
created earlier in this tutorial).
// Create some dummy data by uploading the same file over and over again
for i in 1 .. 100 do
let blob = container.GetBlockBlobReference("myblob" + string i + ".txt")
use fileStream = System.IO.File.OpenRead(localFile)
blob.UploadFromFile(localFile)
Now, call the routine. You use Async.RunSynchronously to force the execution of the asynchronous operation.
ListBlobsSegmentedInFlatListing container |> Async.RunSynchronously
// Create the append blob. Note that if the blob already exists, the
// CreateOrReplace() method will overwrite it. You can check whether the
// blob exists to avoid overwriting it by using CloudAppendBlob.Exists().
appendBlob.CreateOrReplace()
let numBlocks = 10
// Simulate a logging operation by writing text data and byte data to the
// end of the append blob.
for i in 0 .. numBlocks - 1 do
let msg = sprintf "Timestamp: %u \tLog Entry: %d\n" DateTime.UtcNow bytes.[i]
appendBlob.AppendText(msg)
See Understanding Block Blobs, Page Blobs, and Append Blobs for more information about the differences between
the three types of blobs.
Concurrent access
To support concurrent access to a blob from multiple clients or multiple process instances, you can use ETags or
leases.
Etag - provides a way to detect that the blob or container has been modified by another process
Lease - provides a way to obtain exclusive, renewable, write or delete access to a blob for a period of time
For more information, see Managing Concurrency in Microsoft Azure Storage.
Naming containers
Every blob in Azure storage must reside in a container. The container forms part of the blob name. For example,
mydata is the name of the container in these sample blob URIs:
https://storagesample.blob.core.windows.net/mydata/blob1.txt
https://storagesample.blob.core.windows.net/mydata/photos/myphoto.jpg
A container name must be a valid DNS name, conforming to the following naming rules:
1. Container names must start with a letter or number, and can contain only letters, numbers, and the dash (-)
character.
2. Every dash (-) character must be immediately preceded and followed by a letter or number; consecutive dashes
are not permitted in container names.
3. All letters in a container name must be lowercase.
4. Container names must be from 3 through 63 characters long.
Note that the name of a container must always be lowercase. If you include an upper-case letter in a container
name, or otherwise violate the container naming rules, you may receive a 400 error (Bad Request).
Next steps
Now that you've learned the basics of Blob storage, follow these links to learn more.
Tools
F# AzureStorageTypeProvider An F# Type Provider which can be used to explore Blob, Table and Queue Azure
Storage assets and easily apply CRUD operations on them.
FSharp.Azure.Storage An F# API for using Microsoft Azure Table Storage service
Microsoft Azure Storage Explorer (MASE) is a free, standalone app from Microsoft that enables you to work
visually with Azure Storage data on Windows, OS X, and Linux.
Blob storage reference
Storage Client Library for .NET reference
REST API reference
Related guides
Getting Started with Azure Blob Storage in C#
Transfer data with the AzCopy command-line utility
Configuring Connection Strings
Azure Storage Team Blog
Get started with Azure File storage using F#
7/29/2017 • 6 min to read • Edit Online
Azure File storage is a service that offers file shares in the cloud using the standard Server Message Block (SMB)
Protocol. Both SMB 2.1 and SMB 3.0 are supported. With Azure File storage, you can migrate legacy applications
that rely on file shares to Azure quickly and without costly rewrites. Applications running in Azure virtual machines
or cloud services or from on-premises clients can mount a file share in the cloud, just as a desktop application
mounts a typical SMB share. Any number of application components can then mount and access the File storage
share simultaneously.
For a conceptual overview of file storage, please see the .NET guide for file storage.
Prerequisites
To use this guide, you must first create an Azure storage account. You'll also need your storage access key for this
account.
open System
open System.IO
open Microsoft.Azure // Namespace for CloudConfigurationManager
open Microsoft.WindowsAzure.Storage // Namespace for CloudStorageAccount
open Microsoft.WindowsAzure.Storage.File // Namespace for File storage types
However, this is not recommended for real projects. Your storage account key is similar to the root password for
your storage account. Always be careful to protect your storage account key. Avoid distributing it to other users,
hard-coding it, or saving it in a plain-text file that is accessible to others. You can regenerate your key using the
Azure Portal if you believe it may have been compromised.
For real applications, the best way to maintain your storage connection string is in a configuration file. To fetch the
connection string from a configuration file, you can do this:
// Parse the connection string and return a reference to the storage account.
let storageConnString =
CloudConfigurationManager.GetSetting("StorageConnectionString")
Using Azure Configuration Manager is optional. You can also use an API such as the .NET Framework's
ConfigurationManager type.
// Parse the connection string and return a reference to the storage account.
let storageAccount = CloudStorageAccount.Parse(storageConnString)
Now you are ready to write code that reads data from and writes data to File storage.
file.DownloadToFile("log.txt", FileMode.Append)
Set the maximum size for a file share
The example below shows how to check the current usage for a share and how to set the quota for the share.
FetchAttributes must be called to populate a share's Properties , and SetProperties to propagate local changes
to Azure File storage.
For more information about creating and using shared access signatures, see Using Shared Access Signatures
(SAS) and Create and use a SAS with Blob storage.
Copy files
You can copy a file to another file or to a blob, or a blob to a file. If you are copying a blob to a file, or a file to a
blob, you must use a shared access signature (SAS) to authenticate the source object, even if you are copying
within the same storage account.
Copy a file to another file
Here, you copy a file to another file in the same share. Because this copy operation copies between files in the same
storage account, you can use Shared Key authentication to perform the copy.
let filePolicy =
SharedAccessFilePolicy
(Permissions = SharedAccessFilePermissions.Read,
SharedAccessExpiryTime = (DateTimeOffset.UtcNow.AddHours(24.) |> Nullable))
You can copy a blob to a file in the same way. If the source object is a blob, then create a SAS to authenticate access
to that blob during the copy operation.
open Microsoft.WindowsAzure.Storage.File.Protocol
open Microsoft.WindowsAzure.Storage.Shared.Protocol
let props =
FileServiceProperties(
(HourMetrics = MetricsProperties(
MetricsLevel = MetricsLevel.ServiceAndApi,
RetentionDays = (14 |> Nullable),
Version = "1.0"),
MinuteMetrics = MetricsProperties(
MetricsLevel = MetricsLevel.ServiceAndApi,
RetentionDays = (7 |> Nullable),
Version = "1.0"))
fileClient.SetServiceProperties(props)
Next steps
See these links for more information about Azure File storage.
Conceptual articles and videos
Azure Files Storage: a frictionless cloud SMB file system for Windows and Linux
How to use Azure File Storage with Linux
Tooling support for File storage
Using Azure PowerShell with Azure Storage
How to use AzCopy with Microsoft Azure Storage
Using the Azure CLI with Azure Storage
Reference
Storage Client Library for .NET reference
File Service REST API reference
Blog posts
Azure File storage is now generally available
Inside Azure File Storage
Introducing Microsoft Azure File Service
Persisting connections to Microsoft Azure Files
Get started with Azure Queue storage using F#
7/29/2017 • 6 min to read • Edit Online
Azure Queue storage provides cloud messaging between application components. In designing applications for
scale, application components are often decoupled, so that they can scale independently. Queue storage delivers
asynchronous messaging for communication between application components, whether they are running in the
cloud, on the desktop, on an on-premises server, or on a mobile device. Queue storage also supports managing
asynchronous tasks and building process work flows.
About this tutorial
This tutorial shows how to write F# code for some common tasks using Azure Queue storage. Tasks covered
include creating and deleting queues and adding, reading, and deleting queue messages.
For a conceptual overview of queue storage, please see the .NET guide for queue storage.
Prerequisites
To use this guide, you must first create an Azure storage account. You'll also need your storage access key for this
account.
However, this is not recommended for real projects. Your storage account key is similar to the root password for
your storage account. Always be careful to protect your storage account key. Avoid distributing it to other users,
hard-coding it, or saving it in a plain-text file that is accessible to others. You can regenerate your key using the
Azure Portal if you believe it may have been compromised.
For real applications, the best way to maintain your storage connection string is in a configuration file. To fetch the
connection string from a configuration file, you can do this:
// Parse the connection string and return a reference to the storage account.
let storageConnString =
CloudConfigurationManager.GetSetting("StorageConnectionString")
Using Azure Configuration Manager is optional. You can also use an API such as the .NET Framework's
ConfigurationManager type.
// Parse the connection string and return a reference to the storage account.
let storageAccount = CloudStorageAccount.Parse(storageConnString)
Now you are ready to write code that reads data from and writes data to Queue storage.
Create a queue
This example shows how to create a queue if it doesn't already exist:
// Get the next message. Successful processing must be indicated via DeleteMessage later.
let retrieved = queue.GetMessage()
// Process the message in less than 30 seconds, and then delete the message.
queue.DeleteMessage(retrieved)
async {
let! exists = queue.CreateIfNotExistsAsync() |> Async.AwaitTask
queue.FetchAttributes()
let count = queue.ApproximateMessageCount.GetValueOrDefault()
Delete a queue
To delete a queue and all the messages contained in it, call the Delete method on the queue object.
Next steps
Now that you've learned the basics of Queue storage, follow these links to learn about more complex storage tasks.
Storage Client Library for .NET reference
Azure Storage Type Provider
Azure Storage Team Blog
Configuring Connection Strings
REST API reference
Get started with Azure Table storage using F#
8/5/2017 • 8 min to read • Edit Online
Azure Table storage is a service that stores structured NoSQL data in the cloud. Table storage is a key/attribute
store with a schemaless design. Because Table storage is schemaless, it's easy to adapt your data as the needs of
your application evolve. Access to data is fast and cost-effective for all kinds of applications. Table storage is
typically significantly lower in cost than traditional SQL for similar volumes of data.
You can use Table storage to store flexible datasets, such as user data for web applications, address books, device
information, and any other type of metadata that your service requires. You can store any number of entities in a
table, and a storage account may contain any number of tables, up to the capacity limit of the storage account.
About this tutorial
This tutorial shows how to write F# code to do some common tasks using Azure Table storage, including creating
and deleting a table and inserting, updating, deleting, and querying table data.
For a conceptual overview of table storage, please see the .NET guide for table storage
Prerequisites
To use this guide, you must first create an Azure storage account. You'll also need your storage access key for this
account.
open System
open System.IO
open Microsoft.Azure // Namespace for CloudConfigurationManager
open Microsoft.WindowsAzure.Storage // Namespace for CloudStorageAccount
open Microsoft.WindowsAzure.Storage.Table // Namespace for Table storage types
However, this is not recommended for real projects. Your storage account key is similar to the root password for
your storage account. Always be careful to protect your storage account key. Avoid distributing it to other users,
hard-coding it, or saving it in a plain-text file that is accessible to others. You can regenerate your key using the
Azure Portal if you believe it may have been compromised.
For real applications, the best way to maintain your storage connection string is in a configuration file. To fetch the
connection string from a configuration file, you can do this:
// Parse the connection string and return a reference to the storage account.
let storageConnString =
CloudConfigurationManager.GetSetting("StorageConnectionString")
Using Azure Configuration Manager is optional. You can also use an API such as the .NET Framework's
ConfigurationManager type.
// Parse the connection string and return a reference to the storage account.
let storageAccount = CloudStorageAccount.Parse(storageConnString)
Now you are ready to write code that reads data from and writes data to Table storage.
Create a table
This example shows how to create a table if it does not already exist:
let customer =
Customer("Walter", "Harp", "[email protected]", "425-555-0101")
Now we'll add our Customer to the table. To do so, you create a TableOperation that will execute on the table. In
this case, you create an Insert operation.
let customer1 =
Customer("Jeff", "Smith", "[email protected]", "425-555-0102")
let customer2 =
Customer("Ben", "Smith", "[email protected]", "425-555-0103")
let query =
TableQuery<Customer>().Where(
TableQuery.GenerateFilterCondition(
"PartitionKey", QueryComparisons.Equal, "Smith"))
let range =
TableQuery<Customer>().Where(
TableQuery.CombineFilters(
TableQuery.GenerateFilterCondition(
"PartitionKey", QueryComparisons.Equal, "Smith"),
TableOperators.And,
TableQuery.GenerateFilterCondition(
"RowKey", QueryComparisons.LessThan, "M")))
Replace an entity
To update an entity, retrieve it from the Table service, modify the entity object, and then save the changes back to
the Table service using a Replace operation. This causes the entity to be fully replaced on the server, unless the
entity on the server has changed since it was retrieved, in which case the operation will fail. This failure is to
prevent your application from inadvertently overwriting changes from other sources.
try
let customer = retrieveResult.Result :?> Customer
customer.PhoneNumber <- "425-555-0103"
let replaceOp = TableOperation.Replace(customer)
table.Execute(replaceOp) |> ignore
Console.WriteLine("Update succeeeded")
with e ->
Console.WriteLine("Update failed")
Insert-or-replace an entity
Sometimes, you don't know if the entity exists in the table or not. And if it does, the current values stored in it are
no longer needed. You can use InsertOrReplace to create the entity, or replace it if it exists, regardless of its state.
try
customer.PhoneNumber <- "425-555-0104"
let replaceOp = TableOperation.InsertOrReplace(customer)
table.Execute(replaceOp) |> ignore
Console.WriteLine("Update succeeeded")
with e ->
Console.WriteLine("Update failed")
let asyncQuery =
let rec loop (cont: TableContinuationToken) = async {
let! ct = Async.CancellationToken
let! result = table.ExecuteQuerySegmentedAsync(tableQ, cont, ct) |> Async.AwaitTask
Delete an entity
You can delete an entity after you have retrieved it. As with updating an entity, this will fail if the entity has changed
since you retrieved it.
Delete a table
You can delete a table from a storage account. A table that has been deleted will be unavailable to be re-created for
a period of time following the deletion.
table.DeleteIfExists()
Next steps
Now that you've learned the basics of Table storage, follow these links to learn about more complex storage tasks:
Storage Client Library for .NET reference
Azure Storage Type Provider
Azure Storage Team Blog
Configuring Connection Strings
Getting Started with Azure Table Storage in .NET
Package Management for F# Azure Dependencies
7/29/2017 • 2 min to read • Edit Online
Obtaining packages for Azure development is easy when you use a package manager. The two options are Paket
and NuGet.
Using Paket
If you're using Paket as your dependency manager, you can use the paket.exe tool to add Azure dependencies.
For example:
This will add WindowsAzure.Storage to your set of package dependencies for the project in the current directory,
modify the paket.dependencies file, and download the package. If you have previously set up dependencies, or are
working with a project where dependencies have been set up by another developer, you can resolve and install
dependencies locally like this:
You can update all your package dependencies to the latest version like this:
Using Nuget
If you're using NuGet as your dependency manager, you can use the nuget.exe tool to add Azure dependencies.
For example:
This will add WindowsAzure.Storage to your set of package dependencies for the project in the current directory,
and download the package. If you have previously set up dependencies, or are working with a project where
dependencies have been set up by another developer, you can resolve and install dependencies locally like this:
You can update all your package dependencies to the latest version like this:
Referencing Assemblies
In order to use your packages in your F# script, you need to reference the assemblies included in the packages
using a #r directive. For example:
> #r "packages/WindowsAzure.Storage/lib/net40/Microsoft.WindowsAzure.Storage.dll"
As you can see, you'll need to specify the relative path to the DLL and the full DLL name, which may not be exactly
the same as the package name. The path will include a framework version and possibly a package version number.
To find all the installed assemblies, you can use something like this on a Windows command line:
> cd packages/WindowsAzure.Storage
> dir /s/b *.dll
This will give you the paths to the installed assemblies. From there, you can select the correct path for your
framework version.
F# Language Reference
8/5/2017 • 8 min to read • Edit Online
This section is a reference to the F# language, a multi-paradigm programming language targeting .NET.
The F# language supports functional, object-oriented and imperative programming models.
F# Tokens
The following table shows reference topics that provide tables of keywords, symbols and literals used as
tokens in F#.
TITLE DESCRIPTION
Symbol and Operator Reference Contains a table of symbols and operators that are used
in the F# language.
F# Language Concepts
The following table shows reference topics available that describe language concepts.
TITLE DESCRIPTION
Type Inference Describes how the F# compiler infers the types of values,
variables, parameters and return values.
Parameters and Arguments Describes language support for defining parameters and
passing arguments to functions, methods, and
properties. It includes information about how to pass by
reference.
Resource Management: The use Keyword Describes the keywords use and using , which can
control the initialization and release of resources
Import Declarations: The open Keyword Describes how open works. An import declaration
specifies a module or namespace whose elements you
can reference without using a fully qualified name.
TITLE DESCRIPTION
F# Types
The following table shows reference topics available that describe types supported by the F# language.
TITLE DESCRIPTION
Primitive Types Describes the fundamental primitive types that are used
in the F# language. It also provides the corresponding
.NET types and the minimum and maximum values for
each type.
Unit Type Describes the unit type, which is a type that indicates
the absence of a specific value; the unit type has only
a single value, which acts as a placeholder when no other
value exists or is needed.
Reference Cells Describes reference cells, which are storage locations that
enable you to create mutable variables with reference
semantics.
Abstract Classes Describes abstract classes, which are classes that leave
some or all members unimplemented, so that
implementations can be provided by derived classes.
Type Extensions Describes type extensions, which let you add new
members to a previously defined object type.
F# Expressions
The following table lists topics that describe F# expressions.
TITLE DESCRIPTION
Compiler-supported Constructs
The following table lists topics that describe special compiler-supported constructs.
TOPIC DESCRIPTION
Source Line, File, and Path Identifiers Describes the identifiers __LINE__ ,
__SOURCE_DIRECTORY__ and __SOURCE_FILE__ , which
are built-in values that enable you to access the source
line number, directory and file name in your code.
See Also
Visual F#
Keyword Reference
7/29/2017 • 7 min to read • Edit Online
F# Keyword Table
The following table shows all F# keywords in alphabetical order, together with brief descriptions and links to
relevant topics that contain more information.
Constraints
Verbose Syntax
Exception Types
fun Lambda Expressions: The fun Used in lambda expressions, also known
Keyword as anonymous functions.
Exception Types
try Exceptions: The try...with Expression Used to introduce a block of code that
might generate an exception. Used
Exceptions: The try...finally Expression together with with or finally .
Structures
Enumerations
Discriminated Unions
Type Abbreviations
Units of Measure
use Resource Management: The use Used instead of let for values that
Keyword require Dispose to be called to free
resources.
val Explicit Fields: The val Keyword Used in a signature to indicate a value,
or in a type to declare a member, in
Signatures limited situations.
Members
The following tokens are reserved in F# because they are keywords in the OCaml language:
asr
land
lor
lsl
lsr
lxor
mod
sig
If you use the --mlcompatibility compiler option, the above keywords are available for use as identifiers.
The following tokens are reserved as keywords for future expansion of the F# language:
atomic
break
checked
component
const
constraint
constructor
continue
eager
event
external
fixed
functor
include
method
mixin
object
parallel
process
protected
pure
sealed
tailcall
trait
virtual
volatile
See Also
F# Language Reference
Symbol and Operator Reference
Compiler Options
Symbol and Operator Reference
7/29/2017 • 8 min to read • Edit Online
NOTE
The API reference links in this article will take you to MSDN. The docs.microsoft.com API reference is not complete.
This topic includes a table of symbols and operators that are used in the F# language.
? ... <- ... No more information available. Used as an operator for setting
dynamic properties. You must
provide your own
implementation.
Operator Precedence
The following table shows the order of precedence of operators and other expression keywords in the F#
language, in order from lowest precedence to the highest precedence. Also listed is the associativity, if applicable.
OPERATOR ASSOCIATIVITY
as Right
when Right
| (pipe) Left
; Right
let Nonassociative
if Nonassociative
-> Right
:= Right
, Nonassociative
or , || Left
!= op, < op, > op, = , | op, & op, & Left
^ op Right
(including ^^^ )
:: Right
:? Not associative
** op Right
. Left
f(x) Left
F# supports custom operator overloading. This means that you can define your own operators. In the previous
table, op can be any valid (possibly empty) sequence of operator characters, either built-in or user-defined. Thus,
you can use this table to determine what sequence of characters to use for a custom operator to achieve the
desired level of precedence. Leading . characters are ignored when the compiler determines precedence.
See Also
F# Language Reference
Operator Overloading
Arithmetic Operators
8/10/2017 • 3 min to read • Edit Online
This topic describes arithmetic operators that are available in the F# language.
** (exponentiation, to the power of) Possible overflow condition when the result exceeds the
maximum absolute value for the type.
OPERATOR NOTES
See Also
Symbol and Operator Reference
Operator Overloading
Bitwise Operators
Boolean Operators
Boolean Operators
7/29/2017 • 1 min to read • Edit Online
This topic describes the support for Boolean operators in the F# language.
OPERATOR DESCRIPTION
|| Boolean OR
The Boolean AND and OR operators perform short-circuit evaluation, that is, they evaluate the expression on the
right of the operator only when it is necessary to determine the overall result of the expression. The second
expression of the && operator is evaluated only if the first expression evaluates to true ; the second expression of
the || operator is evaluated only if the first expression evaluates to false .
See Also
Bitwise Operators
Arithmetic Operators
Symbol and Operator Reference
Bitwise Operators
7/29/2017 • 1 min to read • Edit Online
This topic describes bitwise operators that are available in the F# language.
OPERATOR NOTES
&&& Bitwise AND operator. Bits in the result have the value 1 if
and only if the corresponding bits in both source operands
are 1.
<<< Bitwise left-shift operator. The result is the first operand with
bits shifted left by the number of bits in the second operand.
Bits shifted off the most significant position are not rotated
into the least significant position. The least significant bits are
padded with zeros. The type of the second argument is
int32 .
The following types can be used with bitwise operators: byte , sbyte , int16 , uint16 , int32 (int) , uint32 ,
int64 , uint64 , nativeint , and unativeint .
See Also
Symbol and Operator Reference
Arithmetic Operators
Boolean Operators
Nullable Operators
7/29/2017 • 3 min to read • Edit Online
Nullable operators are binary arithmetic or comparison operators that work with nullable arithmetic types on
one or both sides. Nullable types arise frequently when you work with data from sources such as databases that
allow nulls in place of actual values. Nullable operators are used frequently in query expressions. In addition to
nullable operators for arithmetic and comparison, conversion operators can be used to convert between
nullable types. There are also nullable versions of certain query operators.
?= =? ?=?
?+ +? ?+?
?- -? ?-?
?* *? ?*?
?/ /? ?/?
?% %? ?%?
Remarks
The nullable operators are included in the NullableOperators module in the namespace Microsoft.FSharp.Linq.
The type for nullable data is System.Nullable<'T> .
In query expressions, nullable types arise when selecting data from a data source that allows nulls instead of
values. In a SQL Server database, each data column in a table has an attribute that indicates whether nulls are
allowed. If nulls are allowed, the data returned from the database can contain nulls that cannot be represented
by a primitive data type such as int , float , and so on. Therefore, the data is returned as a
System.Nullable<int> instead of int , and System.Nullable<float> instead of float . The actual value can be
obtained from a System.Nullable<'T> object by using the Value property, and you can determine if a
System.Nullable<'T> object has a value by calling the HasValue method. Another useful method is the
System.Nullable<'T>.GetValueOrDefault method, which allows you to get the value or a default value of the
appropriate type. The default value is some form of "zero" value, such as 0, 0.0, or false .
Nullable types may be converted to non-nullable primitive types using the usual conversion operators such as
int or float . It is also possible to convert from one nullable type to another nullable type by using the
conversion operators for nullable types. The appropriate conversion operators have the same name as the
standard ones, but they are in a separate module, the Nullable module in the Microsoft.FSharp.Linq namespace.
Typically, you open this namespace when working with query expressions. In that case, you can use the nullable
conversion operators by adding the prefix Nullable. to the appropriate conversion operator, as shown in the
following code.
open Microsoft.FSharp.Linq
// Use the Nullable.float conversion operator to convert from one nullable type to another nullable type.
let nullableFloat = Nullable.float nullableInt
open System
open System.Data
open System.Data.Linq
open Microsoft.FSharp.Data.TypeProviders
open Microsoft.FSharp.Linq
[<Generate>]
type dbSchema = SqlDataConnection<"Data Source=MYSERVER\INSTANCE;Initial Catalog=MyDatabase;Integrated
Security=SSPI;">
let db = dbSchema.GetDataContext()
query {
for row in db.Table2 do
where (row.TestData1.HasValue && row.TestData1.Value > 2)
select row
} |> Seq.iter (fun row -> printfn "%d %s" row.TestData1.Value row.Name)
query {
for row in db.Table2 do
// Use a nullable operator ?>
where (row.TestData1 ?> 2)
select row
} |> Seq.iter (fun row -> printfn "%d %s" (row.TestData1.GetValueOrDefault()) row.Name)
See Also
Type Providers
Query Expressions
Functions
7/29/2017 • 9 min to read • Edit Online
Functions are the fundamental unit of program execution in any programming language. As in other
languages, an F# function has a name, can have parameters and take arguments, and has a body. F# also
supports functional programming constructs such as treating functions as values, using unnamed functions in
expressions, composition of functions to form new functions, curried functions, and the implicit definition of
functions by way of the partial application of function arguments.
You define functions by using the let keyword, or, if the function is recursive, the let rec keyword
combination.
Syntax
// Non-recursive function definition.
let [inline] function-name parameter-list [ : return-type ] = function-body
// Recursive function definition.
let rec function-name parameter-list = recursive-function-body
Remarks
The function-name is an identifier that represents the function. The parameter-list consists of successive
parameters that are separated by spaces. You can specify an explicit type for each parameter, as described in
the Parameters section. If you do not specify a specific argument type, the compiler attempts to infer the type
from the function body. The function-body consists of an expression. The expression that makes up the
function body is typically a compound expression consisting of a number of expressions that culminate in a
final expression that is the return value. The return-type is a colon followed by a type and is optional. If you do
not specify the type of the return value explicitly, the compiler determines the return type from the final
expression.
A simple function definition resembles the following:
let f x = x + 1
In the previous example, the function name is f , the argument is x , which has type int , the function body
is x + 1 , and the return value is of type int .
Functions can be marked inline . For information about inline , see Inline Functions.
Scope
At any level of scope other than module scope, it is not an error to reuse a value or function name. If you
reuse a name, the name declared later shadows the name declared earlier. However, at the top level scope in a
module, names must be unique. For example, the following code produces an error when it appears at
module scope, but not when it appears inside a function:
let list1 = [ 1; 2; 3]
// Error: duplicate definition.
let list1 = []
let function1 =
let list1 = [1; 2; 3]
let list1 = []
list1
let list1 = [ 1; 2; 3]
let sumPlus x =
// OK: inner list1 hides the outer list1.
let list1 = [1; 5; 10]
x + List.sum list1
Parameters
Names of parameters are listed after the function name. You can specify a type for a parameter, as shown in
the following example:
let f (x : int) = x + 1
If you specify a type, it follows the name of the parameter and is separated from the name by a colon. If you
omit the type for the parameter, the parameter type is inferred by the compiler. For example, in the following
function definition, the argument x is inferred to be of type int because 1 is of type int .
let f x = x + 1
However, the compiler will attempt to make the function as generic as possible. For example, note the
following code:
let f x = (x, x)
The function creates a tuple from one argument of any type. Because the type is not specified, the function can
be used with any argument type. For more information, see Automatic Generalization.
Function Bodies
A function body can contain definitions of local variables and functions. Such variables and functions are in
scope in the body of the current function but not outside it. When you have the lightweight syntax option
enabled, you must use indentation to indicate that a definition is in a function body, as shown in the following
example:
For more information, see Code Formatting Guidelines and Verbose Syntax.
Return Values
The compiler uses the final expression in a function body to determine the return value and type. The
compiler might infer the type of the final expression from previous expressions. In the function
cylinderVolume , shown in the previous section, the type of pi is determined from the type of the literal
3.14159 to be float . The compiler uses the type of pi to determine the type of the expression
h * pi * r * r to be float . Therefore, the overall return type of the function is float .
As the code is written above, the compiler applies float to the entire function; if you mean to apply it to the
parameter types as well, use the following code:
Calling a Function
You call functions by specifying the function name followed by a space and then any arguments separated by
spaces. For example, to call the function cylinderVolume and assign the result to the value vol, you write the
following code:
You would then supply the additional argument as needed for various lengths of pipe of the two different
sizes:
Some recursive functions might overflow the program stack or perform inefficiently if you do not write them
with care and with awareness of special techniques, such as the use of accumulators and continuations.
Function Values
In F#, all functions are considered values; in fact, they are known as function values. Because functions are
values, they can be used as arguments to other functions or in other contexts where values are used.
Following is an example of a function that takes a function value as an argument:
You specify the type of a function value by using the -> token. On the left side of this token is the type of the
argument, and on the right side is the return value. In the previous example, apply1 is a function that takes a
function transform as an argument, where transform is a function that takes an integer and returns another
integer. The following code shows how to use apply1 :
let increment x = x + 1
The value of result will be 101 after the previous code runs.
Multiple arguments are separated by successive -> tokens, as shown in the following example:
let mul x y = x * y
Lambda Expressions
A lambda expression is an unnamed function. In the previous examples, instead of defining named functions
increment and mul, you could use lambda expressions as follows:
You define lambda expressions by using the fun keyword. A lambda expression resembles a function
definition, except that instead of the = token, the -> token is used to separate the argument list from the
function body. As in a regular function definition, the argument types can be inferred or specified explicitly,
and the return type of the lambda expression is inferred from the type of the last expression in the body. For
more information, see Lambda Expressions: The fun Keyword.
let function1 x = x + 1
let function2 x = x * 2
let h = function1 >> function2
let result5 = h 100
let addOne x = x + 1
let timesTwo x = 2 * x
// Composition operator
// ( >> ) : ('T1 -> 'T2) -> ('T2 -> 'T3) -> 'T1 -> 'T3
let Compose2 = addOne >> timesTwo
// Result is 5
let result1 = Compose1 2
// Result is 6
let result2 = Compose2 2
// Pipelining
// Pipeline operator
// ( |> ) : 'T1 -> ('T1 -> 'U) -> 'U
let Pipeline1 x = addOne <| timesTwo x
// Result is 5
let result3 = Pipeline1 2
// Result is 6
let result4 = Pipeline2 2
Overloading Functions
You can overload methods of a type but not functions. For more information, see Methods.
See Also
Values
F# Language Reference
let Bindings
7/29/2017 • 5 min to read • Edit Online
A binding associates an identifier with a value or function. You use the let keyword to bind a name to a value or
function.
Syntax
// Binding a value:
let identifier-or-pattern [: type] =expressionbody-expression
// Binding a function value:
let identifier parameter-list [: return-type ] =expressionbody-expression
Remarks
The let keyword is used in binding expressions to define values or function values for one or more names. The
simplest form of the let expression binds a name to a simple value, as follows.
let i = 1
If you separate the expression from the identifier by using a new line, you must indent each line of the expression,
as in the following code.
let someVeryLongIdentifier =
// Note indentation below.
3 * 4 + 5 * 6
Instead of just a name, a pattern that contains names can be specified, for example, a tuple, as shown in the
following code.
let i, j, k = (1, 2, 3)
The body-expression is the expression in which the names are used. The body expression appears on its own line,
indented to line up exactly with the first character in the let keyword:
let result =
let i, j, k = (1, 2, 3)
// Body expression:
i + 2*j + 3*k
A let binding can appear at the module level, in the definition of a class type, or in local scopes, such as in a
function definition. A let binding at the top level in a module or in a class type does not need to have a body
expression, but at other scope levels, the body expression is required. The bound names are usable after the point
of definition, but not at any point before the let binding appears, as is illustrated in the following code.
// Error:
printfn "%d" x
let x = 100
// OK:
printfn "%d" x
Function Bindings
Function bindings follow the rules for value bindings, except that function bindings include the function name
and the parameters, as shown in the following code.
let function1 a =
a + 1
A let binding expression evaluates to the value of the last expression. Therefore, in the following code example,
the value of result is computed from 100 * function3 (1, 2) , which evaluates to 300 .
let result =
let function3 (a, b) = a + b
100 * function3 (1, 2)
Type Annotations
You can specify types for parameters by including a colon (:) followed by a type name, all enclosed in
parentheses. You can also specify the type of the return value by appending the colon and type after the last
parameter. The full type annotations for function1 , with integers as the parameter types, would be as follows.
When there are no explicit type parameters, type inference is used to determine the types of parameters of
functions. This can include automatically generalizing the type of a parameter to be generic.
For more information, see Automatic Generalization and Type Inference.
The scopes of field1 and field2 are limited to the type in which they are declared. For more information, see
let Bindings in Classes and Classes.
[<Obsolete>]
let function1 x y = x + y
module Module1 =
let function1 x = x + 1.0
module Module2 =
let function2 x =
Module1.function1 x
open Module1
let function3 x =
function1 x
Some modules have the attribute RequireQualifiedAccess, which means that the functions that they expose must
be qualified with the name of the module. For example, the F# List module has this attribute.
For more information on modules and access control, see Modules and Access Control.
See Also
Functions
let Bindings in Classes
do Bindings
7/29/2017 • 1 min to read • Edit Online
A do binding is used to execute code without defining a function or value. Also, do bindings can be used in classes,
see do Bindings in Classes.
Syntax
[ attributes ]
[ do ]expression
Remarks
Use a do binding when you want to execute code independently of a function or value definition. The expression
in a do binding must return unit . Code in a top-level do binding is executed when the module is initialized. The
keyword do is optional.
Attributes can be applied to a top-level do binding. For example, if your program uses COM interop, you might
want to apply the STAThread attribute to your program. You can do this by using an attribute on a do binding, as
shown in the following code.
open System
open System.Windows.Forms
[<STAThread>]
do
Application.Run(form1)
See Also
F# Language Reference
Functions
Lambda Expressions: The fun Keyword (F#)
7/29/2017 • 1 min to read • Edit Online
The fun keyword is used to define a lambda expression, that is, an anonymous function.
Syntax
fun parameter-list -> expression
Remarks
The parameter-list typically consists of names and, optionally, types of parameters. More generally, the
parameter-list can be composed of any F# patterns. For a full list of possible patterns, see Pattern Matching. Lists
of valid parameters include the following examples.
The expression is the body of the function, the last expression of which generates a return value. Examples of valid
lambda expressions include the following:
fun x -> x + 1
fun a b c -> printfn "%A %A %A" a b c
fun (a: int) (b: int) (c: int) -> a + b * c
fun x y -> let swap (a, b) = (b, a) in swap (x, y)
See Also
Functions
Recursive Functions: The rec Keyword
7/29/2017 • 1 min to read • Edit Online
The rec keyword is used together with the let keyword to define a recursive function.
Syntax
// Recursive function:
let rec function-nameparameter-list =
function-body
Remarks
Recursive functions, functions that call themselves, are identified explicitly in the F# language. This makes the
identifer that is being defined available in the scope of the function.
The following code illustrates a recursive function that computes the nth Fibonacci number.
NOTE
In practice, code like that above is wasteful of memory and processor time because it involves the recomputation of
previously computed values.
Methods are implicitly recursive within the type; there is no need to add the rec keyword. Let bindings within
classes are not implicitly recursive.
See Also
Functions
Entry Point
7/29/2017 • 1 min to read • Edit Online
This topic describes the method that you use to set the entry point to an F# program.
Syntax
[<EntryPoint>]
let-function-binding
Remarks
In the previous syntax, let-function-binding is the definition of a function in a let binding.
The entry point to a program that is compiled as an executable file is where execution formally starts. You specify
the entry point to an F# application by applying the EntryPoint attribute to the program's main function. This
function (created by using a let binding) must be the last function in the last compiled file. The last compiled file is
the last file in the project or the last file that is passed to the command line.
The entry point function has type string array -> int . The arguments provided on the command line are passed
to the main function in the array of strings. The first element of the array is the first argument; the name of the
executable file is not included in the array, as it is in some other languages. The return value is used as the exit code
for the process. Zero usually indicates success; nonzero values indicate an error. There is no convention for the
specific meaning of nonzero return codes; the meanings of the return codes are application-specific.
The following example illustrates a simple main function.
[<EntryPoint>]
let main args =
printfn "Arguments passed to function : %A" args
// Return 0. This indicates success.
0
When this code is executed with the command line EntryPoint.exe 1 2 3 , the output is as follows.
See Also
Functions
let Bindings
External Functions
7/29/2017 • 1 min to read • Edit Online
This topic describes F# language support for calling functions in native code.
Syntax
[<DllImport( arguments )>]
extern declaration
Remarks
In the previous syntax, arguments represents arguments that are supplied to the
System.Runtime.InteropServices.DllImportAttribute attribute. The first argument is a string that represents the
name of the DLL that contains this function, without the .dll extension. Additional arguments can be supplied for
any of the public properties of the System.Runtime.InteropServices.DllImportAttribute class, such as the calling
convention.
Assume you have a native C++ DLL that contains the following exported function.
#include <stdio.h>
extern "C" void __declspec(dllexport) HelloWorld()
{
printf("Hello world, invoked by F#!\n");
}
You can call this function from F# by using the following code.
open System.Runtime.InteropServices
module InteropWithNative =
[<DllImport(@"C:\bin\nativedll", CallingConvention = CallingConvention.Cdecl)>]
extern void HelloWorld()
InteropWithNative.HelloWorld()
Interoperability with native code is referred to as platform invoke and is a feature of the CLR. For more information,
see Interoperating with Unmanaged Code. The information in that section is applicable to F#.
See Also
Functions
Inline Functions
7/29/2017 • 1 min to read • Edit Online
Inline functions are functions that are integrated directly into the calling code.
Without the inline modifier, type inference forces the function to take a specific type, in this case int . But with
the inline modifier, the function is also inferred to have a statically resolved type parameter. With the inline
modifier, the type is inferred to be the following:
This means that the function accepts any type that supports a conversion to float.
See Also
Functions
Constraints
Statically Resolved Type Parameters
Values
7/29/2017 • 2 min to read • Edit Online
Values in F# are quantities that have a specific type; values can be integral or floating point numbers, characters or
text, lists, sequences, arrays, tuples, discriminated unions, records, class types, or function values.
Binding a Value
The term binding means associating a name with a definition. The let keyword binds a value, as in the following
examples:
let a = 1
let b = 100u
let str = "text"
let f x = x + 1
The type of a value is inferred from the definition. For a primitive type, such as an integral or floating point
number, the type is determined from the type of the literal. Therefore, in the previous example, the compiler infers
the type of b to be unsigned int , whereas the compiler infers the type of a to be int . The type of a function
value is determined from the return value in the function body. For more information about function value types,
see Functions. For more information about literal types, see Literals.
Why Immutable?
Immutable values are values that cannot be changed throughout the course of a program's execution. If you are
used to languages such as C++, Visual Basic, or C#, you might find it surprising that F# puts primacy over
immutable values rather than variables that can be assigned new values during the execution of a program.
Immutable data is an important element of functional programming. In a multithreaded environment, shared
mutable variables that can be changed by many different threads are difficult to manage. Also, with mutable
variables, it can sometimes be hard to tell if a variable might be changed when it is passed to another function.
In pure functional languages, there are no variables, and functions behave strictly as mathematical functions.
Where code in a procedural language uses a variable assignment to alter a value, the equivalent code in a
functional language has an immutable value that is the input, an immutable function, and different immutable
values as the output. This mathematical strictness allows for tighter reasoning about the behavior of the program.
This tighter reasoning is what enables compilers to check code more stringently and to optimize more effectively,
and helps make it easier for developers to understand and write correct code. Functional code is therefore likely to
be easier to debug than ordinary procedural code.
F# is not a pure functional language, yet it fully supports functional programming. Using immutable values is a
good practice because doing this allows your code to benefit from an important aspect of functional
programming.
Mutable Variables
You can use the keyword mutable to specify a variable that can be changed. Mutable variables in F# should
generally have a limited scope, either as a field of a type or as a local value. Mutable variables with a limited scope
are easier to control and are less likely to be modified in incorrect ways.
You can assign an initial value to a mutable variable by using the let keyword in the same way as you would
define a value. However, the difference is that you can subsequently assign new values to mutable variables by
using the <- operator, as in the following example.
let mutable x = 1
x <- x + 1
Related Topics
TITLE DESCRIPTION
let Bindings Provides information about using the let keyword to bind
names to values and functions.
See Also
Null Values
F# Language Reference
Null Values
7/29/2017 • 3 min to read • Edit Online
Null Value
The null value is not normally used in F# for values or variables. However, null appears as an abnormal value in
certain situations. If a type is defined in F#, null is not permitted as a regular value unless the AllowNullLiteral
attribute is applied to the type. If a type is defined in some other .NET language, null is a possible value, and when
you are interoperating with such types, your F# code might encounter null values.
For a type defined in F# and used strictly from F#, the only way to create a null value using the F# library directly is
to use Unchecked.defaultof or Array.zeroCreate. However, for an F# type that is used from other .NET languages, or
if you are using that type with an API that is not written in F#, such as the .NET Framework, null values can occur.
You can use the option type in F# when you might use a reference variable with a possible null value in another
.NET language. Instead of null, with an F# option type, you use the option value None if there is no object. You use
the option value Some(obj) with an object obj when there is an object. For more information, see Options.
The null keyword is a valid keyword in the F# language, and you have to use it when you are working with .NET
Framework APIs or other APIs that are written in another .NET language. The two situations in which you might
need a null value are when you call a .NET API and pass a null value as an argument, and when you interpret the
return value or an output parameter from a .NET method call.
To pass a null value to a .NET method, just use the null keyword in the calling code. The following code example
illustrates this.
open System
To interpret a null value that is obtained from a .NET method, use pattern matching if you can. The following code
example shows how to use pattern matching to interpret the null value that is returned from ReadLine when it
tries to read past the end of an input stream.
// Open a file and create a stream reader.
let fileStream1 =
try
System.IO.File.OpenRead("TextFile1.txt")
with
| :? System.IO.FileNotFoundException -> printfn "Error: TextFile1.txt not found."; exit(1)
Null values for F# types can also be generated in other ways, such as when you use Array.zeroCreate , which calls
Unchecked.defaultof . You must be careful with such code to keep the null values encapsulated. In a library
intended only for F#, you do not have to check for null values in every function. If you are writing a library for
interoperation with other .NET languages, you might have to add checks for null input parameters and throw an
ArgumentNullException , just as you do in C# or Visual Basic code.
You can use the following code to check if an arbitrary value is null.
See Also
Values
Match Expressions
Literals
8/16/2017 • 2 min to read • Edit Online
NOTE
The API reference links in this article will take you to MSDN (for now).
This topic provides a table that shows how to specify the type of a literal in F#.
Literal Types
The following table shows the literal types in F#. Characters that represent digits in hexadecimal notation are not
case-sensitive; characters that identify the type are case-sensitive.
0b00000101y
int32 86l
lf 0x00000000lf
TYPE DESCRIPTION SUFFIX OR PREFIX EXAMPLES
LF 0x0000000000000000LF
or
@"c:\filename"
or
"""<book
title="Paradise
Lost">"""
or
"string1" + "string2"
@"\\server\share"B
(ASCII)
Remarks
Unicode strings can contain explicit encodings that you can specify by using \u followed by a 16-bit hexadecimal
code or UTF-32 encodings that you can specify by using \U followed by a 32-bit hexadecimal code that
represents a Unicode surrogate pair.
As of F# 3.1, you can use the + sign to combine string literals. You can also use the bitwise or ( ||| ) operator to
combine enum flags. For example, the following code is legal in F# 3.1:
[<Literal>]
let Literal1 = "a" + "b"
[<Literal>]
let FileLocation = __SOURCE_DIRECTORY__ + "/" + __SOURCE_FILE__
[<Literal>]
let Literal2 = 1 ||| 64
[<Literal>]
let Literal3 = System.IO.FileAccess.Read ||| System.IO.FileAccess.Write
Named Literals
Values that are intended to be constants can be marked with the Literal attribute. This attribute has the effect of
causing a value to be compiled as a constant.
In pattern matching expressions, identifiers that begin with lowercase characters are always treated as variables to
be bound, rather than as literals, so you should generally use initial capitals when you define literals.
See Also
Core.LiteralAttribute Class
F# Types
7/29/2017 • 4 min to read • Edit Online
This topic describes the types that are used in F# and how F# types are named and described.
Summary of F# Types
Some types are considered primitive types, such as the Boolean type bool and integral and floating point types
of various sizes, which include types for bytes and characters. These types are described in Primitive Types.
Other types that are built into the language include tuples, lists, arrays, sequences, records, and discriminated
unions. If you have experience with other .NET languages and are learning F#, you should read the topics for each
of these types. Links to more information about these types are included in the Related Topics section of this
topic. These F#-specific types support styles of programming that are common to functional programming
languages. Many of these types have associated modules in the F# library that support common operations on
these types.
The type of a function includes information about the parameter types and return type.
The .NET Framework is the source of object types, interface types, delegate types, and others. You can define your
own object types just as you can in any other .NET language.
Also, F# code can define aliases, which are named type abbreviations, that are alternative names for types. You
might use type abbreviations when the type might change in the future and you want to avoid changing the code
that depends on the type. Or, you might use a type abbreviation as a friendly name for a type that can make code
easier to read and understand.
F# provides useful collection types that are designed with functional programming in mind. Using these collection
types helps you write code that is more functional in style. For more information, see F# Collection Types.
float
string
or
modules.type-name
or
namespaces.modules.type-name
int array
float[,]
or list<'a>
list<string>
ref<int>
Dictionary<int, string>
function type that has a single parameter-type1 -> return-type A function that takes an int and
parameter returns a string has type
int -> string
function type that has multiple parameter-type1 -> parameter-type2 A function that takes an int and a
parameters -> ... -> return-type float and returns a string has
type int -> float -> string
TYPE TYPE SYNTAX EXAMPLES
#seq<int>
Related Topics
TOPIC DESCRIPTION
Primitive Types Describes built-in simple types such as integral types, the
Boolean type, and character types.
Unit Type Describes the unit type, a type that has one value and that
is indicated by (); equivalent to void in C# and Nothing in
Visual Basic.
Options Describes the option type, a type that may either have a
value or be empty.
Discriminated Unions Describes the discriminated union type, a type whose values
can be any one of a set of possible types.
Interfaces Describes interface types, which are types that represent a set
of members that provide certain functionality but that
contain no data. An interface type must be implemented by
an object type to be useful.
This topic describes how the F# compiler infers the types of values, variables, parameters and return values.
let f a b = a + b + 100
You can influence type inference by changing the literals. If you make the 100 a uint32 by appending the suffix
u , the types of a , b , and the return value are inferred to be uint32 .
You can also influence type inference by using other constructs that imply restrictions on the type, such as
functions and methods that work with only a particular type.
Also, you can apply explicit type annotations to function or method parameters or to variables in expressions, as
shown in the following examples. Errors result if conflicts occur between different constraints.
You can also explicitly specify the return value of a function by providing a type annotation after all the
parameters.
let addu1 x y : uint32 =
x + y
A common case where a type annotation is useful on a parameter is when the parameter is an object type and
you want to use a member.
Automatic Generalization
If the function code is not dependent on the type of a parameter, the compiler considers the parameter to be
generic. This is called automatic generalization, and it can be a powerful aid to writing generic code without
increasing complexity.
For example, the following function combines two parameters of any type into a tuple.
Additional Information
Type inference is described in more detail in the F# Language Specification.
See Also
Automatic Generalization
Primitive Types
7/29/2017 • 1 min to read • Edit Online
This topic lists the fundamental primitive types that are used in the F# language. It also provides the
corresponding .NET types and the minimum and maximum values for each type.
NOTE
You can perform computations with integers too big for the 64-bit integer type by using the bigint type. bigint is not
considered a primitive type; it is an abbreviation for System.Numerics.BigInteger .
See Also
F# Language Reference
Unit Type
7/29/2017 • 1 min to read • Edit Online
The unit type is a type that indicates the absence of a specific value; the unit type has only a single value, which
acts as a placeholder when no other value exists or is needed.
Syntax
// The value of the unit type.
()
Remarks
Every F# expression must evaluate to a value. For expressions that do not generate a value that is of interest, the
value of type unit is used. The unit type resembles the void type in languages such as C# and C++.
The unit type has a single value, and that value is indicated by the token () .
The value of the unit type is often used in F# programming to hold the place where a value is required by the
language syntax, but when no value is needed or desired. An example might be the return value of a printf
function. Because the important actions of the printf operation occur in the function, the function does not have
to return an actual value. Therefore, the return value is of type unit .
Some constructs expect a unit value. For example, a do binding or any code at the top level of a module is
expected to evaluate to a unit value. The compiler reports a warning when a do binding or code at the top level
of a module produces a result other than the unit value that is not used, as shown in the following example.
let function1 x y = x + y
// The next line results in a compiler warning.
function1 10 20
// Changing the code to one of the following eliminates the warning.
// Use this when you do want the return value.
let result = function1 10 20
// Use this if you are only calling the function for its side effects,
// and do not want the return value.
function1 10 20 |> ignore
This warning is a characteristic of functional programming; it does not appear in other .NET programming
languages. In a purely functional program, in which functions do not have any side effects, the final return value is
the only result of a function call. Therefore, when the result is ignored, it is a possible programming error.
Although F# is not a purely functional programming language, it is a good practice to follow functional
programming style whenever possible.
See Also
Primitive
F# Language Reference
Strings
7/29/2017 • 3 min to read • Edit Online
NOTE
The API reference links in this article will take you to MSDN. The docs.microsoft.com API reference is not complete.
The stringtype represents immutable text as a sequence of Unicode characters. string is an alias for
System.String in the .NET Framework.
Remarks
String literals are delimited by the quotation mark (") character. The backslash character () is used to encode
certain special characters. The backslash and the next character together are known as an escape sequence.
Escape sequences supported in F# string literals are shown in the following table.
Backspace \b
Newline \n
Carriage return \r
Tab \t
Backslash \
Apostrophe \'
If preceded by the @ symbol, the literal is a verbatim string. This means that any escape sequences are ignored,
except that two quotation mark characters are interpreted as one quotation mark character.
Additionally, a string may be enclosed by triple quotes. In this case, all escape sequences are ignored, including
double quotation mark characters. To specify a string that contains an embedded quoted string, you can either
use a verbatim string or a triple-quoted string. If you use a verbatim string, you must specify two quotation mark
characters to indicate a single quotation mark character. If you use a triple-quoted string, you can use the single
quotation mark characters without them being parsed as the end of the string. This technique can be useful when
you work with XML or other structures that include embedded quotation marks.
// Using a verbatim string
let xmlFragment1 = @"<book author=""Milton, John"" title=""Paradise Lost"">"
In code, strings that have line breaks are accepted and the line breaks are interpreted literally as newlines, unless
a backslash character is the last character before the line break. Leading whitespace on the next line is ignored
when the backslash character is used. The following code produces a string str1 that has value "abc\n def"
and a string str2 that has value "abcdef" .
You can access individual characters in a string by using array-like syntax, as follows.
The output is b .
Or you can extract substrings by using array slice syntax, as shown in the following code.
abc
def
You can represent ASCII strings by arrays of unsigned bytes, type byte[] . You add the suffix B to a string literal
to indicate that it is an ASCII string. ASCII string literals used with byte arrays support the same escape sequences
as Unicode strings, except for the Unicode escape sequences.
String Operators
There are two ways to concatenate strings: by using the + operator or by using the ^ operator. The +
operator maintains compatibility with the .NET Framework string handling features.
The following example illustrates string concatenation.
String Class
Because the string type in F# is actually a .NET Framework System.String type, all the System.String members
are available. This includes the + operator, which is used to concatenate strings, the Length property, and the
Chars property, which returns the string as an array of Unicode characters. For more information about strings,
see System.String .
By using the Chars property of System.String , you can access the individual characters in a string by specifying
an index, as is shown in the following code.
String Module
Additional functionality for string handling is included in the String module in the FSharp.Core namespace. For
more information, see Core.String Module.
See Also
F# Language Reference
Tuples
7/29/2017 • 5 min to read • Edit Online
A tuple is a grouping of unnamed but ordered values, possibly of different types. Tuples can either be reference
types or structs.
Syntax
(element, ... , element)
struct(element, ... ,element )
Remarks
Each element in the previous syntax can be any valid F# expression.
Examples
Examples of tuples include pairs, triples, and so on, of the same or different types. Some examples are illustrated
in the following code.
(1, 2)
// Triple of strings.
("one", "two", "three")
You can also deconstruct a tuple via pattern matching outside of a match expression via let binding:
// Or as a struct
let struct (c, d) = struct (1, 2)
Or you can pattern match on tuples as inputs to functions:
If you need only one element of the tuple, the wildcard character (the underscore) can be used to avoid creating a
new name for a value that you do not need.
Copying elements from a reference tuple into a struct tuple is also simple:
The functions fst and snd (reference tuples only) return the first and second elements of a tuple, respectively.
There is no built-in function that returns the third element of a triple, but you can easily write one as follows.
Using Tuples
Tuples provide a convenient way to return multiple values from a function, as shown in the following example.
This example performs integer division and returns the rounded result of the operation as a first member of a
tuple pair and the remainder as a second member of the pair.
let divRem a b =
let x = a / b
let y = a % b
(x, y)
Tuples can also be used as function arguments when you want to avoid the implicit currying of function
arguments that is implied by the usual function syntax.
The usual syntax for defining the function let sum a b = a + b enables you to define a function that is the partial
application of the first argument of the function, as shown in the following code.
let sum a b = a + b
Using a tuple as the parameter disables currying. For more information, see "Partial Application of Arguments" in
Functions.
namespace CSharpTupleInterop
{
public static class Example
{
public static (int, int) AddOneToXAndY((int x, int y) a) =>
(a.x + 1, a.y + 1);
}
}
In your F# code, you can then pass a struct tuple as the parameter and consume the result as a struct tuple.
open TupleInterop
// Won't compile!
let f(t: struct(int*int)): int*int = t
You must pattern match on one tuple and construct the other with the constituent parts. For example:
// Pattern match on the result.
let (a, b) = (1, 2)
// Construct a new tuple from the parts you pattern matched on.
let struct (c, d) = struct (a, b)
See Also
F# Language Reference
F# Types
F# Collection Types
7/29/2017 • 15 min to read • Edit Online
By reviewing this topic, you can determine which F# collection type best suits a particular need. These collection types differ from the
collection types in the .NET Framework, such as those in the System.Collections.Generic namespace, in that the F# collection types are
designed from a functional programming perspective rather than an object-oriented perspective. More specifically, only the array collection
has mutable elements. Therefore, when you modify a collection, you create an instance of the modified collection instead of altering the
original collection.
Collection types also differ in the type of data structure in which objects are stored. Data structures such as hash tables, linked lists, and arrays
have different performance characteristics and a different set of available operations.
F# Collection Types
The following table shows F# collection types.
Array2D Module
Array3D Module
Table of Functions
This section compares the functions that are available on F# collection types. The computational complexity of the function is given, where N
is the size of the first collection, and M is the size of the second collection, if any. A dash (-) indicates that this function isn't available on the
collection. Because sequences are lazily evaluated, a function such as Seq.distinct may be O(1) because it returns immediately, although it still
affects the performance of the sequence when enumerated.
sort O(N log N) O(N log N) O(N log N) - - Sorts the collection
average by element value.
Elements are
O(N^2) worst case compared using
compare.
FUNCTION ARRAY LIST SEQUENCE MAP SET DESCRIPTION
sortBy O(N log N) O(N log N) O(N log N) - - Sorts the given list
average by using keys that
the given
O(N^2) worst case projection
provides. Keys are
compared using
compare.
See Also
F# Types
F# Language Reference
Lists
7/29/2017 • 23 min to read • Edit Online
NOTE
The API reference links in this article will take you to MSDN. The docs.microsoft.com API reference is not complete.
A list in F# is an ordered, immutable series of elements of the same type. To perform basic operations on lists,
use the functions in the List module.
let list123 = [ 1; 2; 3 ]
You can also put line breaks between elements, in which case the semicolons are optional. The latter syntax can
result in more readable code when the element initialization expressions are longer, or when you want to
include a comment for each element.
let list123 = [
1
2
3 ]
Normally, all list elements must be the same type. An exception is that a list in which the elements are specified
to be a base type can have elements that are derived types. Thus the following is acceptable, because both
Button and CheckBox derive from Control .
You can also define list elements by using a range indicated by integers separated by the range operator ( .. ),
as shown in the following code.
let list1 = [ 1 .. 10 ]
An empty list is specified by a pair of square brackets with nothing in between them.
// An empty list.
let listEmpty = []
You can also use a sequence expression to create a list. See Sequence Expressions for more information. For
example, the following code creates a list of squares of integers from 1 to 10.
You can concatenate lists that have compatible types by using the @ operator, as in the following code. If
list1 is [2; 3; 4] and list2 is [100; 2; 3; 4 ] , this code creates list3 as [2; 3; 4; 100; 2; 3; 4] .
Functions for performing operations on lists are available in the List module.
Because lists in F# are immutable, any modifying operations generate new lists instead of modifying existing
lists.
Lists in F# are implemented as singly linked lists, which means that operations that access only the head of the
list are O(1), and element access is O(n).
Properties
The list type supports the following properties:
let list1 = [ 1; 2; 3 ]
// Properties
printfn "list1.IsEmpty is %b" (list1.IsEmpty)
printfn "list1.Length is %d" (list1.Length)
printfn "list1.Head is %d" (list1.Head)
printfn "list1.Tail.Head is %d" (list1.Tail.Head)
printfn "list1.Tail.Tail.Head is %d" (list1.Tail.Tail.Head)
printfn "list1.Item(1) is %d" (list1.Item(1))
Using Lists
Programming with lists enables you to perform complex operations with a small amount of code. This section
describes common operations on lists that are important to functional programming.
Recursion with Lists
Lists are uniquely suited to recursive programming techniques. Consider an operation that must be performed
on every element of a list. You can do this recursively by operating on the head of the list and then passing the
tail of the list, which is a smaller list that consists of the original list without the first element, back again to the
next level of recursion.
To write such a recursive function, you use the cons operator ( :: ) in pattern matching, which enables you to
separate the head of a list from the tail.
The following code example shows how to use pattern matching to implement a recursive function that
performs operations on a list.
The previous code works well for small lists, but for larger lists, it could overflow the stack. The following code
improves on this code by using an accumulator argument, a standard technique for working with recursive
functions. The use of the accumulator argument makes the function tail recursive, which saves stack space.
The function RemoveAllMultiples is a recursive function that takes two lists. The first list contains the numbers
whose multiples will be removed, and the second list is the list from which to remove the numbers. The code in
the following example uses this recursive function to eliminate all the non-prime numbers from a list, leaving a
list of prime numbers as the result.
let IsPrimeMultipleTest n x =
x = n || x % n <> 0
let GetPrimesUpTo n =
let max = int (sqrt (float n))
RemoveAllMultiples [ 2 .. max ] [ 1 .. n ]
Primes Up To 100:
[2; 3; 5; 7; 11; 13; 17; 19; 23; 29; 31; 37; 41; 43; 47; 53; 59; 61; 67; 71; 73; 79; 83; 89; 97]
Module Functions
The List module provides functions that access the elements of a list. The head element is the fastest and easiest
to access. Use the property Head or the module function List.head. You can access the tail of a list by using the
Tail property or the List.tail function. To find an element by index, use the List.nth function. List.nth traverses
the list. Therefore, it is O(n). If your code uses List.nth frequently, you might want to consider using an array
instead of a list. Element access in arrays is O(1).
Boolean Operations on Lists
The List.isEmpty function determines whether a list has any elements.
The List.exists function applies a Boolean test to elements of a list and returns true if any element satisfies the
test. List.exists2 is similar but operates on successive pairs of elements in two lists.
The following code demonstrates the use of List.exists .
// Use List.exists to determine whether there is an element of a list satisfies a given Boolean expression.
// containsNumber returns true if any of the elements of the supplied list match
// the supplied number.
let containsNumber number list = List.exists (fun elem -> elem = number) list
let list0to3 = [0 .. 3]
printfn "For list %A, contains zero is %b" list0to3 (containsNumber 0 list0to3)
Lists [1; 2; 3; 4; 5] and [5; 4; 3; 2; 1] have at least one equal element at the same position.
You can use List.forall if you want to test whether all the elements of a list meet a condition.
let isAllZeroes list = List.forall (fun elem -> elem = 0.0) list
printfn "%b" (isAllZeroes [0.0; 0.0])
printfn "%b" (isAllZeroes [0.0; 1.0])
true
false
Similarly, List.forall2 determines whether all elements in the corresponding positions in two lists satisfy a
Boolean expression that involves each pair of elements.
let listEqual list1 list2 = List.forall2 (fun elem1 elem2 -> elem1 = elem2) list1 list2
printfn "%b" (listEqual [0; 1; 2] [0; 1; 2])
printfn "%b" (listEqual [0; 0; 0] [0; 1; 0])
true
false
[-2; 1; 4; 5; 8]
let sortedList2 = List.sortBy (fun elem -> abs elem) [1; 4; 8; -2; 5]
printfn "%A" sortedList2
[1; -2; 4; 5; 8]
The next example demonstrates the use of List.sortWith . In this example, the custom comparison function
compareWidgets is used to first compare one field of a custom type, and then another when the values of the
first field are equal.
type Widget = { ID: int; Rev: int }
let listToCompare = [
{ ID = 92; Rev = 1 }
{ ID = 110; Rev = 1 }
{ ID = 100; Rev = 5 }
{ ID = 100; Rev = 2 }
{ ID = 92; Rev = 1 }
]
[{ID = 92;
Rev = 1;}; {ID = 92;
Rev = 1;}; {ID = 100;
Rev = 2;}; {ID = 100;
Rev = 5;}; {ID = 110;
Rev = 1;}]
The result is 5.
If the elements must be transformed first, call List.pick, which takes a function that returns an option, and looks
for the first option value that is Some(x) . Instead of returning the element, List.pick returns the result x . If
no matching element is found, List.pick throws System.Collections.Generic.KeyNotFoundException . The
following code shows the use of List.pick .
Another group of search operations, List.tryFind and related functions, return an option value. The List.tryFind
function returns the first element of a list that satisfies a condition if such an element exists, but the option value
None if not. The variation List.tryFindIndex returns the index of the element, if one is found, rather than the
element itself. These functions are illustrated in the following code.
let list1d = [1; 3; 7; 9; 11; 13; 15; 19; 22; 29; 36]
let isEven x = x % 2 = 0
match List.tryFind isEven list1d with
| Some value -> printfn "The first even value is %d." value
| None -> printfn "There is no even value in the list."
// Compute the sum of the squares of the elements of a list by using List.sumBy.
let sum2 = List.sumBy (fun elem -> elem*elem) [1 .. 10]
let list1 = [ 1; 2; 3 ]
let list2 = [ -1; -2; -3 ]
let listZip = List.zip list1 list2
printfn "%A" listZip
let list3 = [ 0; 0; 0]
let listZip3 = List.zip3 list1 list2 list3
printfn "%A" listZip3
The corresponding unzip versions, List.unzip and List.unzip3, take lists of tuples and return lists in a tuple, where
the first list contains all the elements that were first in each tuple, and the second list contains the second
element of each tuple, and so on.
The following code example demonstrates the use of List.unzip.
List.iter: element is 1
List.iter: element is 2
List.iter: element is 3
List.iteri: element 0 is 1
List.iteri: element 1 is 2
List.iteri: element 2 is 3
List.iter2: elements are 1 4
List.iter2: elements are 2 5
List.iter2: elements are 3 6
List.iteri2: element 0 of list1 is 1; element 0 of list2 is 4
List.iteri2: element 1 of list1 is 2; element 1 of list2 is 5
List.iteri2: element 2 of list1 is 3; element 2 of list2 is 6
Another frequently used function that transforms list elements is List.map, which enables you to apply a
function to each element of a list and put all the results into a new list. List.map2 and List.map3 are variations
that take multiple lists. You can also use List.mapi and List.mapi2, if, in addition to the element, the function
needs to be passed the index of each element. The only difference between List.mapi2 and List.mapi is that
List.mapi2 works with two lists. The following example illustrates List.map.
[2; 3; 4]
[5; 7; 9]
[1; 3; 5]
[0; 7; 18]
List.collect is like List.map , except that each element produces a list and all these lists are concatenated into a
final list. In the following code, each element of the list generates three numbers. These are all collected into one
list.
let collectList = List.collect (fun x -> [for i in 1..3 -> x * i]) list1
printfn "%A" collectList
[1; 2; 3; 2; 4; 6; 3; 6; 9]
You can also use List.filter, which takes a Boolean condition and produces a new list that consists only of
elements that satisfy the given condition.
["Rome's"; "Bob's"]
testList [1; 1; 1]
testList [1; 2; 1]
testList [1; 2; 3]
The versions of these functions that have a digit in the function name operate on more than one list. For
example, List.fold2 performs computations on two lists.
The following example demonstrates the use of List.fold2 .
// Use List.fold2 to perform computations over two lists (of equal size) at the same time.
// Example: Sum the greater element at each list position.
let sumGreatest list1 list2 = List.fold2 (fun acc elem1 elem2 ->
acc + max elem1 elem2) 0 list1 list2
List.fold and List.scan differ in that List.fold returns the final value of the extra parameter, but List.scan
returns the list of the intermediate values (along with the final value) of the extra parameter.
Each of these functions includes a reverse variation, for example, List.foldBack, which differs in the order in
which the list is traversed and the order of the arguments. Also, List.fold and List.foldBack have variations,
List.fold2 and List.foldBack2, that take two lists of equal length. The function that executes on each element can
use corresponding elements of both lists to perform some action. The element types of the two lists can be
different, as in the following example, in which one list contains transaction amounts for a bank account, and the
other list contains the type of transaction: deposit or withdrawal.
// Discriminated union type that encodes the transaction type.
type Transaction =
| Deposit
| Withdrawal
// Use fold2 to perform a calculation on the list to update the account balance.
let endingBalance = List.fold2 (fun acc elem1 elem2 ->
match elem1 with
| Deposit -> acc + elem2
| Withdrawal -> acc - elem2)
initialBalance
transactionTypes
transactionAmounts
printfn "%f" endingBalance
For a calculation like summation, List.fold and List.foldBack have the same effect because the result does
not depend on the order of traversal. In the following example, List.foldBack is used to add the elements in a
list.
let sumListBack list = List.foldBack (fun acc elem -> acc + elem) list 0
printfn "%d" (sumListBack [1; 2; 3])
// For a calculation in which the order of traversal is important, fold and foldBack have different
// results. For example, replacing fold with foldBack in the listReverse function
// produces a function that copies the list, rather than reversing it.
let copyList list = List.foldBack (fun elem acc -> elem::acc) list []
printfn "%A" (copyList [1 .. 10])
The following example returns to the bank account example. This time a new transaction type is added: an
interest calculation. The ending balance now depends on the order of transactions.
type Transaction2 =
| Deposit
| Withdrawal
| Interest
The function List.reduce is somewhat like List.fold and List.scan , except that instead of passing around a
separate accumulator, List.reduce takes a function that takes two arguments of the element type instead of
just one, and one of those arguments acts as the accumulator, meaning that it stores the intermediate result of
the computation. List.reduce starts by operating on the first two list elements, and then uses the result of the
operation along with the next element. Because there is not a separate accumulator that has its own type,
List.reduce can be used in place of List.fold only when the accumulator and the element type have the
same type. The following code demonstrates the use of List.reduce . List.reduce throws an exception if the
list provided has no elements.
In the following code, the first call to the lambda expression is given the arguments 2 and 4, and returns 6, and
the next call is given the arguments 6 and 10, so the result is 16.
See Also
F# Language Reference
F# Types
Sequences
Arrays
Options
Options
7/29/2017 • 3 min to read • Edit Online
The option type in F# is used when an actual value might not exist for a named value or variable. An option has an
underlying type and can hold a value of that type, or it might not have a value.
Remarks
The following code illustrates a function which generates an option type.
As you can see, if the input a is greater than 0, Some(a) is generated. Otherwise, None is generated.
The value None is used when an option does not have an actual value. Otherwise, the expression Some( ... )
gives the option a value. The values Some and None are useful in pattern matching, as in the following function
exists , which returns true if the option has a value and false if it does not.
Using Options
Options are commonly used when a search does not return a matching result, as shown in the following code.
In the previous code, a list is searched recursively. The function tryFindMatch takes a predicate function pred that
returns a Boolean value, and a list to search. If an element that satisfies the predicate is found, the recursion ends
and the function returns the value as an option in the expression Some(head) . The recursion ends when the empty
list is matched. At that point the value head has not been found, and None is returned.
Many F# library functions that search a collection for a value that may or may not exist return the option type. By
convention, these functions begin with the try prefix, for example, Seq.tryFindIndex .
Options can also be useful when a value might not exist, for example if it is possible that an exception will be
thrown when you try to construct a value. The following code example illustrates this.
open System.IO
let openFile filename =
try
let file = File.Open (filename, FileMode.Create)
Some(file)
with
| ex -> eprintf "An exception occurred with message %s" ex.Message
None
The openFile function in the previous example has type string -> File option because it returns a File object
if the file opens successfully and None if an exception occurs. Depending on the situation, it may not be an
appropriate design choice to catch an exception rather than allowing it to propagate.
Option Module
There is a module, Option, that contains useful functions that perform operations on options. Some functions
repeat the functionality of the properties but are useful in contexts where a function is needed. Option.isSome and
Option.isNone are both module functions that test whether an option holds a value. Option.get obtains the value,
if there is one. If there is no value, it throws System.ArgumentException .
The Option.bind function executes a function on the value, if there is a value. The function must take exactly one
argument, and its parameter type must be the option type. The return value of the function is another option type.
The option module also includes functions that correspond to the functions that are available for lists, arrays,
sequences, and other collection types. These functions include Option.map , Option.iter , Option.forall ,
Option.exists , Option.foldBack , Option.fold , and Option.count . These functions enable options to be used like
a collection of zero or one elements. For more information and examples, see the discussion of collection
functions in Lists.
See Also
F# Language Reference
F# Types
Results
7/29/2017 • 2 min to read • Edit Online
Starting with F# 4.1, there is a Result<'T,'TFailure> type which you can use for writing error-tolerant code which
can be composed.
Syntax
// The definition of Result in FSharp.Core
[<StructuralEquality; StructuralComparison>]
[<CompiledName("FSharpResult`2")>]
[<Struct>]
type Result<'T,'TError> =
| Ok of ResultValue:'T
| Error of ErrorValue:'TError
Remarks
Note that the result type is a struct discriminated union, which is another feature introduced in F# 4.1. Structural
equality semantics apply here.
The Result type is typically used in monadic error-handling, which is often referred to as Railway-oriented
Programming within the F# community. The following trivial example demonstrates this approach.
// Define a simple type which has fields that can be validated
type Request =
{ Name: string
Email: string }
let test() =
// Now, create a Request and pattern match on the result.
let req1 = { Name = "Phillip"; Email = "[email protected]" }
let res1 = validateRequest (OK req1)
match res1 with
| Ok req -> printfn "My request was valid! Name: %s Email %s" req1.Name req1.Email
| Error e -> printfn "Error: %s" e
// Prints " "My request was valid! Name: Phillip Email: [email protected]"
test()
As you can see, it's quite easy to chain together various validation functions if you force them all to return a Result
. This lets you break up functionality like this into small pieces which are as composable as you need them to be.
This also has the added value of enforcing the use of pattern matching at the end of a round of validation, which in
turns enforces a higher degree of program correctness.
See Also
Discriminated Unions
Pattern Matching
Sequences
7/29/2017 • 18 min to read • Edit Online
NOTE
The API reference links in this article will take you to MSDN. The docs.microsoft.com API reference is not complete.
A sequence is a logical series of elements all of one type. Sequences are particularly useful when you have a
large, ordered collection of data but do not necessarily expect to use all of the elements. Individual sequence
elements are computed only as required, so a sequence can provide better performance than a list in situations
in which not all the elements are used. Sequences are represented by the seq<'T> type, which is an alias for
System.Collections.Generic.IEnumerable . Therefore, any .NET Framework type that implements
System.IEnumerable can be used as a sequence. The Seq module provides support for manipulations involving
sequences.
Sequence Expressions
A sequence expression is an expression that evaluates to a sequence. Sequence expressions can take a number of
forms. The simplest form specifies a range. For example, seq { 1 .. 5 } creates a sequence that contains five
elements, including the endpoints 1 and 5. You can also specify an increment (or decrement) between two
double periods. For example, the following code creates the sequence of multiples of 10.
Sequence expressions are made up of F# expressions that produce values of the sequence. They can use the
yield keyword to produce values that become part of the sequence.
Following is an example.
You can use the -> operator instead of yield , in which case you can omit the do keyword, as shown in the
following example.
The following code generates a list of coordinate pairs along with an index into an array that represents the grid.
An if expression used in a sequence is a filter. For example, to generate a sequence of only prime numbers,
assuming that you have a function isprime of type int -> bool , construct the sequence as follows.
seq { for n in 1 .. 100 do if isprime n then yield n }
When you use yield or -> in an iteration, each iteration is expected to generate a single element of the
sequence. If each iteration produces a sequence of elements, use yield! . In that case, the elements generated
on each iteration are concatenated to produce the final sequence.
You can combine multiple expressions together in a sequence expression. The elements generated by each
expression are concatenated together. For an example, see the "Examples" section of this topic.
Examples
The first example uses a sequence expression that contains an iteration, a filter, and a yield to generate an array.
This code prints a sequence of prime numbers between 1 and 100 to the console.
The following code uses yield to create a multiplication table that consists of tuples of three elements, each
consisting of two factors and the product.
let multiplicationTable =
seq { for i in 1..9 do
for j in 1..9 do
yield (i, j, i*j) }
The following example demonstrates the use of yield! to combine individual sequences into a single final
sequence. In this case, the sequences for each subtree in a binary tree are concatenated in a recursive function to
produce the final sequence.
Module Functions
The Seq module in the Microsoft.FSharp.Collections namespace contains functions for working with sequences.
These functions work with lists, arrays, maps, and sets as well, because all of those types are enumerable, and
therefore can be treated as sequences.
Creating Sequences
You can create sequences by using sequence expressions, as described previously, or by using certain functions.
You can create an empty sequence by using Seq.empty, or you can create a sequence of just one specified
element by using Seq.singleton.
You can use Seq.init to create a sequence for which the elements are created by using a function that you
provide. You also provide a size for the sequence. This function is just like List.init, except that the elements are
not created until you iterate through the sequence. The following code illustrates the use of Seq.init .
The output is
0 10 20 30 40
By using Seq.ofArray and Seq.ofList<'T> Function, you can create sequences from arrays and lists. However, you
can also convert arrays and lists to sequences by using a cast operator. Both techniques are shown in the
following code.
By using Seq.cast, you can create a sequence from a weakly typed collection, such as those defined in
System.Collections . Such weakly typed collections have the element type System.Object and are enumerated
by using the non-generic System.Collections.Generic.IEnumerable`1 type. The following code illustrates the
use of Seq.cast to convert an System.Collections.ArrayList into a sequence.
open System
let mutable arrayList1 = new System.Collections.ArrayList(10)
for i in 1 .. 10 do arrayList1.Add(10) |> ignore
let seqCast : seq<int> = Seq.cast arrayList1
You can define infinite sequences by using the Seq.initInfinite function. For such a sequence, you provide a
function that generates each element from the index of the element. Infinite sequences are possible because of
lazy evaluation; elements are created as needed by calling the function that you specify. The following code
example produces an infinite sequence of floating point numbers, in this case the alternating series of
reciprocals of squares of successive integers.
Seq.unfold generates a sequence from a computation function that takes a state and transforms it to produce
each subsequent element in the sequence. The state is just a value that is used to compute each element, and can
change as each element is computed. The second argument to Seq.unfold is the initial value that is used to start
the sequence. Seq.unfold uses an option type for the state, which enables you to terminate the sequence by
returning the None value. The following code shows two examples of sequences, seq1 and fib , that are
generated by an unfold operation. The first, seq1 , is just a simple sequence with numbers up to 100. The
second, fib , uses unfold to compute the Fibonacci sequence. Because each element in the Fibonacci sequence
is the sum of the previous two Fibonacci numbers, the state value is a tuple that consists of the previous two
numbers in the sequence. The initial value is (1,1) , the first two numbers in the sequence.
let seq1 = Seq.unfold (fun state -> if (state > 20) then None else Some(state, state + 1)) 0
printfn "The sequence seq1 contains numbers from 0 to 20."
for x in seq1 do printf "%d " x
let fib = Seq.unfold (fun state ->
if (snd state > 1000) then None
else Some(fst state + snd state, (snd state, fst state + snd state))) (1,1)
printfn "\nThe sequence fib contains Fibonacci numbers."
for x in fib do printf "%d " x
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
The following code is an example that uses many of the sequence module functions described here to generate
and compute the values of infinite sequences. The code might take a few minutes to run.
// infiniteSequences.fs
// generateInfiniteSequence generates sequences of floating point
// numbers. The sequences generated are computed from the fDenominator
// function, which has the type (int -> float) and computes the
// denominator of each term in the sequence from the index of that
// term. The isAlternating parameter is true if the sequence has
// alternating signs.
let generateInfiniteSequence fDenominator isAlternating =
if (isAlternating) then
Seq.initInfinite (fun index -> 1.0 /(fDenominator index) * (if (index % 2 = 0) then -1.0 else 1.0))
else
Seq.initInfinite (fun index -> 1.0 /(fDenominator index))
// Compute the sums for three sequences that converge, and compare
// the sums to the expected theoretical values.
let result1 = infiniteSum harmonicAlternatingSeries 0.00001 100000
printfn "Result: %f ln2: %f" result1 (log 2.0)
let pi = Math.PI
let result2 = infiniteSum oddNumberSeries 0.00001 10000
printfn "Result: %f pi/4: %f" result2 (pi/4.0)
let printSeq seq1 = Seq.iter (printf "%A ") seq1; printfn ""
1 4 9 16 25
1 4 9 16 25 36 49 64 81 100
1 4 9 16 25
1 4 9 16 25 36 49 64 81 100
By using Seq.takeWhile, you can specify a predicate function (a Boolean function) and create a sequence from
another sequence made up of those elements of the original sequence for which the predicate is true , but stop
before the first element for which the predicate returns false . Seq.skip returns a sequence that skips a specified
number of the first elements of another sequence and returns the remaining elements. Seq.skipWhile returns a
sequence that skips the first elements of another sequence as long as the predicate returns true , and then
returns the remaining elements, starting with the first element for which the predicate returns false .
The following code example illustrates the behavior of and differences between Seq.takeWhile , Seq.skip , and
Seq.skipWhile .
// takeWhile
let mySeqLessThan10 = Seq.takeWhile (fun elem -> elem < 10) mySeq
mySeqLessThan10 |> printSeq
// skip
let mySeqSkipFirst5 = Seq.skip 5 mySeq
mySeqSkipFirst5 |> printSeq
// skipWhile
let mySeqSkipWhileLessThan10 = Seq.skipWhile (fun elem -> elem < 10) mySeq
mySeqSkipWhileLessThan10 |> printSeq
The output is as follows.
1 4 9
36 49 64 81 100
16 25 36 49 64 81 100
Transforming Sequences
Seq.pairwise creates a new sequence in which successive elements of the input sequence are grouped into
tuples.
let printSeq seq1 = Seq.iter (printf "%A ") seq1; printfn ""
let seqPairwise = Seq.pairwise (seq { for i in 1 .. 10 -> i*i })
printSeq seqPairwise
printfn ""
let seqDelta = Seq.map (fun elem -> snd elem - fst elem) seqPairwise
printSeq seqDelta
Seq.windowed is like Seq.pairwise , except that instead of producing a sequence of tuples, it produces a
sequence of arrays that contain copies of adjacent elements (a window) from the sequence. You specify the
number of adjacent elements you want in each array.
The following code example demonstrates the use of Seq.windowed . In this case the number of elements in the
window is 3. The example uses printSeq , which is defined in the previous code example.
let seqNumbers = [ 1.0; 1.5; 2.0; 1.5; 1.0; 1.5 ] :> seq<float>
let seqWindows = Seq.windowed 3 seqNumbers
let seqMovingAverage = Seq.map Array.average seqWindows
printfn "Initial sequence: "
printSeq seqNumbers
printfn "\nWindows of length 3: "
printSeq seqWindows
printfn "\nMoving average: "
printSeq seqMovingAverage
Windows of length 3:
[|1.0; 1.5; 2.0|] [|1.5; 2.0; 1.5|] [|2.0; 1.5; 1.0|] [|1.5; 1.0; 1.5|]
Moving average:
1.5 1.666666667 1.5 1.333333333
In the previous code, only the first element is computed and examined, and the result is -1.
Seq.countBy takes a function that generates a value called a key for each element. A key is generated for each
element by calling this function on each element. Seq.countBy then returns a sequence that contains the key
values, and a count of the number of elements that generated each value of the key.
printSeq seqResult
The previous output shows that there were 34 elements of the original sequence that produced the key 1, 33
values that produced the key 2, and 33 values that produced the key 0.
You can group elements of a sequence by calling Seq.groupBy. Seq.groupBy takes a sequence and a function
that generates a key from an element. The function is executed on each element of the sequence. Seq.groupBy
returns a sequence of tuples, where the first element of each tuple is the key and the second is a sequence of
elements that produce that key.
The following code example shows the use of Seq.groupBy to partition the sequence of numbers from 1 to 100
into three groups that have the distinct key values 0, 1, and 2.
let sequence = seq { 1 .. 100 }
let printSeq seq1 = Seq.iter (printf "%A ") seq1; printfn ""
let sequences3 = Seq.groupBy (fun index ->
if (index % 3 = 0) then 0
elif (index % 3 = 1) then 1
else 2) sequence
sequences3 |> printSeq
(1, seq [1; 4; 7; 10; ...]) (2, seq [2; 5; 8; 11; ...]) (0, seq [3; 6; 9; 12; ...])
You can create a sequence that eliminates duplicate elements by calling Seq.distinct. Or you can use
Seq.distinctBy, which takes a key-generating function to be called on each element. The resulting sequence
contains elements of the original sequence that have unique keys; later elements that produce a duplicate key to
an earlier element are discarded.
The following code example illustrates the use of Seq.distinct . Seq.distinct is demonstrated by generating
sequences that represent binary numbers, and then showing that the only distinct elements are 0 and 1.
let binary n =
let rec generateBinary n =
if (n / 2 = 0) then [n]
else (n % 2) :: generateBinary (n / 2)
generateBinary n |> List.rev |> Seq.ofList
The following code demonstrates Seq.distinctBy by starting with a sequence that contains negative and
positive numbers and using the absolute value function as the key-generating function. The resulting sequence
is missing all the positive numbers that correspond to the negative numbers in the sequence, because the
negative numbers appear earlier in the sequence and therefore are selected instead of the positive numbers that
have the same absolute value, or key.
let inputSequence = { -5 .. 10 }
let printSeq seq1 = Seq.iter (printf "%A ") seq1; printfn ""
printfn "Original sequence: "
printSeq inputSequence
printfn "\nSequence with distinct absolute values: "
let seqDistinctAbsoluteValue = Seq.distinctBy (fun elem -> abs elem) inputSequence
seqDistinctAbsoluteValue |> printSeq
Seq.cache creates a stored version of a sequence. Use Seq.cache to avoid reevaluation of a sequence, or when
you have multiple threads that use a sequence, but you must make sure that each element is acted upon only
one time. When you have a sequence that is being used by multiple threads, you can have one thread that
enumerates and computes the values for the original sequence, and remaining threads can use the cached
sequence.
See Also
F# Language Reference
F# Types
Arrays
8/10/2017 • 17 min to read • Edit Online
NOTE
The API reference link will take you to MSDN. The docs.microsoft.com API reference is not complete.
Arrays are fixed-size, zero-based, mutable collections of consecutive data elements that are all of the same type.
Creating Arrays
You can create arrays in several ways. You can create a small array by listing consecutive values between [| and
|] and separated by semicolons, as shown in the following examples.
let array1 = [| 1; 2; 3 |]
You can also put each element on a separate line, in which case the semicolon separator is optional.
let array1 =
[|
1
2
3
|]
The type of the array elements is inferred from the literals used and must be consistent. The following code
causes an error because 1.0 is a float and 2 and 3 are integers.
// Causes an error.
// let array2 = [| 1.0; 2; 3 |]
You can also use sequence expressions to create arrays. Following is an example that creates an array of squares
of integers from 1 to 10.
To create an array in which all the elements are initialized to zero, use Array.zeroCreate .
Accessing Elements
You can access array elements by using a dot operator ( . ) and brackets ( [ and ] ).
array1.[0]
array1.[0..2]
array1.[..2]
array1.[2..]
0 1 2 3 4 5 6 7 8 9
printfn "Array of squares: %A" (Array.init 10 (fun index -> index * index))
Array.copy creates a new array that contains elements that are copied from an existing array. Note that the copy
is a shallow copy, which means that if the element type is a reference type, only the reference is copied, not the
underlying object. The following code example illustrates this.
open System.Text
let firstArray : StringBuilder array = Array.init 3 (fun index -> new StringBuilder(""))
let secondArray = Array.copy firstArray
// Reset an element of the first array to a new value.
firstArray.[0] <- new StringBuilder("Test1")
// Change an element of the first array.
firstArray.[1].Insert(0, "Test2") |> ignore
printfn "%A" firstArray
printfn "%A" secondArray
[|Test1; Test2; |]
[|; Test2; |]
The string Test1 appears only in the first array because the operation of creating a new element overwrites the
reference in firstArray but does not affect the original reference to an empty string that is still present in
secondArray . The string Test2 appears in both arrays because the Insert operation on the
System.Text.StringBuilder type affects the underlying System.Text.StringBuilder object, which is referenced in
both arrays.
Array.sub generates a new array from a subrange of an array. You specify the subrange by providing the
starting index and the length. The following code demonstrates the use of Array.sub .
let a1 = [| 0 .. 99 |]
let a2 = Array.sub a1 5 10
printfn "%A" a2
The output shows that the subarray starts at element 5 and contains 10 elements.
[|1; 2; 3; 4; 5; 6|]
Array.choose selects elements of an array to include in a new array. The following code demonstrates
Array.choose . Note that the element type of the array does not have to match the type of the value returned in
the option type. In this example, the element type is int and the option is the result of a polynomial function,
elem*elem - 1 , as a floating point number.
Array.collect runs a specified function on each array element of an existing array and then collects the
elements generated by the function and combines them into a new array. The following code demonstrates
Array.collect .
[|0; 1; 0; 1; 2; 3; 4; 5; 0; 1; 2; 3; 4; 5; 6; 7; 8; 9; 10|]
Array.concat takes a sequence of arrays and combines them into a single array. The following code
demonstrates Array.concat .
[|(1, 1, 1); (1, 2, 2); (1, 3, 3); (2, 1, 2); (2, 2, 4); (2, 3, 6); (3, 1, 3);
(3, 2, 6); (3, 3, 9)|]
Array.filter takes a Boolean condition function and generates a new array that contains only those elements
from the input array for which the condition is true. The following code demonstrates Array.filter .
printfn "%A" (Array.filter (fun elem -> elem % 2 = 0) [| 1 .. 10|])
[|2; 4; 6; 8; 10|]
Array.rev generates a new array by reversing the order of an existing array. The following code demonstrates
Array.rev .
"Hello world!"
You can easily combine functions in the array module that transform arrays by using the pipeline operator ( |> ),
as shown in the following example.
[| 1 .. 10 |]
|> Array.filter (fun elem -> elem % 2 = 0)
|> Array.choose (fun elem -> if (elem <> 8) then Some(elem*elem) else None)
|> Array.rev
|> printfn "%A"
The output is
Multidimensional Arrays
A multidimensional array can be created, but there is no syntax for writing a multidimensional array literal. Use
the operator array2D to create an array from a sequence of sequences of array elements. The sequences can be
array or list literals. For example, the following code creates a two-dimensional array.
You can also use the function Array2D.init to initialize arrays of two dimensions, and similar functions are
available for arrays of three and four dimensions. These functions take a function that is used to create the
elements. To create a two-dimensional array that contains elements set to an initial value instead of specifying a
function, use the Array2D.create function, which is also available for arrays up to four dimensions. The following
code example first shows how to create an array of arrays that contain the desired elements, and then uses
Array2D.init to generate the desired two-dimensional array.
Array indexing and slicing syntax is supported for arrays up to rank 4. When you specify an index in multiple
dimensions, you use commas to separate the indexes, as illustrated in the following code example.
twoDimensionalArray.[0, 1] <- 1.0
The type of a two-dimensional array is written out as <type>[,] (for example, int[,] , double[,] ), and the type
of a three-dimensional array is written as <type>[,,] , and so on for arrays of higher dimensions.
Only a subset of the functions available for one-dimensional arrays is also available for multidimensional arrays.
For more information, see Collections.Array Module , Collections.Array2D Module , Collections.Array3D Module ,
and Collections.Array4D Module .
Array Slicing and Multidimensional Arrays
In a two-dimensional array (a matrix), you can extract a sub-matrix by specifying ranges and using a wildcard ( *
) character to specify whole rows or columns.
As of F# 3.1, you can decompose a multidimensional array into subarrays of the same or lower dimension. For
example, you can obtain a vector from a matrix by specifying a single row or column.
You can use this slicing syntax for types that implement the element access operators and overloaded GetSlice
methods. For example, the following code creates a Matrix type that wraps the F# 2D array, implements an Item
property to provide support for array indexing, and implements three versions of GetSlice . If you can use this
code as a template for your matrix types, you can use all the slicing operations that this section describes.
type Matrix<'T>(N: int, M: int) =
let internalArray = Array2D.zeroCreate<'T> N M
member this.Item
with get(a: int, b: int) = internalArray.[a, b]
and set(a: int, b: int) (value:'T) = internalArray.[a, b] <- value
member this.GetSlice(rowStart: int option, rowFinish : int option, colStart: int option, colFinish : int
option) =
let rowStart =
match rowStart with
| Some(v) -> v
| None -> 0
let rowFinish =
match rowFinish with
| Some(v) -> v
| None -> internalArray.GetLength(0) - 1
let colStart =
match colStart with
| Some(v) -> v
| None -> 0
let colFinish =
match colFinish with
| Some(v) -> v
| None -> internalArray.GetLength(1) - 1
internalArray.[rowStart..rowFinish, colStart..colFinish]
module test =
let generateTestMatrix x y =
let matrix = new Matrix<float>(3, 3)
for i in 0..2 do
for j in 0..2 do
matrix.[i, j] <- float(i) * x - float(j) * y
matrix
let allNegative = Array.exists (fun elem -> abs (elem) = elem) >> not
printfn "%A" (allNegative [| -1; -2; -3 |])
printfn "%A" (allNegative [| -10; -1; 5 |])
printfn "%A" (allNegative [| 0 |])
true
false
false
true
Similarly, the function Array.forall tests an array to determine whether every element satisfies a Boolean
condition. The variation Array.forall2 does the same thing by using a Boolean function that involves elements
of two arrays of equal length. The following code illustrates the use of these functions.
false
true
true
false
Searching Arrays
Array.find takes a Boolean function and returns the first element for which the function returns true , or raises
a System.Collections.Generic.KeyNotFoundException if no element that satisfies the condition is found.
Array.findIndex is like Array.find , except that it returns the index of the element instead of the element itself.
The following code uses Array.find and Array.findIndex to locate a number that is both a perfect square and
perfect cube.
let arrayA = [| 2 .. 100 |]
let delta = 1.0e-10
let isPerfectSquare (x:int) =
let y = sqrt (float x)
abs(y - round y) < delta
let isPerfectCube (x:int) =
let y = System.Math.Pow(float x, 1.0/3.0)
abs(y - round y) < delta
let element = Array.find (fun elem -> isPerfectSquare elem && isPerfectCube elem) arrayA
let index = Array.findIndex (fun elem -> isPerfectSquare elem && isPerfectCube elem) arrayA
printfn "The first element that is both a square and a cube is %d and its index is %d." element index
The first element that is both a square and a cube is 64 and its index is 62.
Array.tryFind is like Array.find, except that its result is an option type, and it returns None if no element is
found. Array.tryFind should be used instead of Array.find when you do not know whether a matching
element is in the array. Similarly, Array.tryFindIndex is like Array.findIndex except that the option type is the
return value. If no element is found, the option is None .
The following code demonstrates the use of Array.tryFind . This code depends on the previous code.
lookForCubeAndSquare [| 1 .. 10 |]
lookForCubeAndSquare [| 100 .. 1000 |]
lookForCubeAndSquare [| 2 .. 50 |]
Found an element: 1
Found an element: 729
Use Array.tryPick when you need to transform an element in addition to finding it. The result is the first
element for which the function returns the transformed element as an option value, or None if no such element
is found.
The following code shows the use of Array.tryPick . In this case, instead of a lambda expression, several local
helper functions are defined to simplify the code.
let findPerfectSquareAndCube array1 =
let delta = 1.0e-10
let isPerfectSquare (x:int) =
let y = sqrt (float x)
abs(y - round y) < delta
let isPerfectCube (x:int) =
let y = System.Math.Pow(float x, 1.0/3.0)
abs(y - round y) < delta
// intFunction : (float -> float) -> int -> int
// Allows the use of a floating point function with integers.
let intFunction function1 number = int (round (function1 (float number)))
let cubeRoot x = System.Math.Pow(x, 1.0/3.0)
// testElement: int -> (int * int * int) option
// Test an element to see whether it is a perfect square and a perfect
// cube, and, if so, return the element, square root, and cube root
// as an option value. Otherwise, return None.
let testElement elem =
if isPerfectSquare elem && isPerfectCube elem then
Some(elem, intFunction sqrt elem, intFunction cubeRoot elem)
else None
match Array.tryPick testElement array1 with
| Some (n, sqrt, cuberoot) -> printfn "Found an element %d with square root %d and cube root %d." n sqrt
cuberoot
| None -> printfn "Did not find an element that is both a perfect square and a perfect cube."
findPerfectSquareAndCube [| 1 .. 10 |]
findPerfectSquareAndCube [| 2 .. 100 |]
findPerfectSquareAndCube [| 100 .. 1000 |]
findPerfectSquareAndCube [| 1000 .. 10000 |]
findPerfectSquareAndCube [| 2 .. 50 |]
These functions for performing computations correspond to the functions of the same name in the List module.
For usage examples, see Lists.
Modifying Arrays
Array.set sets an element to a specified value. Array.fill sets a range of elements in an array to a specified
value. The following code provides an example of Array.fill .
let arrayFill1 = [| 1 .. 25 |]
Array.fill arrayFill1 2 20 0
printfn "%A" arrayFill1
You can use Array.blit to copy a subsection of one array to another array.
Converting to and from Other Types
Array.ofList creates an array from a list. Array.ofSeq creates an array from a sequence. Array.toList and
Array.toSeq convert to these other collection types from the array type.
Sorting Arrays
Use Array.sort to sort an array by using the generic comparison function. Use Array.sortBy to specify a
function that generates a value, referred to as a key, to sort by using the generic comparison function on the key.
Use Array.sortWith if you want to provide a custom comparison function. Array.sort , Array.sortBy , and
Array.sortWith all return the sorted array as a new array. The variations Array.sortInPlace ,
Array.sortInPlaceBy , and Array.sortInPlaceWith modify the existing array instead of returning a new one.
See Also
F# Language Reference
F#; Types
Generics
7/29/2017 • 6 min to read • Edit Online
F# function values, methods, properties, and aggregate types such as classes, records, and discriminated unions
can be generic. Generic constructs contain at least one type parameter, which is usually supplied by the user of the
generic construct. Generic functions and types enable you to write code that works with a variety of types without
repeating the code for each type. Making your code generic can be simple in F#, because often your code is
implicitly inferred to be generic by the compiler's type inference and automatic generalization mechanisms.
Syntax
// Explicitly generic function.
let function-name<type-parameters> parameter-list =
function-body
Remarks
The declaration of an explicitly generic function or type is much like that of a non-generic function or type, except
for the specification (and use) of the type parameters, in angle brackets after the function or type name.
Declarations are often implicitly generic. If you do not fully specify the type of every parameter that is used to
compose a function or type, the compiler attempts to infer the type of each parameter, value, and variable from
the code you write. For more information, see Type Inference. If the code for your type or function does not
otherwise constrain the types of parameters, the function or type is implicitly generic. This process is named
automatic generalization. There are some limits on automatic generalization. For example, if the F# compiler is
unable to infer the types for a generic construct, the compiler reports an error that refers to a restriction called the
value restriction. In that case, you may have to add some type annotations. For more information about automatic
generalization and the value restriction, and how to change your code to address the problem, see Automatic
Generalization.
In the previous syntax, type-parameters is a comma-separated list of parameters that represent unknown types,
each of which starts with a single quotation mark, optionally with a constraint clause that further limits what types
may be used for that type parameter. For the syntax for constraint clauses of various kinds and other information
about constraints, see Constraints.
The type-definition in the syntax is the same as the type definition for a non-generic type. It includes the
constructor parameters for a class type, an optional as clause, the equal symbol, the record fields, the inherit
clause, the choices for a discriminated union, let and do bindings, member definitions, and anything else
permitted in a non-generic type definition.
The other syntax elements are the same as those for non-generic functions and types. For example, object-
identifier is an identifier that represents the containing object itself.
Properties, fields, and constructors cannot be more generic than the enclosing type. Also, values in a module
cannot be generic.
let makeList a b =
[a; b]
The signature of the function is inferred to be 'a -> 'a -> 'a list . Note that a and b in this example are
inferred to have the same type. This is because they are included in a list together, and all elements of a list must
be of the same type.
You can also make a function generic by using the single quotation mark syntax in a type annotation to indicate
that a parameter type is a generic type parameter. In the following code, function1 is generic because its
parameters are declared in this manner, as type parameters.
let function2<'T> x y =
printfn "%A, %A" x y
Examples
// A generic function.
// In this example, the generic type parameter 'a makes function3 generic.
let function3 (x : 'a) (y : 'a) =
printf "%A %A" x y
// A generic class.
type C<'a>(a : 'a, b : 'a) =
let z = a
let y = b
member this.GenericMethod(x : 'a) =
printfn "%A %A %A" x y z
type Test() =
// A generic member
member this.Function1<'a>(x, y) =
printfn "%A, %A" x y
See Also
Language Reference
Types
Statically Resolved Type Parameters
Generics in the .NET Framework
Automatic Generalization
Constraints
Automatic Generalization
7/29/2017 • 3 min to read • Edit Online
F# uses type inference to evaluate the types of functions and expressions. This topic describes how F#
automatically generalizes the arguments and types of functions so that they work with multiple types when this
is possible.
Automatic Generalization
The F# compiler, when it performs type inference on a function, determines whether a given parameter can be
generic. The compiler examines each parameter and determines whether the function has a dependency on the
specific type of that parameter. If it does not, the type is inferred to be generic.
The following code example illustrates a function that the compiler infers to be generic.
However, the two arguments must be of the same type. The signature is 'a -> 'a -> 'a , not 'a -> 'b -> 'a .
Therefore, the following code produces an error because the types do not match.
The max function also works with any type that supports the greater-than operator. Therefore, you could also
use it on a string, as shown in the following code.
Value Restriction
The compiler performs automatic generalization only on complete function definitions that have explicit
arguments, and on simple immutable values.
This means that the compiler issues an error if you try to compile code that is not sufficiently constrained to be a
specific type, but is also not generalizable. The error message for this problem refers to this restriction on
automatic generalization for values as the value restriction.
Typically, the value restriction error occurs either when you want a construct to be generic but the compiler has
insufficient information to generalize it, or when you unintentionally omit sufficient type information in a
nongeneric construct. The solution to the value restriction error is to provide more explicit information to more
fully constrain the type inference problem, in one of the following ways:
Constrain a type to be nongeneric by adding an explicit type annotation to a value or parameter.
If the problem is using a nongeneralizable construct to define a generic function, such as a function
composition or incompletely applied curried function arguments, try to rewrite the function as an ordinary
function definition.
If the problem is an expression that is too complex to be generalized, make it into a function by adding an
extra, unused parameter.
Add explicit generic type parameters. This option is rarely used.
The following code examples illustrate each of these scenarios.
Case 1: Too complex an expression. In this example, the list counter is intended to be int option ref , but it is
not defined as a simple immutable value.
Case 2: Using a nongeneralizable construct to define a generic function. In this example, the construct is
nongeneralizable because it involves partial application of function arguments.
Case 3: Adding an extra, unused parameter. Because this expression is not simple enough for generalization, the
compiler issues the value restriction error.
In the last case, the value becomes a type function, which may be used to create values of many different types,
for example as follows:
See Also
Type Inference
Generics
Statically Resolved Type Parameters
Constraints
Constraints
7/29/2017 • 4 min to read • Edit Online
This topic describes constraints that you can apply to generic type parameters to specify the requirements for a
type argument in a generic type or function.
Syntax
type-parameter-list when constraint1 [ and constraint2]
Remarks
There are several different constraints you can apply to limit the types that can be used in a generic type. The
following table lists and describes these constraints.
Type Constraint type-parameter :> type The provided type must be equal to or
derived from the type specified, or, if
the type is an interface, the provided
type must implement the interface.
Null Constraint type-parameter : null The provided type must support the
null literal. This includes all .NET object
types but not F# list, tuple, function,
class, record, or union types.
Explicit Member Constraint [(]type-parameter [or ... or type- At least one of the type arguments
parameter)] : (*member-signature *) provided must have a member that
has the specified signature; not
intended for common use. Members
must be either explicitly defined on the
type or part of an implicit type
extension to be valid targets for an
Explicit Member Constraint.
Constructor Constraint type-parameter : ( new : unit -> 'a ) The provided type must have a default
constructor.
Reference Type Constraint : not struct The provided type must be a .NET
reference type.
You have to add a constraint when your code has to use a feature that is available on the constraint type but not
on types in general. For example, if you use the type constraint to specify a class type, you can use any one of
the methods of that class in the generic function or type.
Specifying constraints is sometimes required when writing type parameters explicitly, because without a
constraint, the compiler has no way of verifying that the features that you are using will be available on any type
that might be supplied at run time for the type parameter.
The most common constraints you use in F# code are type constraints that specify base classes or interfaces.
The other constraints are either used by the F# library to implement certain functionality, such as the explicit
member constraint, which is used to implement operator overloading for arithmetic operators, or are provided
mainly because F# supports the complete set of constraints that is supported by the common language runtime.
During the type inference process, some constraints are inferred automatically by the compiler. For example, if
you use the + operator in a function, the compiler infers an explicit member constraint on variable types that
are used in the expression.
The following code illustrates some constraint declarations.
// Base Type Constraint
type Class1<'T when 'T :> System.Exception> =
class end
// Null constraint
type Class3<'T when 'T : null> =
class end
// Constructor constraint
type Class7<'T when 'T : (new : unit -> 'T)>() =
member val Field = new 'T()
// 'T must support equality. This is true for any type that does not
// have the NoEquality attribute.
type Class11<'T when 'T : equality> =
class end
// If there are multiple constraints, use the and keyword to separate them.
type Class14<'T,'U when 'T : equality and 'U : equality> =
class end
See Also
Generics
Constraints
Statically Resolved Type Parameters
7/29/2017 • 3 min to read • Edit Online
A statically resolved type parameter is a type parameter that is replaced with an actual type at compile time
instead of at run time. They are preceded by a caret (^) symbol.
Syntax
ˆtype-parameter
Remarks
In the F# language, there are two distinct kinds of type parameters. The first kind is the standard generic type
parameter. These are indicated by an apostrophe ('), as in 'T and 'U . They are equivalent to generic type
parameters in other .NET Framework languages. The other kind is statically resolved and is indicated by a caret
symbol, as in ^T and ^U .
Statically resolved type parameters are primarily useful in conjunction with member constraints, which are
constraints that allow you to specify that a type argument must have a particular member or members in order to
be used. There is no way to create this kind of constraint by using a regular generic type parameter.
The following table summarizes the similarities and differences between the two kinds of type parameters.
Member constraints Cannot be used with member Can be used with member constraints.
constraints.
Code generation A type (or method) with standard Multiple instantiations of types and
generic type parameters results in the methods are generated, one for each
generation of a single generic type or type that is needed.
method.
Use with inline functions No. An inline function cannot be Yes. Statically resolved type parameters
parameterized with a standard generic cannot be used on functions or
type parameter. methods that are not inline.
Many F# core library functions, especially operators, have statically resolved type parameters. These functions and
operators are inline, and result in efficient code generation for numeric computations.
Inline methods and functions that use operators, or use other functions that have statically resolved type
parameters, can also use statically resolved type parameters themselves. Often, type inference infers such inline
functions to have statically resolved type parameters. The following example illustrates an operator definition that
is inferred to have a statically resolved type parameter.
let inline (+@) x y = x + x * y
// Call that uses int.
printfn "%d" (1 +@ 1)
// Call that uses float.
printfn "%f" (1.0 +@ 0.5)
The resolved type of (+@) is based on the use of both (+) and (*) , both of which cause type inference to infer
member constraints on the statically resolved type parameters. The resolved type, as shown in the F# interpreter,
is as follows.
^a -> ^c -> ^d
when (^a or ^b) : (static member (+) : ^a * ^b -> ^d) and
(^a or ^c) : (static member (+) : ^a * ^c -> ^b)
2
1.500000
Starting with F# 4.1, you can also specify concrete type names in statically resolved type parameter signatures. In
previous versions of the language, the type name could actually be inferred by the compiler, but could not actually
be specified in the signature. As of F# 4.1, you may also specify concrete type names in statically resolved type
parameter signatures. Here's an example:
type CFunctor() =
static member inline fmap (f: ^a -> ^b, a: ^a list) = List.map f a
static member inline fmap (f: ^a -> ^b, a: ^a option) =
match a with
| None -> None
| Some x -> Some (f x)
let inline replace_instance< ^a, ^b, ^c, ^d when (^a or ^c): (static member replace: ^b * ^c -> ^d)> (a: ^b,
f: ^c) =
((^a or ^c): (static member replace: ^b * ^c -> ^d) (a, f))
See Also
Generics
Type Inference
Automatic Generalization
Constraints
Inline Functions
Records
8/14/2017 • 6 min to read • Edit Online
Records represent simple aggregates of named values, optionally with members. Starting with F# 4.1, they can
either be structs or reference types. They are reference types by default.
Syntax
[ attributes ]
type [accessibility-modifier] typename = {
[ mutable ] label1 : type1;
[ mutable ] label2 : type2;
...
}
[ member-list ]
Remarks
In the previous syntax, typename is the name of the record type, label1 and label2 are names of values, referred
to as labels, and type1 and type2 are the types of these values. member-list is the optional list of members for
the type. You can use the [<Struct>] attribute to create a struct record rather than a record which is a reference
type.
Following are some examples.
// A struct record.
[<Struct>]
type StructPoint =
{ X: float
Y: float
Z: float }
Do not use the shortened form if there could be another type that also has the same labels.
type Point = { x : float; y: float; z: float; }
type Point3D = { x: float; y: float; z: float }
// Ambiguity: Point or Point3D?
let mypoint3D = { x = 1.0; y = 1.0; z = 0.0; }
The labels of the most recently declared type take precedence over those of the previously declared type, so in
the preceding example, mypoint3D is inferred to be Point3D . You can explicitly specify the record type, as in the
following code.
Methods can be defined for record types just as for class types.
type MyRecord = {
X: int;
Y: int;
Z: int
}
let myRecord1 = { X = 1; Y = 2; Z = 3; }
The semicolons after the last field in the record expression and in the type definition are optional, regardless of
whether the fields are all in one line.
When you create a record, you must supply values for each field. You cannot refer to the values of other fields in
the initialization expression for any field.
In the following code, the type of myRecord2 is inferred from the names of the fields. Optionally, you can specify
the type name explicitly.
Another form of record construction can be useful when you have to copy an existing record, and possibly
change some of the field values. The following line of code illustrates this.
This form of the record expression is called the copy and update record expression.
Records are immutable by default; however, you can easily create modified records by using a copy and update
expression. You can also explicitly specify a mutable field.
type Car = {
Make : string
Model : string
mutable Odometer : int
}
let myCar = { Make = "Fabrikam"; Model = "Coupe"; Odometer = 108112 }
myCar.Odometer <- myCar.Odometer + 21
Don't use the DefaultValue attribute with record fields. A better approach is to define default instances of records
with fields that are initialized to default values and then use a copy and update record expression to set any fields
that differ from the default values.
If you write the same code with classes, the two class objects would be unequal because the two values would
represent two objects on the heap and only the addresses would be compared (unless the class type overrides
the System.Object.Equals method).
If you need reference equality for records, add the attribute [<ReferenceEquality>] above the record.
See Also
F# Types
Classes
F# Language Reference
Reference-Equality
Pattern Matching
Discriminated Unions
8/16/2017 • 8 min to read • Edit Online
Discriminated unions provide support for values that can be one of a number of named cases, possibly each with
different values and types. Discriminated unions are useful for heterogeneous data; data that can have special
cases, including valid and error cases; data that varies in type from one instance to another; and as an alternative
for small object hierarchies. In addition, recursive discriminated unions are used to represent tree data structures.
Syntax
[ attributes ]
type type-name =
| case-identifier1 [of [ fieldname1 : ] type1 [ * [ fieldname2 : ] type2 ...]
| case-identifier2 [of [fieldname3 : ]type3 [ * [ fieldname4 : ]type4 ...]
...
Remarks
Discriminated unions are similar to union types in other languages, but there are differences. As with a union
type in C++ or a variant type in Visual Basic, the data stored in the value is not fixed; it can be one of several
distinct options. Unlike unions in these other languages, however, each of the possible options is given a case
identifier. The case identifiers are names for the various possible types of values that objects of this type could
be; the values are optional. If values are not present, the case is equivalent to an enumeration case. If values are
present, each value can either be a single value of a specified type, or a tuple that aggregates multiple fields of
the same or different types. As of F# 3.1, you can give an individual field a name, but the name is optional, even if
other fields in the same case are named.
For example, consider the following declaration of a Shape type.
type Shape =
| Rectangle of width : float * length : float
| Circle of radius : float
| Prism of width : float * float * height : float
The preceding code declares a discriminated union Shape, which can have values of any of three cases:
Rectangle, Circle, and Prism. Each case has a different set of fields. The Rectangle case has two named fields, both
of type float , that have the names width and length. The Circle case has just one named field, radius. The Prism
case has three fields, two of which (width and height) are named fields. Unnamed fields are referred to as
anonymous fields.
You construct objects by providing values for the named and anonymous fields according to the following
examples.
This code shows that you can either use the named fields in the initialization, or you can rely on the ordering of
the fields in the declaration and just provide the values for each field in turn. The constructor call for rect in the
previous code uses the named fields, but the constructor call for circ uses the ordering. You can mix the
ordered fields and named fields, as in the construction of prism .
The option type is a simple discriminated union in the F# core library. The option type is declared as follows.
The previous code specifies that the type Option is a discriminated union that has two cases, Some and None .
The Some case has an associated value that consists of one anonymous field whose type is represented by the
type parameter 'a . The None case has no associated value. Thus the option type specifies a generic type that
either has a value of some type or no value. The type Option also has a lowercase type alias, option , that is
more commonly used.
The case identifiers can be used as constructors for the discriminated union type. For example, the following code
is used to create values of the option type.
The case identifiers are also used in pattern matching expressions. In a pattern matching expression, identifiers
are provided for the values associated with the individual cases. For example, in the following code, x is the
identifier given the value that is associated with the Some case of the option type.
In pattern matching expressions, you can use named fields to specify discriminated union matches. For the Shape
type that was declared previously, you can use the named fields as the following code shows to extract the values
of the fields.
Normally, the case identifiers can be used without qualifying them with the name of the union. If you want the
name to always be qualified with the name of the union, you can apply the RequireQualifiedAccess attribute to
the union type definition.
Unwrapping Discriminated Unions
In F# Discriminated Unions are often used in domain-modeling for wrapping a single type. It's easy to extract the
underlying value via pattern matching as well. You don't need to use a match expression for a single case:
[<Struct>]
type SingleCase = Case of string
[<Struct>]
type Multicase =
| Case1 of string
| Case2 of int
| Case3 of double
Because these are value types and not reference types, there are extra considerations compared with reference
discriminated unions:
1. They are copied as value types and have value type semantics.
2. You cannot use a recursive type definition with a multicase struct Discriminated Union.
3. You must provide unique case names for a multicase struct Discriminated Union.
type Shape =
// The value here is the radius.
| Circle of float
// The value here is the side length.
| EquilateralTriangle of double
// The value here is the side length.
| Square of double
// The values here are the height and width.
| Rectangle of double * double
Instead of a virtual method to compute an area or perimeter, as you would use in an object-oriented
implementation, you can use pattern matching to branch to appropriate formulas to compute these quantities. In
the following example, different formulas are used to compute the area, depending on the shape.
let pi = 3.141592654
type Tree =
| Tip
| Node of int * Tree * Tree
In the previous code, resultSumTree has the value 10. The following illustration shows the tree structure for
myTree .
Discriminated unions work well if the nodes in the tree are heterogeneous. In the following code, the type
Expression represents the abstract syntax tree of an expression in a simple programming language that
supports addition and multiplication of numbers and variables. Some of the union cases are not recursive and
represent either numbers ( Number ) or variables ( Variable ). Other cases are recursive, and represent operations
( Add and Multiply ), where the operands are also expressions. The Evaluate function uses a match expression
to recursively process the syntax tree.
type Expression =
| Number of int
| Add of Expression * Expression
| Multiply of Expression * Expression
| Variable of string
Common Attributes
The following attributes are commonly seen in discriminated unions:
[RequireQualifiedAccess]
[NoEquality]
[NoComparison]
[Struct] (F# 4.1 and higher)
See Also
F# Language Reference
Enumerations
7/29/2017 • 2 min to read • Edit Online
Enumerations, also known as enums, , are integral types where labels are assigned to a subset of the values. You
can use them in place of literals to make code more readable and maintainable.
Syntax
type enum-name =
| value1 = integer-literal1
| value2 = integer-literal2
...
Remarks
An enumeration looks much like a discriminated union that has simple values, except that the values can be
specified. The values are typically integers that start at 0 or 1, or integers that represent bit positions. If an
enumeration is intended to represent bit positions, you should also use the Flags attribute.
The underlying type of the enumeration is determined from the literal that is used, so that, for example, you can
use literals with a suffix, such as 1u , 2u , and so on, for an unsigned integer ( uint32 ) type.
When you refer to the named values, you must use the name of the enumeration type itself as a qualifier, that is,
enum-name.value1 , not just value1 . This behavior differs from that of discriminated unions. This is because
enumerations always have the RequireQualifiedAccess attribute.
The following code shows the declaration and use of an enumeration.
// Declaration of an enumeration.
type Color =
| Red = 0
| Green = 1
| Blue = 2
// Use of an enumeration.
let col1 : Color = Color.Red
You can easily convert enumerations to the underlying type by using the appropriate operator, as shown in the
following code.
Enumerated types can have one of the following underlying types: sbyte , byte , int16 , uint16 , int32 , uint32 ,
int64 , uint16 , uint64 , and char . Enumeration types are represented in the .NET Framework as types that are
inherited from System.Enum , which in turn is inherited from System.ValueType . Thus, they are value types that are
located on the stack or inline in the containing object, and any value of the underlying type is a valid value of the
enumeration. This is significant when pattern matching on enumeration values, because you have to provide a
pattern that catches the unnamed values.
The enum function in the F# library can be used to generate an enumeration value, even a value other than one of
the predefined, named values. You use the enum function as follows.
The default enum function works with type int32 . Therefore, it cannot be used with enumeration types that have
other underlying types. Instead, use the following.
type uColor =
| Red = 0u
| Green = 1u
| Blue = 2u
let col3 = Microsoft.FSharp.Core.LanguagePrimitives.EnumOfValue<uint32, uColor>(2u)
See Also
F# Language Reference
Casting and Conversions
Reference Cells
7/29/2017 • 7 min to read • Edit Online
Reference cells are storage locations that enable you to create mutable values with reference semantics.
Syntax
ref expression
Remarks
You use the ref operator before a value to create a new reference cell that encapsulates the value. You can then
change the underlying value because it is mutable.
A reference cell holds an actual value; it is not just an address. When you create a reference cell by using the ref
operator, you create a copy of the underlying value as an encapsulated mutable value.
You can dereference a reference cell by using the ! (bang) operator.
The following code example illustrates the declaration and use of reference cells.
// Declare a reference.
let refVar = ref 6
The output is 50 .
Reference cells are instances of the Ref generic record type, which is declared as follows.
type Ref<'a> =
{ mutable contents: 'a }
The type 'a ref is a synonym for Ref<'a> . The compiler and IntelliSense in the IDE display the former for this
type, but the underlying definition is the latter.
The ref operator creates a new reference cell. The following code is the declaration of the ref operator.
The following table shows the features that are available on the reference cell.
! (dereference operator) Returns the underlying 'a ref -> 'a let (!) r = r.contents
value.
OPERATOR, MEMBER, OR FIELD DESCRIPTION TYPE DEFINITION
:= (assignment operator) Changes the underlying 'a ref -> 'a -> unit let (:=) r x =
value. r.contents <- x
ref (operator) Encapsulates a value into a 'a -> 'a ref let ref x = { contents
new reference cell. = x }
Value (property) Gets or sets the underlying unit -> 'a member x.Value =
value. x.contents
contents (record field) Gets or sets the underlying 'a let ref x = { contents
value. = x }
There are several ways to access the underlying value. The value returned by the dereference operator ( ! ) is not
an assignable value. Therefore, if you are modifying the underlying value, you must use the assignment operator (
:= ) instead.
Both the Value property and the contents field are assignable values. Therefore, you can use these to either
access or change the underlying value, as shown in the following code.
xRef.Value <- 11
printfn "%d" (xRef.Value)
xRef.contents <- 12
printfn "%d" (xRef.contents)
10
10
11
12
The field contents is provided for compatibility with other versions of ML and will produce a warning during
compilation. To disable the warning, use the --mlcompatibility compiler option. For more information, see
Compiler Options.
The following code illustrates the use of reference cells in parameter passing. The Incrementor type has a method
Increment that takes a parameter that includes byref in the parameter type. The byref in the parameter type
indicates that callers must pass a reference cell or the address of a typical variable of the specified type, in this case
int. The remaining code illustrates how to call Increment with both of these types of arguments, and shows the use
of the ref operator on a variable to create a reference cell (ref myDelta1). It then shows the use of the address-of
operator (&) to generate an appropriate argument. Finally, the Increment method is called again by using a
reference cell that is declared by using a let binding. The final line of code demonstrates the use of the ! operator
to dereference the reference cell for printing.
type Incrementor(delta) =
member this.Increment(i : int byref) =
i <- i + delta
For more information about how to pass by reference, see Parameters and Arguments.
NOTE
C# programmers should know that ref works differently in F# than it does in C#. For example, the use of ref when you pass
an argument does not have the same effect in F# as it does in C#.
In the previous code, the reference cell finished is included in local state, that is, variables that are in the closure
are created and used entirely within the expression, in this case a sequence expression. Consider what occurs when
the variables are non-local. Closures can also access non-local state, but when this occurs, the variables are copied
and stored by value. This process is known as value semantics. This means that the values at the time of the copy
are stored, and any subsequent changes to the variables are not reflected. If you want to track the changes of non-
local variables, or, in other words, if you need a closure that interacts with non-local state by using reference
semantics, you must use a reference cell.
The following code examples demonstrate the use of reference cells in closures. In this case, the closure results
from the partial application of function arguments.
// The following code demonstrates the use of reference
// cells to enable partially applied arguments to be changed
// by later code.
myMutableIncrement <- 12
myRefIncrement := 12
myRefIncrement := 12
open RefReturns
let consumeRefReturn() =
let result = RefClass.Find(3, [| 1; 2; 3; 4; 5 |]) // 'result' is of type 'byref<int>'.
()
You can also declare functions which could take a ref return as input, for example:
There is currently no way to generate a ref return in F# which could be consumed in C#.
See Also
F# Language Reference
Parameters and Arguments
Symbol and Operator Reference
Type Abbreviations
7/29/2017 • 1 min to read • Edit Online
Syntax
type type-abbreviation = type-name
Remarks
You can use type abbreviations to give a type a more meaningful name, in order to make code easier to read. You
can also use them to create an easy to use name for a type that is otherwise cumbersome to write out. Additionally,
you can use type abbreviations to make it easier to change an underlying type without changing all the code that
uses the type. The following is a simple type abbreviation.
In the previous code, Transform is a type abbreviation that represents a function that takes a single argument of
any type and that returns a single value of that same type.
Type abbreviations are not preserved in the .NET Framework MSIL code. Therefore, when you use an F# assembly
from another .NET Framework language, you must use the underlying type name for a type abbreviation.
Type abbreviations can also be used on units of measure. For more information, see Units of Measure.
See Also
F# Language Reference
Classes
7/29/2017 • 8 min to read • Edit Online
Classes are types that represent objects that can have properties, methods, and events.
Syntax
// Class definition:
type [access-modifier] type-name [type-params] [access-modifier] ( parameter-list ) [ as identifier ] =
[ class ]
[ inherit base-type-name(base-constructor-args) ]
[ let-bindings ]
[ do-bindings ]
member-list
...
[ end ]
// Mutually recursive class definitions:
type [access-modifier] type-name1 ...
and [access-modifier] type-name2 ...
...
Remarks
Classes represent the fundamental description of .NET object types; the class is the primary type concept that
supports object-oriented programming in F#.
In the preceding syntax, the type-name is any valid identifier. The type-params describes optional generic type
parameters. It consists of type parameter names and constraints enclosed in angle brackets ( < and > ). For
more information, see Generics and Constraints. The parameter-list describes constructor parameters. The first
access modifier pertains to the type; the second pertains to the primary constructor. In both cases, the default is
public .
You specify the base class for a class by using the inherit keyword. You must supply arguments, in
parentheses, for the base class constructor.
You declare fields or function values that are local to the class by using let bindings, and you must follow the
general rules for let bindings. The do-bindings section includes code to be executed upon object construction.
The member-list consists of additional constructors, instance and static method declarations, interface
declarations, abstract bindings, and property and event declarations. These are described in Members.
The identifier that is used with the optional as keyword gives a name to the instance variable, or self
identifier, which can be used in the type definition to refer to the instance of the type. For more information, see
the section Self Identifiers later in this topic.
The keywords class and end that mark the start and end of the definition are optional.
Mutually recursive types, which are types that reference each other, are joined together with the and keyword
just as mutually recursive functions are. For an example, see the section Mutually Recursive Types.
Constructors
The constructor is code that creates an instance of the class type. Constructors for classes work somewhat
differently in F# than they do in other .NET languages. In an F# class, there is always a primary constructor
whose arguments are described in the parameter-list that follows the type name, and whose body consists of
the let (and let rec ) bindings at the start of the class declaration and the do bindings that follow. The
arguments of the primary constructor are in scope throughout the class declaration.
You can add additional constructors by using the new keyword to add a member, as follows:
new ( argument-list ) = constructor-body
The body of the new constructor must invoke the primary constructor that is specified at the top of the class
declaration.
The following example illustrates this concept. In the following code, MyClass has two constructors, a primary
constructor that takes two arguments and another constructor that takes no arguments.
Self Identifiers
A self identifier is a name that represents the current instance. Self identifiers resemble the this keyword in C#
or C++ or Me in Visual Basic. You can define a self identifier in two different ways, depending on whether you
want the self identifier to be in scope for the whole class definition or just for an individual method.
To define a self identifier for the whole class, use the as keyword after the closing parentheses of the
constructor parameter list, and specify the identifier name.
To define a self identifier for just one method, provide the self identifier in the member declaration, just before
the method name and a period (.) as a separator.
The following code example illustrates the two ways to create a self identifier. In the first line, the as keyword is
used to define the self identifier. In the fifth line, the identifier this is used to define a self identifier whose
scope is restricted to the method PrintMessage .
Type arguments are inferred when the type is used. In the following code, the inferred type is a sequence of
tuples.
Specifying Inheritance
The inherit clause identifies the direct base class, if there is one. In F#, only one direct base class is allowed.
Interfaces that a class implements are not considered base classes. Interfaces are discussed in the Interfaces
topic.
You can access the methods and properties of the base class from the derived class by using the language
keyword base as an identifier, followed by a period (.) and the name of the member.
For more information, see Inheritance.
Members Section
You can define static or instance methods, properties, interface implementations, abstract members, event
declarations, and additional constructors in this section. Let and do bindings cannot appear in this section.
Because members can be added to a variety of F# types in addition to classes, they are discussed in a separate
topic, Members.
See Also
F# Language Reference
Members
Inheritance
Interfaces
Structures
7/29/2017 • 2 min to read • Edit Online
A structure is a compact object type that can be more efficient than a class for types that have a small amount of
data and simple behavior.
Syntax
[ attributes ]
type [accessibility-modifier] type-name =
struct
type-definition-elements
end
// or
[ attributes ]
[<StructAttribute>]
type [accessibility-modifier] type-name =
type-definition-elements
Remarks
Structures are value types, which means that they are stored directly on the stack or, when they are used as fields
or array elements, inline in the parent type. Unlike classes and records, structures have pass-by-value semantics.
This means that they are useful primarily for small aggregates of data that are accessed and copied frequently.
In the previous syntax, two forms are shown. The first is not the lightweight syntax, but it is nevertheless
frequently used because, when you use the struct and end keywords, you can omit the StructAttribute
attribute, which appears in the second form. You can abbreviate StructAttribute to just Struct .
The type-definition-elements in the previous syntax represents member declarations and definitions. Structures
can have constructors and mutable and immutable fields, and they can declare members and interface
implementations. For more information, see Members.
Structures cannot participate in inheritance, cannot contain let or do bindings, and cannot recursively contain
fields of their own type (although they can contain reference cells that reference their own type).
Because structures do not allow let bindings, you must declare fields in structures by using the val keyword.
The val keyword defines a field and its type but does not allow initialization. Instead, val declarations are
initialized to zero or null. For this reason, structures that have an implicit constructor (that is, parameters that are
given immediately after the structure name in the declaration) require that val declarations be annotated with
the DefaultValue attribute. Structures that have a defined constructor still support zero-initialization. Therefore,
the DefaultValue attribute is a declaration that such a zero value is valid for the field. Implicit constructors for
structures do not perform any actions because let and do bindings aren’t allowed on the type, but the implicit
constructor parameter values passed in are available as private fields.
Explicit constructors might involve initialization of field values. When you have a structure that has an explicit
constructor, it still supports zero-initialization; however, you do not use the DefaultValue attribute on the val
declarations because it conflicts with the explicit constructor. For more information about val declarations, see
Explicit Fields: The val Keyword.
Attributes and accessibility modifiers are allowed on structures, and follow the same rules as those for other
types. For more information, see Attributes and Access Control.
The following code examples illustrate structure definitions.
See Also
F# Language Reference
Classes
Records
Members
Inheritance
7/29/2017 • 3 min to read • Edit Online
type MyDerived(...) =
inherit MyBase(...)
A class can have at most one direct base class. If you do not specify a base class by using the inherit keyword,
the class implicitly inherits from System.Object .
Inherited Members
If a class inherits from another class, the methods and members of the base class are available to users of the
derived class as if they were direct members of the derived class.
Any let bindings and constructor parameters are private to a class and, therefore, cannot be accessed from
derived classes.
The keyword base is available in derived classes and refers to the base class instance. It is used like the self-
identifier.
And in a derived class, an override of this virtual method follows this pattern:
If you omit the default implementation in the base class, the base class becomes an abstract class.
The following code example illustrates the declaration of a new virtual method function1 in a base class and how
to override it in a derived class.
type MyClassBase1() =
let mutable z = 0
abstract member function1 : int -> int
default u.function1(a : int) = z <- z + a; z
type MyClassDerived1() =
inherit MyClassBase1()
override u.function1(a: int) = a + 1
In the case of multiple constructors, the following code can be used. The first line of the derived class constructors
is the inherit clause, and the fields appear as explicit fields that are declared with the val keyword. For more
information, see Explicit Fields: The val Keyword.
type BaseClass =
val string1 : string
new (str) = { string1 = str }
new () = { string1 = "" }
type DerivedClass =
inherit BaseClass
Alternatives to Inheritance
In cases where a minor modification of a type is required, consider using an object expression as an alternative to
inheritance. The following example illustrates the use of an object expression as an alternative to creating a new
derived type:
open System
See Also
Object Expressions
F# Language Reference
Interfaces
7/29/2017 • 3 min to read • Edit Online
Syntax
// Interface declaration:
[ attributes ]
type interface-name =
[ interface ] [ inherit base-interface-name ...]
abstract member1 : [ argument-types1 -> ] return-type1
abstract member2 : [ argument-types2 -> ] return-type2
...
[ end ]
Remarks
Interface declarations resemble class declarations except that no members are implemented. Instead, all the
members are abstract, as indicated by the keyword abstract . You do not provide a method body for abstract
methods. However, you can provide a default implementation by also including a separate definition of the
member as a method together with the default keyword. Doing so is equivalent to creating a virtual method in a
base class in other .NET languages. Such a virtual method can be overridden in classes that implement the
interface.
You can optionally give each method parameter a name using normal F# syntax:
type ISprintable =
abstract member Print : format:string -> unit
In the above ISprintable example, the Print method has a single parameter of the type string with the name
format .
There are two ways to implement interfaces: by using object expressions, and by using class types. In either case,
the class type or object expression provides method bodies for abstract methods of the interface.
Implementations are specific to each type that implements the interface. Therefore, interface methods on different
types might be different from each other.
The keywords interface and end , which mark the start and end of the definition, are optional when you use
lightweight syntax. If you do not use these keywords, the compiler attempts to infer whether the type is a class or
an interface by analyzing the constructs that you use. If you define a member or use other class syntax, the type is
interpreted as a class.
The .NET coding style is to begin all interfaces with a capital I .
type IPrintable =
abstract member Print : unit -> unit
Interface implementations are inherited, so any derived classes do not need to reimplement them.
An alternative is to declare a method on the object that upcasts and calls the interface method, as in the following
example.
type Interface1 =
abstract member Method1 : int -> int
type Interface2 =
abstract member Method2 : int -> int
type Interface3 =
inherit Interface1
inherit Interface2
abstract member Method3 : int -> int
type MyClass() =
interface Interface3 with
member this.Method1(n) = 2 * n
member this.Method2(n) = n + 100
member this.Method3(n) = n / 10
See Also
F# Language Reference
Object Expressions
Classes
Abstract Classes
7/29/2017 • 4 min to read • Edit Online
Abstract classes are classes that leave some or all members unimplemented, so that implementations can be
provided by derived classes.
Syntax
// Abstract class syntax.
[<AbstractClass>]
type [ accessibility-modifier ] abstract-class-name =
[ inherit base-class-or-interface-name ]
[ abstract-member-declarations-and-member-definitions ]
Remarks
In object-oriented programming, an abstract class is used as a base class of a hierarchy, and represents common
functionality of a diverse set of object types. As the name "abstract" implies, abstract classes often do not
correspond directly onto concrete entities in the problem domain. However, they do represent what many
different concrete entities have in common.
Abstract classes must have the AbstractClass attribute. They can have implemented and unimplemented
members. The use of the term abstract when applied to a class is the same as in other .NET languages; however,
the use of the term abstract when applied to methods (and properties) is a little different in F# from its use in
other .NET languages. In F#, when a method is marked with the abstract keyword, this indicates that a member
has an entry, known as a virtual dispatch slot, in the internal table of virtual functions for that type. In other words,
the method is virtual, although the virtual keyword is not used in the F# language. The keyword abstract is
used on virtual methods regardless of whether the method is implemented. The declaration of a virtual dispatch
slot is separate from the definition of a method for that dispatch slot. Therefore, the F# equivalent of a virtual
method declaration and definition in another .NET language is a combination of both an abstract method
declaration and a separate definition, with either the default keyword or the override keyword. For more
information and examples, see Methods.
A class is considered abstract only if there are abstract methods that are declared but not defined. Therefore,
classes that have abstract methods are not necessarily abstract classes. Unless a class has undefined abstract
methods, do not use the AbstractClass attribute.
In the previous syntax, accessibility-modifier can be public , private or internal . For more information, see
Access Control.
As with other types, abstract classes can have a base class and one or more base interfaces. Each base class or
interface appears on a separate line together with the inherit keyword.
The type definition of an abstract class can contain fully defined members, but it can also contain abstract
members. The syntax for abstract members is shown separately in the previous syntax. In this syntax, the type
signature of a member is a list that contains the parameter types in order and the return types, separated by ->
tokens and/or * tokens as appropriate for curried and tupled parameters. The syntax for abstract member type
signatures is the same as that used in signature files and that shown by IntelliSense in the Visual Studio Code
Editor.
The following code illustrates an abstract class Shape, which has two non-abstract derived classes, Square and
Circle. The example shows how to use abstract classes, methods, and properties. In the example, the abstract class
Shape represents the common elements of the concrete entities circle and square. The common features of all
shapes (in a two-dimensional coordinate system) are abstracted out into the Shape class: the position on the grid,
an angle of rotation, and the area and perimeter properties. These can be overridden, except for position, the
behavior of which individual shapes cannot change.
The rotation method can be overridden, as in the Circle class, which is rotation invariant because of its symmetry.
So in the Circle class, the rotation method is replaced by a method that does nothing.
Output:
See Also
Classes
Members
Methods
Properties
Members
7/29/2017 • 1 min to read • Edit Online
Remarks
Members are features that are part of a type definition and are declared with the member keyword. F# object
types such as records, classes, discriminated unions, interfaces, and structures support members. For more
information, see Records, Classes, Discriminated Unions, Interfaces, and Structures.
Members typically make up the public interface for a type, which is why they are public unless otherwise
specified. Members can also be declared private or internal. For more information, see Access Control.
Signatures for types can also be used to expose or not expose certain members of a type. For more
information, see Signatures.
Private fields and do bindings, which are used only with classes, are not true members, because they are
never part of the public interface of a type and are not declared with the member keyword, but they are
described in this section also.
Related Topics
TOPIC DESCRIPTION
let Bindings in Classes Describes the definition of private fields and functions in
classes.
Explicit Fields: The val Keyword Describes the definition of uninitialized fields in a type.
let Bindings in Classes
7/29/2017 • 1 min to read • Edit Online
You can define private fields and private functions for F# classes by using let bindings in the class definition.
Syntax
// Field.
[static] let [ mutable ] binding1 [ and ... binding-n ]
// Function.
[static] let [ rec ] binding1 [ and ... binding-n ]
Remarks
The previous syntax appears after the class heading and inheritance declarations but before any member
definitions. The syntax is like that of let bindings outside of classes, but the names defined in a class have a
scope that is limited to the class. A let binding creates a private field or function; to expose data or functions
publicly, declare a property or a member method.
A let binding that is not static is called an instance let binding. Instance let bindings execute when objects
are created. Static let bindings are part of the static initializer for the class, which is guaranteed to execute before
the type is first used.
The code within instance let bindings can use the primary constructor's parameters.
Attributes and accessibility modifiers are not permitted on let bindings in classes.
The following code examples illustrate several types of let bindings in classes.
// A do binding.
do
count <- count + 1
member this.Prop1 = x
member this.Prop2 = y
member this.CreatedCount = count
member this.FunctionValue = privateFunction x y
10 52 1 204
See Also
Members
do Bindings in Classes
let Bindings
do Bindings in Classes
7/29/2017 • 2 min to read • Edit Online
A do binding in a class definition performs actions when the object is constructed or, for a static do binding,
when the type is first used.
Syntax
[static] do expression
Remarks
A do binding appears together with or after let bindings but before member definitions in a class definition.
Although the do keyword is optional for do bindings at the module level, it is not optional for do bindings in a
class definition.
For the construction of every object of any given type, non-static do bindings and non-static let bindings are
executed in the order in which they appear in the class definition. Multiple do bindings can occur in one type. The
non-static let bindings and the non-static do bindings become the body of the primary constructor. The code in
the non-static do bindings section can reference the primary constructor parameters and any values or functions
that are defined in the let bindings section.
Non-static do bindings can access members of the class as long as the class has a self identifier that is defined by
an as keyword in the class heading, and as long as all uses of those members are qualified with the self identifier
for the class.
Because let bindings initialize the private fields of a class, which is often necessary to guarantee that members
behave as expected, do bindings are usually put after let bindings so that code in the do binding can execute
with a fully initialized object. If your code attempts to use a member before the initialization is complete, an
InvalidOperationException is raised.
Static do bindings can reference static members or fields of the enclosing class but not instance members or
fields. Static do bindings become part of the static initializer for the class, which is guaranteed to execute before
the class is first used.
Attributes are ignored for do bindings in types. If an attribute is required for code that executes in a do binding,
it must be applied to the primary constructor.
In the following code, a class has a static do binding and a non-static do binding. The object has a constructor
that has two parameters, a and b , and two private fields are defined in the let bindings for the class. Two
properties are also defined. All of these are in scope in the non-static do bindings section, as is illustrated by the
line that prints all those values.
open System
Initializing MyType.
Initializing object 1 2 2 4 8 16
See Also
Members
Classes
Constructors
let Bindings in Classes
do Bindings
Properties
7/29/2017 • 7 min to read • Edit Online
Syntax
// Property that has both get and set defined.
[ attributes ]
[ static ] member [accessibility-modifier] [self-identifier.]PropertyName
with [accessibility-modifier] get() =
get-function-body
and [accessibility-modifier] set parameter =
set-function-body
Remarks
Properties represent the "has a" relationship in object-oriented programming, representing data that is associated
with object instances or, for static properties, with the type.
You can declare properties in two ways, depending on whether you want to explicitly specify the underlying value
(also called the backing store) for the property, or if you want to allow the compiler to automatically generate the
backing store for you. Generally, you should use the more explicit way if the property has a non-trivial
implementation and the automatic way when the property is just a simple wrapper for a value or variable. To
declare a property explicitly, use the member keyword. This declarative syntax is followed by the syntax that
specifies the get and set methods, also named accessors. The various forms of the explicit syntax shown in the
syntax section are used for read/write, read-only, and write-only properties. For read-only properties, you define
only a get method; for write-only properties, define only a set method. Note that when a property has both
get and set accessors, the alternative syntax enables you to specify attributes and accessibility modifiers that
are different for each accessor, as is shown in the following code.
// A read-only property.
member this.MyReadOnlyProperty = myInternalValue
// A write-only property.
member this.MyWriteOnlyProperty with set (value) = myInternalValue <- value
// A read-write property.
member this.MyReadWriteProperty
with get () = myInternalValue
and set (value) = myInternalValue <- value
For read/write properties, which have both a get and set method, the order of get and set can be reversed.
Alternatively, you can provide the syntax shown for get only and the syntax shown for set only instead of using
the combined syntax. Doing this makes it easier to comment out the individual get or set method, if that is
something you might need to do. This alternative to using the combined syntax is shown in the following code.
Private values that hold the data for properties are called backing stores. To have the compiler create the backing
store automatically, use the keywords member val , omit the self-identifier, then provide an expression to initialize
the property. If the property is to be mutable, include with get, set . For example, the following class type
includes two automatically implemented properties. Property1 is read-only and is initialized to the argument
provided to the primary constructor, and Property2 is a settable property initialized to an empty string:
Automatically implemented properties are part of the initialization of a type, so they must be included before any
other member definitions, just like let bindings and do bindings in a type definition. Note that the expression
that initializes an automatically implemented property is only evaluated upon initialization, and not every time the
property is accessed. This behavior is in contrast to the behavior of an explicitly implemented property. What this
effectively means is that the code to initialize these properties is added to the constructor of a class. Consider the
following code that shows this difference:
type MyClass() =
let random = new System.Random()
member val AutoProperty = random.Next() with get, set
member this.ExplicitProperty = random.Next()
Output
class1.AutoProperty = 1853799794
class1.AutoProperty = 1853799794
class1.ExplicitProperty = 978922705
class1.ExplicitProperty = 1131210765
The output of the preceding code shows that the value of AutoProperty is unchanged when called repeatedly,
whereas the ExplicitProperty changes each time it is called. This demonstrates that the expression for an
automatically implemented property is not evaluated each time, as is the getter method for the explicit property.
WARNING
There are some libraries, such as the Entity Framework ( System.Data.Entity ) that perform custom operations in base class
constructors that don't work well with the initialization of automatically implemented properties. In those cases, try using
explicit properties.
Properties can be members of classes, structures, discriminated unions, records, interfaces, and type extensions
and can also be defined in object expressions.
Attributes can be applied to properties. To apply an attribute to a property, write the attribute on a separate line
before the property. For more information, see Attributes.
By default, properties are public. Accessibility modifiers can also be applied to properties. To apply an accessibility
modifier, add it immediately before the name of the property if it is meant to apply to both the get and set
methods; add it before the get and set keywords if different accessibility is required for each accessor. The
accessibility-modifier can be one of the following: public , private , internal . For more information, see Access
Control.
Property implementations are executed each time a property is accessed.
Properties can also be array-like, in which case they are called indexed properties. For more information, see
Indexed Properties.
// Assume that the constructor argument sets the initial value of the
// internal backing store.
let mutable myObject = new MyType(10)
myObject.MyProperty <- 20
printfn "%d" (myObject.MyProperty)
Abstract Properties
Properties can be abstract. As with methods, abstract just means that there is a virtual dispatch associated with
the property. Abstract properties can be truly abstract, that is, without a definition in the same class. The class that
contains such a property is therefore an abstract class. Alternatively, abstract can just mean that a property is
virtual, and in that case, a definition must be present in the same class. Note that abstract properties must not be
private, and if one accessor is abstract, the other must also be abstract. For more information about abstract
classes, see Abstract Classes.
See Also
Members
Methods
Indexed Properties
7/29/2017 • 2 min to read • Edit Online
Indexed properties are properties that provide array-like access to ordered data.
Syntax
// Indexed property that has both get and set defined.
member self-identifier.PropertyName
with get(index-variable) =
get-function-body
and set index-variablesvalue-variables =
set-function-body
Remarks
The three forms of the previous syntax show how to define indexed properties that have both a get and a set
method, have a get method only, or have a set method only. You can also combine both the syntax shown for
get only and the syntax shown for set only, and produce a property that has both get and set. This latter form
allows you to put different accessibility modifiers and attributes on the get and set methods.
When the PropertyName is Item , the compiler treats the property as a default indexed property. A default indexed
property is a property that you can access by using array-like syntax on the object instance. For example, if obj is
an object of the type that defines this property, the syntax obj.[index] is used to access the property.
The syntax for accessing a nondefault indexed property is to provide the name of the property and the index in
parentheses. For example, if the property is Ordinal , you write obj.Ordinal(index) to access it.
Regardless of which form you use, you should always use the curried form for the set method on an indexed
property. For information about curried functions, see Functions.
Example
The following code example illustrates the definition and use of default and non-default indexed properties that
have get and set methods.
type NumberStrings() =
let mutable ordinals = [| "one"; "two"; "three"; "four"; "five";
"six"; "seven"; "eight"; "nine"; "ten" |]
let mutable cardinals = [| "first"; "second"; "third"; "fourth";
"fifth"; "sixth"; "seventh"; "eighth";
"ninth"; "tenth" |]
member this.Item
with get(index) = ordinals.[index]
and set index value = ordinals.[index] <- value
member this.Ordinal
with get(index) = ordinals.[index]
and set index value = ordinals.[index] <- value
member this.Cardinal
with get(index) = cardinals.[index]
and set index value = cardinals.[index] <- value
for i in 0 .. 9 do
printf "%s " (nstrs.Ordinal(i))
printf "%s " (nstrs.Cardinal(i))
printfn ""
Output
ONE two three four five six seven eight nine ten
ONE first two second three third four fourth five fifth six 6th
seven seventh eight eighth nine ninth ten tenth
open System.Collections.Generic
type SparseMatrix() =
let mutable table = new Dictionary<(int * int), float>()
member this.Item
with get(key1, key2) = table.[(key1, key2)]
and set (key1, key2) value = table.[(key1, key2)] <- value
See Also
Members
Methods
7/29/2017 • 7 min to read • Edit Online
A method is a function that is associated with a type. In object-oriented programming, methods are used to expose
and implement the functionality and behavior of objects and types.
Syntax
// Instance method definition.
[ attributes ]
member [inline] self-identifier.method-nameparameter-list [ : return-type ]=
method-body
Remarks
In the previous syntax, you can see the various forms of method declarations and definitions. In longer method
bodies, a line break follows the equal sign (=), and the whole method body is indented.
Attributes can be applied to any method declaration. They precede the syntax for a method definition and are
usually listed on a separate line. For more information, see Attributes.
Methods can be marked inline . For information about inline , see Inline Functions.
Non-inline methods can be used recursively within the type; there is no need to explicitly use the rec keyword.
Instance Methods
Instance methods are declared with the member keyword and a self-identifier, followed by a period (.) and the
method name and parameters. As is the case for let bindings, the parameter-list can be a pattern. Typically, you
enclose method parameters in parentheses in a tuple form, which is the way methods appear in F# when they are
created in other .NET Framework languages. However, the curried form (parameters separated by spaces) is also
common, and other patterns are supported also.
The following example illustrates the definition and use of a non-abstract instance method.
member this.SomeOtherMethod(a, b, c) =
this.SomeMethod(a, b, c) * factor
Within instance methods, do not use the self identifier to access fields defined by using let bindings. Use the self
identifier when accessing other members and properties.
Static Methods
The keyword static is used to specify that a method can be called without an instance and is not associated with
an object instance. Otherwise, methods are instance methods.
The example in the next section shows fields declared with the let keyword, property members declared with the
member keyword, and a static method declared with the static keyword.
The following example illustrates the definition and use of static methods. Assume that these method definitions
are in the SomeType class in the previous section.
The following example illustrates a derived class that overrides a base class method. In this case, the override
changes the behavior so that the method does nothing.
Overloaded Methods
Overloaded methods are methods that have identical names in a given type but that have different arguments. In
F#, optional arguments are usually used instead of overloaded methods. However, overloaded methods are
permitted in the language, provided that the arguments are in tuple form, not curried form.
Optional Arguments
Starting with F# 4.1, you can also have optional arguments with a default parameter value in methods. This is to
help facilitate interoperation with C# code. The following example demonstrates the syntax:
Note that the value passed in for DefaultParameterValue must match the input type. In the above sample, it is an
int . Attempting to pass a non-integer value into DefaultParameterValue would result in a compile error.
// Test code.
let testIntersection =
let r1 = RectangleXY(10.0, 10.0, 20.0, 20.0)
let r2 = RectangleXY(15.0, 15.0, 25.0, 25.0)
let r3 : RectangleXY option = RectangleXY.intersection(r1, r2)
match r3 with
| Some(r3) -> printfn "Intersection rectangle: %f %f %f %f" r3.X1 r3.Y1 r3.X2 r3.Y2
| None -> printfn "No intersection found."
testIntersection
See Also
Members
Constructors
7/29/2017 • 6 min to read • Edit Online
This topic describes how to define and use constructors to create and initialize class and structure objects.
type MyStruct =
struct
val X : int
val Y : int
val Z : int
new(x, y, z) = { X = x; Y = y; Z = z }
end
The side effects of the primary constructor still execute. Therefore, the output is as follows.
In additional constructors, you can also define a self identifier by putting the as clause right after the constructor
parameters. The following example illustrates this syntax.
Problems can occur when you try to use an object before it is fully defined. Therefore, uses of the self identifier can
cause the compiler to emit a warning and insert additional checks to ensure the members of an object are not
accessed before the object is initialized. You should only use the self identifier in the do bindings of the primary
constructor, or after the then keyword in additional constructors.
The name of the self identifier does not have to be this . It can be any valid identifier.
type Account() =
let mutable balance = 0.0
let mutable number = 0
let mutable firstName = ""
let mutable lastName = ""
member this.AccountNumber
with get() = number
and set(value) = number <- value
member this.FirstName
with get() = firstName
and set(value) = firstName <- value
member this.LastName
with get() = lastName
and set(value) = lastName <- value
member this.Balance
with get() = balance
and set(value) = balance <- value
member this.Deposit(amount: float) = this.Balance <- this.Balance + amount
member this.Withdraw(amount: float) = this.Balance <- this.Balance - amount
The following version of the previous code illustrates the combination of ordinary arguments, optional arguments,
and property settings in one constructor call.
type Account(accountNumber : int, ?first: string, ?last: string, ?bal : float) =
let mutable balance = defaultArg bal 0.0
let mutable number = accountNumber
let mutable firstName = defaultArg first ""
let mutable lastName = defaultArg last ""
member this.AccountNumber
with get() = number
and set(value) = number <- value
member this.FirstName
with get() = firstName
and set(value) = firstName <- value
member this.LastName
with get() = lastName
and set(value) = lastName <- value
member this.Balance
with get() = balance
and set(value) = balance <- value
member this.Deposit(amount: float) = this.Balance <- this.Balance + amount
member this.Withdraw(amount: float) = this.Balance <- this.Balance - amount
See Also
Members
Events
7/29/2017 • 6 min to read • Edit Online
NOTE
The API reference links in this article will take you to MSDN. The docs.microsoft.com API reference is not complete.
Events enable you to associate function calls with user actions and are important in GUI programming. Events can
also be triggered by your applications or by the operating system.
Handling Events
When you use a GUI library like Windows Forms or Windows Presentation Foundation (WPF), much of the code in
your application runs in response to events that are predefined by the library. These predefined events are
members of GUI classes such as forms and controls. You can add custom behavior to a preexisting event, such as a
button click, by referencing the specific named event of interest (for example, the Click event of the Form class)
and invoking the Add method, as shown in the following code. If you run this from F# Interactive, omit the call to
System.Windows.Forms.Application.Run(System.Windows.Forms.Form) .
open System.Windows.Forms
The type of the Add method is ('a -> unit) -> unit . Therefore, the event handler method takes one parameter,
typically the event arguments, and returns unit . The previous example shows the event handler as a lambda
expression. The event handler can also be a function value, as in the following code example. The following code
example also shows the use of the event handler parameters, which provide information specific to the type of
event. For a MouseMove event, the system passes a System.Windows.Forms.MouseEventArgs object, which contains the
X and Y position of the pointer.
open System.Windows.Forms
form.Click.Add(Beep)
form.MouseMove.Add(MouseMoveEventHandler)
Application.Run(form)
Creating Custom Events
F# events are represented by the F# Event class, which implements the IEvent interface. IEvent is itself an interface
that combines the functionality of two other interfaces, System.IObservable<'T> and IDelegateEvent. Therefore,
Event s have the equivalent functionality of delegates in other languages, plus the additional functionality from
IObservable , which means that F# events support event filtering and using F# first-class functions and lambda
expressions as event handlers. This functionality is provided in the Event module.
To create an event on a class that acts just like any other .NET Framework event, add to the class a let binding
that defines an Event as a field in a class. You can specify the desired event argument type as the type argument,
or leave it blank and have the compiler infer the appropriate type. You also must define an event member that
exposes the event as a CLI event. This member should have the CLIEvent attribute. It is declared like a property and
its implementation is just a call to the Publish property of the event. Users of your class can use the Add method of
the published event to add a handler. The argument for the Add method can be a lambda expression. You can use
the Trigger property of the event to raise the event, passing the arguments to the handler function. The following
code example illustrates this. In this example, the inferred type argument for the event is a tuple, which represents
the arguments for the lambda expression.
open System.Collections.Generic
type MyClassWithCLIEvent() =
[<CLIEvent>]
member this.Event1 = event1.Publish
member this.TestEvent(arg) =
event1.Trigger(this, arg)
classWithEvent.TestEvent("Hello World!")
The additional functionality provided by the Event module is illustrated here. The following code example
illustrates the basic use of Event.create to create an event and a trigger method, add two event handlers in the
form of lambda expressions, and then trigger the event to execute both lambda expressions.
type MyType() =
let myEvent = new Event<_>()
member this.AddHandlers() =
Event.add (fun string1 -> printfn "%s" string1) myEvent.Publish
Event.add (fun string1 -> printfn "Given a value: %s" string1) myEvent.Publish
member this.Trigger(message) =
myEvent.Trigger(message)
Event occurred.
Given a value: Event occurred.
The Observable module contains similar functions that operate on observable objects. Observable objects are
similar to events but only actively subscribe to events if they themselves are being subscribed to.
open System.Windows.Forms
open System.ComponentModel
// Create a form, hook up the event handler, and start the application.
let appForm = new AppForm()
let inpc = appForm :> INotifyPropertyChanged
inpc.PropertyChanged.Add(appForm.OnPropertyChanged)
Application.Run(appForm)
If you want to hook up the event in the constructor, the code is a bit more complicated because the event hookup
must be in a then block in an additional constructor, as in the following example:
module CustomForm
open System.Windows.Forms
open System.ComponentModel
// This property does not have the property changed event set.
member val Property1 : string = "text" with get, set
[<CLIEvent>]
member this.PropertyChanged = propertyChanged.Publish
new() as this =
new AppForm(0)
then
let inpc = this :> INotifyPropertyChanged
inpc.PropertyChanged.Add(this.OnPropertyChanged)
// Create a form, hook up the event handler, and start the application.
let appForm = new AppForm()
Application.Run(appForm)
See Also
Members
Handling and Raising Events
Lambda Expressions: The fun Keyword
Control.Event Module
Control.Event<'T> Class
Control.Event<'Delegate,'Args> Class
Explicit Fields: The val Keyword
7/29/2017 • 4 min to read • Edit Online
The val keyword is used to declare a location to store a value in a class or structure type, without initializing it.
Storage locations declared in this manner are called explicit fields. Another use of the val keyword is in
conjunction with the member keyword to declare an auto-implemented property. For more information on auto-
implemented properties, see Properties.
Syntax
val [ mutable ] [ access-modifier ] field-name : type-name
Remarks
The usual way to define fields in a class or structure type is to use a let binding. However, let bindings must
be initialized as part of the class constructor, which is not always possible, necessary, or desirable. You can use the
val keyword when you want a field that is uninitialized.
Explicit fields can be static or non-static. The access-modifier can be public , private , or internal . By default,
explicit fields are public. This differs from let bindings in classes, which are always private.
The DefaultValue attribute is required on explicit fields in class types that have a primary constructor. This
attribute specifies that the field is initialized to zero. The type of the field must support zero-initialization. A type
supports zero-initialization if it is one of the following:
A primitive type that has a zero value.
A type that supports a null value, either as a normal value, as an abnormal value, or as a representation of a
value. This includes classes, tuples, records, functions, interfaces, .NET reference types, the unit type, and
discriminated union types.
A .NET value type.
A structure whose fields all support a default zero value.
For example, an immutable field called someField has a backing field in the .NET compiled representation with the
name someField@ , and you access the stored value using a property named someField .
For a mutable field, the .NET compiled representation is a .NET field.
WARNING
Note The .NET Framework namespace System.ComponentModel contains an attribute that has the same name. For
information about this attribute, see System.ComponentModel.DefaultValueAttribute .
The following code shows the use of explicit fields and, for comparison, a let binding in a class that has a
primary constructor. Note that the let -bound field myInt1 is private. When the let -bound field myInt1 is
referenced from a member method, the self identifier this is not required. But when you are referencing the
explicit fields myInt2 and myString , the self identifier is required.
type MyType() =
let mutable myInt1 = 10
[<DefaultValue>] val mutable myInt2 : int
[<DefaultValue>] val mutable myString : string
member this.SetValsAndPrint( i: int, str: string) =
myInt1 <- i
this.myInt2 <- i + 1
this.myString <- str
printfn "%d %d %s" myInt1 (this.myInt2) (this.myString)
11 12 abc
30 def
The following code shows the use of explicit fields in a class that does not have a primary constructor. In this case,
the DefaultValue attribute is not required, but all the fields must be initialized in the constructors that are defined
for the type.
type MyClass =
val a : int
val b : int
// The following version of the constructor is an error
// because b is not initialized.
// new (a0, b0) = { a = a0; }
// The following version is acceptable because all fields are initialized.
new(a0, b0) = { a = a0; b = b0; }
The output is 35 22 .
The following code shows the use of explicit fields in a structure. Because a structure is a value type, it
automatically has a default constructor that sets the values of its fields to zero. Therefore, the DefaultValue
attribute is not required.
type MyStruct =
struct
val mutable myInt : int
val mutable myString : string
end
See Also
Properties
Members
let Bindings in Classes
Type Extensions
7/29/2017 • 4 min to read • Edit Online
Type extensions let you add new members to a previously defined object type.
Syntax
// Intrinsic extension.
type typename with
member self-identifier.member-name =
body
...
[ end ]
// Optional extension.
type typename with
member self-identifier.member-name =
body
...
[ end ]
Remarks
There are two forms of type extensions that have slightly different syntax and behavior. An intrinsic extension is an
extension that appears in the same namespace or module, in the same source file, and in the same assembly (DLL
or executable file) as the type being extended. An optional extension is an extension that appears outside the
original module, namespace, or assembly of the type being extended. Intrinsic extensions appear on the type when
the type is examined by reflection, but optional extensions do not. Optional extensions must be in modules, and
they are only in scope when the module that contains the extension is open.
In the previous syntax, typename represents the type that is being extended. Any type that can be accessed can be
extended, but the type name must be an actual type name, not a type abbreviation. You can define multiple
members in one type extension. The self-identifier represents the instance of the object being invoked, just as in
ordinary members.
The end keyword is optional in lightweight syntax.
Members defined in type extensions can be used just like other members on a class type. Like other members,
they can be static or instance members. These methods are also known as extension methods; properties are
known as extension properties, and so on. Optional extension members are compiled to static members for which
the object instance is passed implicitly as the first parameter. However, they act as if they were instance members
or static members according to how they are declared. Implicit extension members are included as members of
the type and can be used without restriction.
Extension methods cannot be virtual or abstract methods. They can overload other methods of the same name, but
the compiler gives preference to non-extension methods in the case of an ambiguous call.
If multiple intrinsic type extensions exist for one type, all members must be unique. For optional type extensions,
members in different type extensions to the same type can have the same names. Ambiguity errors occur only if
client code opens two different scopes that define the same member names.
In the following example, a type in a module has an intrinsic type extension. To client code outside the module, the
type extension appears as a regular member of the type in all respects.
module MyModule1 =
// Define a type.
type MyClass() =
member this.F() = 100
module MyModule2 =
let function1 (obj1: MyModule1.MyClass) =
// Call an ordinary method.
printfn "%d" (obj1.F())
// Call the extension method.
printfn "%d" (obj1.G())
You can use intrinsic type extensions to separate the definition of a type into sections. This can be useful in
managing large type definitions, for example, to keep compiler-generated code and authored code separate or to
group together code created by different people or associated with different functionality.
In the following example, an optional type extension extends the System.Int32 type with an extension method
FromString that calls the static member Parse . The testFromString method demonstrates that the new member
is called just like any instance member.
testFromString "500"
The new instance member will appear like any other method of the Int32 type in IntelliSense, but only when the
module that contains the extension is open or otherwise in scope.
This approach is particularly useful when the generic type parameter is constrained. Further, you can now declare
extension members like this in F# code and define an additional, semantically rich set of extension methods. In F#,
you usually define extension members as the following example shows:
open System.Collections.Generic
However, for a generic type, the type variable may not be constrained. You can now declare a C#-style extension
member in F# to work around this limitation. When you combine this kind of declaration with the inline feature of
F#, you can present generic algorithms as extension members.
Consider the following declaration:
[<Extension>]
type ExtraCSharpStyleExtensionMethodsInFSharp () =
[<Extension>]
static member inline Sum(xs: IEnumerable<'T>) = Seq.sum xs
By using this declaration, you can write code that resembles the following sample.
In this code, the same generic arithmetic code is applied to lists of two types without overloading, by defining a
single extension member.
See Also
F# Language Reference
Members
Parameters and Arguments
8/5/2017 • 9 min to read • Edit Online
This topic describes language support for defining parameters and passing arguments to functions, methods, and
properties. It includes information about how to pass by reference, and how to define and use methods that can
take a variable number of arguments.
Parameter Patterns
Parameters supplied to functions and methods are, in general, patterns separated by spaces. This means that, in
principle, any of the patterns described in Match Expressions can be used in a parameter list for a function or
member.
Methods usually use the tuple form of passing arguments. This achieves a clearer result from the perspective of
other .NET languages because the tuple form matches the way arguments are passed in .NET methods.
The curried form is most often used with functions created by using let bindings.
The following pseudocode shows examples of tuple and curried arguments.
// Tuple form.
member this.SomeMethod(param1, param2) = ...
// Curried form.
let function1 param1 param2 = ...
Combined forms are possible when some arguments are in tuples and some are not.
Other patterns can also be used in parameter lists, but if the parameter pattern does not match all possible inputs,
there might be an incomplete match at run time. The exception MatchFailureException is generated when the
value of an argument does not match the patterns specified in the parameter list. The compiler issues a warning
when a parameter pattern allows for incomplete matches. At least one other pattern is commonly useful for
parameter lists, and that is the wildcard pattern. You use the wildcard pattern in a parameter list when you simply
want to ignore any arguments that are supplied. The following code illustrates the use of the wildcard pattern in
an argument list.
[<EntryPoint>]
let main _ =
printfn "Entry point!"
0
Other patterns that are sometimes used in arguments are the as pattern, and identifier patterns associated with
discriminated unions and active patterns. You can use the single-case discriminated union pattern as follows.
Active patterns can be useful as parameters, for example, when transforming an argument into a desired format,
as in the following example:
let (| Polar |) { x = x; y = y} =
( sqrt (x*x + y*y), System.Math.Atan (y/ x) )
You can use the as pattern to store a matched value as a local value, as is shown in the following line of code.
Another pattern that is used occasionally is a function that leaves the last argument unnamed by providing, as the
body of the function, a lambda expression that immediately performs a pattern match on the implicit argument.
An example of this is the following line of code.
This code defines a function that takes a generic list and returns true if the list is empty, and false otherwise.
The use of such techniques can make code more difficult to read.
Occasionally, patterns that involve incomplete matches are useful, for example, if you know that the lists in your
program have only three elements, you might use a pattern like the following in a parameter list.
let sum [a; b; c;] = a + b + c
The use of patterns that have incomplete matches is best reserved for quick prototyping and other temporary
uses. The compiler will issue a warning for such code. Such patterns cannot cover the general case of all possible
inputs and therefore are not suitable for component APIs.
Named Arguments
Arguments for methods can be specified by position in a comma-separated argument list, or they can be passed
to a method explicitly by providing the name, followed by an equal sign and the value to be passed in. If specified
by providing the name, they can appear in a different order from that used in the declaration.
Named arguments can make code more readable and more adaptable to certain types of changes in the API, such
as a reordering of method parameters.
Named arguments are allowed only for methods, not for let -bound functions, function values, or lambda
expressions.
The following code example demonstrates the use of named arguments.
type SpeedingTicket() =
member this.GetMPHOver(speed: int, limit: int) = speed - limit
In a call to a class constructor, you can set the values of properties of the class by using a syntax similar to that of
named arguments. The following example shows this syntax.
type Account() =
let mutable balance = 0.0
let mutable number = 0
let mutable firstName = ""
let mutable lastName = ""
member this.AccountNumber
with get() = number
and set(value) = number <- value
member this.FirstName
with get() = firstName
and set(value) = firstName <- value
member this.LastName
with get() = lastName
and set(value) = lastName <- value
member this.Balance
with get() = balance
and set(value) = balance <- value
member this.Deposit(amount: float) = this.Balance <- this.Balance + amount
member this.Withdraw(amount: float) = this.Balance <- this.Balance - amount
type DuplexType =
| Full
| Half
Passing by Reference
F# supports the byref keyword, which specifies that a parameter is passed by reference. This means that any
changes to the value are retained after the execution of the function. Values provided to a byref parameter must
be mutable. Alternatively, you can pass reference cells of the appropriate type.
Passing by reference in .NET languages evolved as a way to return more than one value from a function. In F#,
you can return a tuple for this purpose, or use a mutable reference cell as a parameter. The byref parameter is
mainly provided for interoperability with .NET libraries.
The following examples illustrate the use of the byref keyword. Note that when you use a reference cell as a
parameter, you must create a reference cell as a named value and use that as the parameter, not just add the ref
operator as shown in the first call to Increment in the following code. Because creating a reference cell creates a
copy of the underlying value, the first call just increments a temporary value.
type Incrementor(z) =
member this.Increment(i : int byref) =
i <- i + z
let mutable y = 10
incrementor.Increment(&y)
// Prints 11.
printfn "%d" y
You can use a tuple as a return value to store any out parameters in .NET library methods. Alternatively, you can
treat the out parameter as a byref parameter. The following code example illustrates both ways.
Parameter Arrays
Occasionally it is necessary to define a function that takes an arbitrary number of parameters of heterogeneous
type. It would not be practical to create all the possible overloaded methods to account for all the types that could
be used. The .NET implementations provide support for such methods through the parameter array feature. A
method that takes a parameter array in its signature can be provided with an arbitrary number of parameters. The
parameters are put into an array. The type of the array elements determines the parameter types that can be
passed to the function. If you define the parameter array with System.Object as the element type, then client code
can pass values of any type.
In F#, parameter arrays can only be defined in methods. They cannot be used in standalone functions or functions
that are defined in modules.
You define a parameter array by using the ParamArray attribute. The ParamArray attribute can only be applied to
the last parameter.
The following code illustrates both calling a .NET method that takes a parameter array and the definition of a type
in F# that has a method that takes a parameter array.
open System
type X() =
member this.F([<ParamArray>] args: Object[]) =
for arg in args do
printfn "%A" arg
[<EntryPoint>]
let main _ =
// call a .NET method that takes a parameter array, passing values of various types
Console.WriteLine("a {0} {1} {2} {3} {4}", 1, 10.0, "Hello world", 1u, true)
See Also
Members
Operator Overloading
7/29/2017 • 7 min to read • Edit Online
This topic describes how to overload arithmetic operators in a class or record type, and at the global level.
Syntax
// Overloading an operator as a class or record member.
static member (operator-symbols) (parameter-list) =
method-body
// Overloading an operator at the global level
let [inline] (operator-symbols) parameter-list = function-body
Remarks
In the previous syntax, the operator-symbol is one of + , - , * , / , = , and so on. The parameter-list specifies
the operands in the order they appear in the usual syntax for that operator. The method-body constructs the
resulting value.
Operator overloads for operators must be static. Operator overloads for unary operators, such as + and - ,
must use a tilde ( ~ ) in the operator-symbol to indicate that the operator is a unary operator and not a binary
operator, as shown in the following declaration.
The following code illustrates a vector class that has just two operators, one for unary minus and one for
multiplication by a scalar. In the example, two overloads for scalar multiplication are needed because the
operator must work regardless of the order in which the vector and scalar appear.
let v2 = v1 * 2.0
let v3 = 2.0 * v1
let v4 = - v2
A table that shows the precedence of all operators in F# can be found in Symbol and Operator Reference.
[] op_Nil
:: op_Cons
+ op_Addition
- op_Subtraction
* op_Multiply
/ op_Division
@ op_Append
^ op_Concatenate
% op_Modulus
&&& op_BitwiseAnd
||| op_BitwiseOr
^^^ op_ExclusiveOr
OPERATOR GENERATED NAME
<<< op_LeftShift
~~~ op_LogicalNot
>>> op_RightShift
~+ op_UnaryPlus
~- op_UnaryNegation
= op_Equality
<= op_LessThanOrEqual
>= op_GreaterThanOrEqual
< op_LessThan
> op_GreaterThan
? op_Dynamic
?<- op_DynamicAssignment
|> op_PipeRight
<| op_PipeLeft
! op_Dereference
>> op_ComposeRight
<< op_ComposeLeft
+= op_AdditionAssignment
-= op_SubtractionAssignment
*= op_MultiplyAssignment
/= op_DivisionAssignment
.. op_Range
OPERATOR GENERATED NAME
.. .. op_RangeStep
Other combinations of operator characters that are not listed here can be used as operators and have names that
are made up by concatenating names for the individual characters from the following table. For example, +!
becomes op_PlusBang .
> Greater
< Less
+ Plus
- Minus
* Multiply
/ Divide
= Equals
~ Twiddle
% Percent
. Dot
& Amp
| Bar
@ At
^ Hat
! Bang
? Qmark
( LParen
, Comma
) RParen
[ LBrack
OPERATOR CHARACTER NAME
] RBrack
Example
The following code illustrates the use of operator overloading to implement a fraction type. A fraction is
represented by a numerator and a denominator. The function hcf is used to determine the highest common
factor, which is used to reduce fractions.
Output:
See Also
Members
Flexible Types
7/29/2017 • 2 min to read • Edit Online
A flexible type annotation indicates that a parameter, variable, or value has a type that is compatible with a
specifed type, where compatibility is determined by position in an object-oriented hierarchy of classes or
interfaces. Flexible types are useful specifically when the automatic conversion to types higher in the type
hierarchy does not occur but you still want to enable your functionality to work with any type in the hierarchy or
any type that implements an interface.
Syntax
#type
Remarks
In the previous syntax, type represents a base type or an interface.
A flexible type is equivalent to a generic type that has a constraint that limits the allowed types to types that are
compatible with the base or interface type. That is, the following two lines of code are equivalent.
#SomeType
Flexible types are useful in several types of situations. For example, when you have a higher order function (a
function that takes a function as an argument), it is often useful to have the function return a flexible type. In the
following example, the use of a flexible type with a sequence argument in iterate2 enables the higher order
function to work with functions that generate sequences, arrays, lists, and any other enumerable type.
Consider the following two functions, one of which returns a sequence, the other of which returns a flexible type.
You can pass any of the following enumerable sequences to this function:
A list of lists
A list of arrays
An array of lists
An array of sequences
Any other combination of enumerable sequences
The following code uses Seq.concat to demonstrate the scenarios that you can support by using flexible types.
let seq1 = { 1 .. 3 }
let seq2 = { 4 .. 6 }
let seq3 = { 7 .. 9 }
In F#, as in other object-oriented languages, there are contexts in which derived types or types that implement
interfaces are automatically converted to a base type or interface type. These automatic conversions occur in direct
arguments, but not when the type is in a subordinate position, as part of a more complex type such as a return
type of a function type, or as a type argument. Thus, the flexible type notation is primarily useful when the type you
are applying it to is part of a more complex type.
See Also
F# Language Reference
Generics
Delegates
7/29/2017 • 3 min to read • Edit Online
A delegate represents a function call as an object. In F#, you ordinarily should use function values to represent
functions as first-class values; however, delegates are used in the .NET Framework and so are needed when you
interoperate with APIs that expect them. They may also be used when authoring libraries designed for use from
other .NET Framework languages.
Syntax
type delegate-typename = delegate of type1 -> type2
Remarks
In the previous syntax, type1 represents the argument type or types and type2 represents the return type. The
argument types that are represented by type1 are automatically curried. This suggests that for this type you use a
tuple form if the arguments of the target function are curried, and a parenthesized tuple for arguments that are
already in the tuple form. The automatic currying removes a set of parentheses, leaving a tuple argument that
matches the target method. Refer to the code example for the syntax you should use in each case.
Delegates can be attached to F# function values, and static or instance methods. F# function values can be passed
directly as arguments to delegate constructors. For a static method, you construct the delegate by using the name
of the class and the method. For an instance method, you provide the object instance and method in one
argument. In both cases, the member access operator ( . ) is used.
The Invoke method on the delegate type calls the encapsulated function. Also, delegates can be passed as
function values by referencing the Invoke method name without the parentheses.
The following code shows the syntax for creating delegates that represent various methods in a class. Depending
on whether the method is a static method or an instance method, and whether it has arguments in the tuple form
or the curried form, the syntax for declaring and assigning the delegate is a little different.
type Test1() =
static member add(a : int, b : int) =
a + b
static member add2 (a : int) (b : int) =
a + b
// For static methods, use the class name, the dot operator, and the
// name of the static method.
let del1 : Delegate1 = new Delegate1( Test1.add )
let del2 : Delegate2 = new Delegate2( Test1.add2 )
// For instance methods, use the instance value name, the dot operator, and the instance method name.
let del3 : Delegate1 = new Delegate1( testObject.Add )
let del4 : Delegate2 = new Delegate2( testObject.Add2 )
The following code shows some of the different ways you can work with delegates.
type Delegate1 = delegate of int * char -> string
// You can pass a lambda expression as an argument to a function expecting a compatible delegate type
// System.Array.ConvertAll takes an array and a converter delegate that transforms an element from
// one type to another according to a specified function.
let stringArray = System.Array.ConvertAll([|'a';'b'|], fun c -> replicate' 3 c)
printfn "%A" stringArray
aaaaa
bbbbb
ccccc
[|"aaa"; "bbb"|]
See Also
F# Language Reference
Parameters and Arguments
Events
Object Expressions
7/29/2017 • 1 min to read • Edit Online
An object expression is an expression that creates a new instance of a dynamically created, anonymous object type
that is based on an existing base type, interface, or set of interfaces.
Syntax
// When typename is a class:
{ new typename [type-params]arguments with
member-definitions
[ additional-interface-definitions ]
}
// When typename is not a class:
{ new typename [generic-type-args] with
member-definitions
[ additional-interface-definitions ]
}
Remarks
In the previous syntax, the typename represents an existing class type or interface type. type-params describes
the optional generic type parameters. The arguments are used only for class types, which require constructor
parameters. The member-definitions are overrides of base class methods, or implementations of abstract
methods from either a base class or an interface.
The following example illustrates several different types of object expressions.
// This object expression specifies a System.Object but overrides the
// ToString method.
let obj1 = { new System.Object() with member x.ToString() = "F#" }
printfn "%A" obj1
type ISecond =
inherit IFirst
abstract H : unit -> unit
abstract J : unit -> unit
See Also
F# Language Reference
Copy and Update Record Expressions
7/29/2017 • 1 min to read • Edit Online
A copy and update record expression is an expression that copies an existing record, updates specified fields, and
returns the updated record.
Syntax
{ record-name with
updated-member-definitions }
Remarks
Records are immutable by default, so that there is no update to an existing record possible. To create an updated
record all the fields of a record would have to be specified again. To simplify this task a copy and update record
expression can be used. This expression takes an existing record, creates a new one of the same type by using
specified fields from the expression and the missing field specified by the expression. This can be useful when you
have to copy an existing record, and possibly change some of the field values.
Take for instance a newly created record.
If you were to update only on field of that record you could use the copy and update record expression like the
following:
See Also
Records
F# Language Reference
Casting and Conversions (F#)
7/29/2017 • 6 min to read • Edit Online
Arithmetic Types
F# provides conversion operators for arithmetic conversions between various primitive types, such as between
integer and floating point types. The integral and char conversion operators have checked and unchecked forms;
the floating point operators and the enum conversion operator do not. The unchecked forms are defined in
Microsoft.FSharp.Core.Operators and the checked forms are defined in Microsoft.FSharp.Core.Operators.Checked .
The checked forms check for overflow and generate a runtime exception if the resulting value exceeds the limits
of the target type.
Each of these operators has the same name as the name of the destination type. For example, in the following
code, in which the types are explicitly annotated, byte appears with two different meanings. The first occurrence
is the type and the second is the conversion operator.
let x : int = 5
OPERATOR DESCRIPTION
In addition to built-in primitive types, you can use these operators with types that implement op_Explicit or
op_Implicit methods with appropriate signatures. For example, the int conversion operator works with any
type that provides a static method op_Explicit that takes the type as a parameter and returns int . As a special
exception to the general rule that methods cannot be overloaded by return type, you can do this for op_Explicit
and op_Implicit .
Enumerated Types
The enum operator is a generic operator that takes one type parameter that represents the type of the enum to
convert to. When it converts to an enumerated type, type inference attempts to determine the type of the enum
that you want to convert to. In the following example, the variable col1 is not explicitly annotated, but its type is
inferred from the later equality test. Therefore, the compiler can deduce that you are converting to a Color
enumeration. Alternatively, you can supply a type annotation, as with col2 in the following example.
type Color =
| Red = 1
| Green = 2
| Blue = 3
You can also specify the target enumeration type explicitly as a type parameter, as in the following code:
Note that the enumeration casts work only if the underlying type of the enumeration is compatible with the type
being converted. In the following code, the conversion fails to compile because of the mismatch between int32
and uint32 .
upcast expression
When you use the upcast operator, the compiler attempts to infer the type you are converting to from the context.
If the compiler is unable to determine the target type, the compiler reports an error.
Downcasting
The :?> operator performs a dynamic cast, which means that the success of the cast is determined at run time. A
cast that uses the :?> operator is not checked at compile time; but at run time, an attempt is made to cast to the
specified type. If the object is compatible with the target type, the cast succeeds. If the object is not compatible
with the target type, the runtime raises an InvalidCastException .
You can also use the downcast operator to perform a dynamic type conversion. The following expression
specifies a conversion down the hierarchy to a type that is inferred from program context:
downcast expression
As for the upcast operator, if the compiler cannot infer a specific target type from the context, it reports an error.
The following code illustrates the use of the :> and :?> operators. The code illustrates that the :?> operator is
best used when you know that conversion will succeed, because it throws InvalidCastException if the conversion
fails. If you do not know that a conversion will succeed, a type test that uses a match expression is better because
it avoids the overhead of generating an exception.
type Base1() =
abstract member F : unit -> unit
default u.F() =
printfn "F Base1"
type Derived1() =
inherit Base1()
override u.F() =
printfn "F Derived1"
// Upcast to Base1.
let base1 = d1 :> Base1
downcastBase1 base1
Because generic operators downcast and upcast rely on type inference to determine the argument and return
type, in the above code, you can replace
with
base1 = upcast d1
In the previous code, the argument type and return types are Derived1 and Base1 , respectively.
For more information about type tests, see Match Expressions.
See Also
F# Language Reference
Access Control
7/29/2017 • 2 min to read • Edit Online
Access control refers to declaring which clients can use certain program elements, such as types, methods, and
functions.
NOTE
The access specifier protected is not used in F#, although it is acceptable if you are using types authored in languages
that do support protected access. Therefore, if you override a protected method, your method remains accessible only
within the class and its descendents.
In general, the specifier is put in front of the name of the entity, except when a mutable or inline specifier is
used, which appear after the access control specifier.
If no access specifier is used, the default is public , except for let bindings in a type, which are always private
to the type.
Signatures in F# provide another mechanism for controlling access to F# program elements. Signatures are not
required for access control. For more information, see Signatures.
Example
The following code illustrates the use of access control specifiers. There are two files in the project, Module1.fs
and Module2.fs . Each file is implicitly a module. Therefore, there are two modules, Module1 and Module2 . A
private type and an internal type are defined in Module1 . The private type cannot be accessed from Module2 , but
the internal type can.
// Module1.fs
module Module1
The following code tests the accessibility of the types created in Module1.fs .
// Module2.fs
module Module2
open Module1
See Also
F# Language Reference
Signatures
Conditional Expressions: if...then...else
7/29/2017 • 1 min to read • Edit Online
The if...then...else expression runs different branches of code and also evaluates to a different value
depending on the Boolean expression given.
Syntax
if boolean-expression then expression1 [ else expression2 ]
Remarks
In the previous syntax, expression1 runs when the Boolean expression evaluates to true ; otherwise, expression2
runs.
Unlike in other languages, the if...then...else construct is an expression, not a statement. That means that it
produces a value, which is the value of the last expression in the branch that executes. The types of the values
produced in each branch must match. If there is no explicit else branch, its type is unit . Therefore, if the type of
the then branch is any type other than unit , there must be an else branch with the same return type. When
chaining if...then...else expressions together, you can use the keyword elif instead of else if ; they are
equivalent.
Example
The following example illustrates how to use the if...then...else expression.
let test x y =
if x = y then "equals"
elif x < y then "is less than"
else "is greater than"
if age < 10
then printfn "You are only %d years old and already learning F#? Wow!" age
John
910 is less than 20
You are only 9 years old and already learning F#? Wow!
See Also
F# Language Reference
Match Expressions
7/29/2017 • 3 min to read • Edit Online
The match expression provides branching control that is based on the comparison of an expression with a set
of patterns.
Syntax
// Match expression.
match test-expression with
| pattern1 [ when condition ] -> result-expression1
| pattern2 [ when condition ] -> result-expression2
| ...
Remarks
The pattern matching expressions allow for complex branching based on the comparison of a test expression
with a set of patterns. In the match expression, the test-expression is compared with each pattern in turn, and
when a match is found, the corresponding result-expression is evaluated and the resulting value is returned as
the value of the match expression.
The pattern matching function shown in the previous syntax is a lambda expression in which pattern matching
is performed immediately on the argument. The pattern matching function shown in the previous syntax is
equivalent to the following.
For more information about lambda expressions, see Lambda Expressions: The fun Keyword.
The whole set of patterns should cover all the possible matches of the input variable. Frequently, you use the
wildcard pattern ( _ ) as the last pattern to match any previously unmatched input values.
The following code illustrates some of the ways in which the match expression is used. For a reference and
examples of all the possible patterns that can be used, see Pattern Matching.
let list1 = [ 1; 5; 100; 450; 788 ]
printList list1
Guards on Patterns
You can use a when clause to specify an additional condition that the variable must satisfy to match a pattern.
Such a clause is referred to as a guard. The expression following the when keyword is not evaluated unless a
match is made to the pattern associated with that guard.
The following example illustrates the use of a guard to specify a numeric range for a variable pattern. Note that
multiple conditions are combined by using Boolean operators.
rangeTest 10 20 5
rangeTest 10 20 10
rangeTest 10 20 40
Note that because values other than literals cannot be used in the pattern, you must use a when clause if you
have to compare some part of the input against a value. This is shown in the following code.
See Also
F# Language Reference
Active Patterns
Pattern Matching
Pattern Matching
7/29/2017 • 12 min to read • Edit Online
Patterns are rules for transforming input data. They are used throughout the F# language to compare data with a
logical structure or structures, decompose data into constituent parts, or extract information from data in various
ways.
Remarks
Patterns are used in many language constructs, such as the match expression. They are used when you are
processing arguments for functions in let bindings, lambda expressions, and in the exception handlers
associated with the try...with expression. For more information, see Match Expressions, let Bindings, Lambda
Expressions: The fun Keyword, and Exceptions: The try...with Expression.
For example, in the match expression, the pattern is what follows the pipe symbol.
Each pattern acts as a rule for transforming input in some way. In the match expression, each pattern is
examined in turn to see if the input data is compatible with the pattern. If a match is found, the result expression
is executed. If a match is not found, the next pattern rule is tested. The optional when condition part is explained
in Match Expressions.
Supported patterns are shown in the following table. At run time, the input is tested against each of the following
patterns in the order listed in the table, and patterns are applied recursively, from first to last as they appear in
your code, and from left to right for the patterns on each line.
Constant pattern Any numeric, character, or string literal, 1.0 , "test" , 30 , Color.Red
an enumeration constant, or a defined
literal identifier
Wildcard pattern _ _
Constant Patterns
Constant patterns are numeric, character, and string literals, enumeration constants (with the enumeration type
name included). A match expression that has only constant patterns can be compared to a case statement in
other languages. The input is compared with the literal value and the pattern matches if the values are equal. The
type of the literal must be compatible with the type of the input.
The following example demonstrates the use of literal patterns, and also uses a variable pattern and an OR
pattern.
[<Literal>]
let Three = 3
let filter123 x =
match x with
// The following line contains literal patterns combined with an OR pattern.
| 1 | 2 | Three -> printfn "Found 1, 2, or 3!"
// The following line contains a variable pattern.
| var1 -> printfn "%d" var1
Another example of a literal pattern is a pattern based on enumeration constants. You must specify the
enumeration type name when you use enumeration constants.
type Color =
| Red = 0
| Green = 1
| Blue = 2
printColorName Color.Red
printColorName Color.Green
printColorName Color.Blue
Identifier Patterns
If the pattern is a string of characters that forms a valid identifier, the form of the identifier determines how the
pattern is matched. If the identifier is longer than a single character and starts with an uppercase character, the
compiler tries to make a match to the identifier pattern. The identifier for this pattern could be a value marked
with the Literal attribute, a discriminated union case, an exception identifier, or an active pattern case. If no
matching identifier is found, the match fails and the next pattern rule, the variable pattern, is compared to the
input.
Discriminated union patterns can be simple named cases or they can have a value, or a tuple containing multiple
values. If there is a value, you must specify an identifier for the value. In the case of a tuple, you must supply a
tuple pattern with an identifier for each element of the tuple or an identifier with a field name for one or more
named union fields. See the code examples in this section for examples.
The option type is a discriminated union that has two cases, Some and None . One case ( Some ) has a value, but
the other ( None ) is just a named case. Therefore, Some needs to have a variable for the value associated with the
Some case, but None must appear by itself. In the following code, the variable var1 is given the value that is
obtained by matching to the Some case.
In the following example, the PersonName discriminated union contains a mixture of strings and characters that
represent possible forms of names. The cases of the discriminated union are FirstOnly , LastOnly , and
FirstLast .
type PersonName =
| FirstOnly of string
| LastOnly of string
| FirstLast of string * string
For discriminated unions that have named fields, you use the equals sign (=) to extract the value of a named
field. For example, consider a discriminated union with a declaration like the following.
type Shape =
| Rectangle of height : float * width : float
| Circle of radius : float
You can use the named fields in a pattern matching expression as follows.
The use of the named field is optional, so in the previous example, both Circle(r) and Circle(radius = r) have
the same effect.
When you specify multiple fields, use the semicolon (;) as a separator.
Active patterns enable you to define more complex custom pattern matching. For more information about active
patterns, see Active Patterns.
The case in which the identifier is an exception is used in pattern matching in the context of exception handlers.
For information about pattern matching in exception handling, see Exceptions: The try...with Expression.
Variable Patterns
The variable pattern assigns the value being matched to a variable name, which is then available for use in the
execution expression to the right of the -> symbol. A variable pattern alone matches any input, but variable
patterns often appear within other patterns, therefore enabling more complex structures such as tuples and
arrays to be decomposed into variables.
The following example demonstrates a variable pattern within a tuple pattern.
let function1 x =
match x with
| (var1, var2) when var1 > var2 -> printfn "%d is greater than %d" var1 var2
| (var1, var2) when var1 < var2 -> printfn "%d is less than %d" var1 var2
| (var1, var2) -> printfn "%d equals %d" var1 var2
function1 (1,2)
function1 (2, 1)
function1 (0, 0)
as Pattern
The as pattern is a pattern that has an as clause appended to it. The as clause binds the matched value to a
name that can be used in the execution expression of a match expression, or, in the case where this pattern is
used in a let binding, the name is added as a binding to the local scope.
The following example uses an as pattern.
let (var1, var2) as tuple1 = (1, 2)
printfn "%d %d %A" var1 var2 tuple1
OR Pattern
The OR pattern is used when input data can match multiple patterns, and you want to execute the same code as
a result. The types of both sides of the OR pattern must be compatible.
The following example demonstrates the OR pattern.
AND Pattern
The AND pattern requires that the input match two patterns. The types of both sides of the AND pattern must be
compatible.
The following example is like detectZeroTuple shown in the Tuple Pattern section later in this topic, but here
both var1 and var2 are obtained as values by using the AND pattern.
Cons Pattern
The cons pattern is used to decompose a list into the first element, the head, and a list that contains the
remaining elements, the tail.
let list1 = [ 1; 2; 3; 4 ]
printList list1
List Pattern
The list pattern enables lists to be decomposed into a number of elements. The list pattern itself can match only
lists of a specific number of elements.
Array Pattern
The array pattern resembles the list pattern and can be used to decompose arrays of a specific length.
Parenthesized Pattern
Parentheses can be grouped around patterns to achieve the desired associativity. In the following example,
parentheses are used to control associativity between an AND pattern and a cons pattern.
Tuple Pattern
The tuple pattern matches input in tuple form and enables the tuple to be decomposed into its constituent
elements by using pattern matching variables for each position in the tuple.
The following example demonstrates the tuple pattern and also uses literal patterns, variable patterns, and the
wildcard pattern.
let detectZeroTuple point =
match point with
| (0, 0) -> printfn "Both values zero."
| (0, var2) -> printfn "First value is 0 in (0, %d)" var2
| (var1, 0) -> printfn "Second value is 0 in (%d, 0)" var1
| _ -> printfn "Both nonzero."
detectZeroTuple (0, 0)
detectZeroTuple (1, 0)
detectZeroTuple (0, 10)
detectZeroTuple (10, 15)
Record Pattern
The record pattern is used to decompose records to extract the values of fields. The pattern does not have to
reference all fields of the record; any omitted fields just do not participate in matching and are not extracted.
Wildcard Pattern
The wildcard pattern is represented by the underscore ( _ ) character and matches any input, just like the
variable pattern, except that the input is discarded instead of assigned to a variable. The wildcard pattern is often
used within other patterns as a placeholder for values that are not needed in the expression to the right of the
-> symbol. The wildcard pattern is also frequently used at the end of a list of patterns to match any unmatched
input. The wildcard pattern is demonstrated in many code examples in this topic. See the preceding code for one
example.
let detect1 x =
match x with
| 1 -> printfn "Found a 1!"
| (var1 : int) -> printfn "%d" var1
detect1 0
detect1 1
open System.Windows.Forms
let RegisterControl(control:Control) =
match control with
| :? Button as button -> button.Text <- "Registered."
| :? CheckBox as checkbox -> checkbox.Text <- "Registered."
| _ -> ()
Null Pattern
The null pattern matches the null value that can appear when you are working with types that allow a null value.
Null patterns are frequently used when interoperating with .NET Framework code. For example, the return value
of a .NET API might be the input to a match expression. You can control program flow based on whether the
return value is null, and also on other characteristics of the returned value. You can use the null pattern to
prevent null values from propagating to the rest of your program.
The following example uses the null pattern and the variable pattern.
See Also
Match Expressions
Active Patterns
F# Language Reference
Active Patterns
7/29/2017 • 6 min to read • Edit Online
Active patterns enable you to define named partitions that subdivide input data, so that you can use these names
in a pattern matching expression just as you would for a discriminated union. You can use active patterns to
decompose data in a customized manner for each partition.
Syntax
// Complete active pattern definition.
let (|identifer1|identifier2|...|) [ arguments ] = expression
// Partial active pattern definition.
let (|identifier|_|) [ arguments ] = expression
Remarks
In the previous syntax, the identifiers are names for partitions of the input data that is represented by arguments,
or, in other words, names for subsets of the set of all values of the arguments. There can be up to seven partitions
in an active pattern definition. The expression describes the form into which to decompose the data. You can use
an active pattern definition to define the rules for determining which of the named partitions the values given as
arguments belong to. The (| and |) symbols are referred to as banana clips and the function created by this type of
let binding is called an active recognizer.
As an example, consider the following active pattern with an argument.
You can use the active pattern in a pattern matching expression, as in the following example.
TestNumber 7
TestNumber 11
TestNumber 32
7 is odd
11 is odd
32 is even
Another use of active patterns is to decompose data types in multiple ways, such as when the same underlying
data has various possible representations. For example, a Color object could be decomposed into an RGB
representation or an HSB representation.
open System.Drawing
Red
Red: 255 Green: 0 Blue: 0
Hue: 360.000000 Saturation: 1.000000 Brightness: 0.500000
Black
Red: 0 Green: 0 Blue: 0
Hue: 0.000000 Saturation: 0.000000 Brightness: 0.000000
White
Red: 255 Green: 255 Blue: 255
Hue: 0.000000 Saturation: 0.000000 Brightness: 1.000000
Gray
Red: 128 Green: 128 Blue: 128
Hue: 0.000000 Saturation: 0.000000 Brightness: 0.501961
BlanchedAlmond
Red: 255 Green: 235 Blue: 205
Hue: 36.000000 Saturation: 1.000000 Brightness: 0.901961
In combination, these two ways of using active patterns enable you to partition and decompose data into just the
appropriate form and perform the appropriate computations on the appropriate data in the form most
convenient for the computation.
The resulting pattern matching expressions enable data to be written in a convenient way that is very readable,
greatly simplifying potentially complex branching and data analysis code.
parseNumeric "1.1"
parseNumeric "0"
parseNumeric "0.0"
parseNumeric "10"
parseNumeric "Something else"
When using partial active patterns, sometimes the individual choices can be disjoint or mutually exclusive, but
they need not be. In the following example, the pattern Square and the pattern Cube are not disjoint, because
some numbers are both squares and cubes, such as 64. The following program prints out all integers up to
1000000 that are both squares and cubes.
let err = 1.e-10
let examineNumber x =
match x with
| Cube x -> printfn "%d is a cube" x
| _ -> ()
match x with
| Square x -> printfn "%d is a square" x
| _ -> ()
let findSquareCubes x =
if (match x with
| Cube x -> true
| _ -> false
&&
match x with
| Square x -> true
| _ -> false
)
then printf "%d \n" x
1
64
729
4096
15625
46656
117649
262144
531441
1000000
// ParseRegex parses a regular expression and returns a list of the strings that match each group in
// the regular expression.
// List.tail is called to eliminate the first element in the list, which is the full matched expression,
// since only the matches for each group are wanted.
let (|ParseRegex|_|) regex str =
let m = Regex(regex).Match(str)
if m.Success
then Some (List.tail [ for x in m.Groups -> x.Value ])
else None
// Three different date formats are demonstrated here. The first matches two-
// digit dates and the second matches full dates. This code assumes that if a two-digit
// date is provided, it is an abbreviation, not a year in the first century.
let parseDate str =
match str with
| ParseRegex "(\d{1,2})/(\d{1,2})/(\d{1,2})$" [Integer m; Integer d; Integer y]
-> new System.DateTime(y + 2000, m, d)
| ParseRegex "(\d{1,2})/(\d{1,2})/(\d{3,4})" [Integer m; Integer d; Integer y]
-> new System.DateTime(y, m, d)
| ParseRegex "(\d{1,4})-(\d{1,2})-(\d{1,2})" [Integer y; Integer m; Integer d]
-> new System.DateTime(y, m, d)
| _ -> new System.DateTime()
See Also
F# Language Reference
Match Expressions
Loops: for...to Expression
7/29/2017 • 1 min to read • Edit Online
The for...to expression is used to iterate in a loop over a range of values of a loop variable.
Syntax
for identifier = start [ to | downto ] finish do
body-expression
Remarks
The type of the identifier is inferred from the type of the start and finish expressions. Types for these expressions
must be 32-bit integers.
Although technically an expression, for...to is more like a traditional statement in an imperative programming
language. The return type for the body-expression must be unit . The following examples show various uses of
the for...to expression.
function1()
function2()
// A for...to loop that uses functions as the start and finish expressions.
let beginning x y = x - 2*y
let ending x y = x + 2*y
let function3 x y =
for i = (beginning x y) to (ending x y) do
printf "%d " i
printfn ""
function3 10 4
1 2 3 4 5 6 7 8 9 10
10 9 8 7 6 5 4 3 2 1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
See Also
F# Language Reference
Loops: for...in Expression
Loops: while...do Expression
Loops: for...in Expression
7/29/2017 • 3 min to read • Edit Online
This looping construct is used to iterate over the matches of a pattern in an enumerable collection such as a
range expression, sequence, list, array, or other construct that supports enumeration.
Syntax
for pattern in enumerable-expression do
body-expression
Remarks
The for...in expression can be compared to the for each statement in other .NET languages because it is used
to loop over the values in an enumerable collection. However, for...in also supports pattern matching over the
collection instead of just iteration over the whole collection.
The enumerable expression can be specified as an enumerable collection or, by using the .. operator, as a
range on an integral type. Enumerable collections include lists, sequences, arrays, sets, maps, and so on. Any type
that implements System.Collections.IEnumerable can be used.
When you express a range by using the .. operator, you can use the following syntax.
start .. finish
You can also use a version that includes an increment called the skip, as in the following code.
start .. skip .. finish
When you use integral ranges and a simple counter variable as a pattern, the typical behavior is to increment the
counter variable by 1 on each iteration, but if the range includes a skip value, the counter is incremented by the
skip value instead.
Values matched in the pattern can also be used in the body expression.
The following code examples illustrate the use of the for...in expression.
1
5
100
450
788
The following example shows how to loop over a sequence, and how to use a tuple pattern instead of a simple
variable.
let seq1 = seq { for i in 1 .. 10 -> (i, i*i) }
for (a, asqr) in seq1 do
printfn "%d squared is %d" a asqr
1 squared is 1
2 squared is 4
3 squared is 9
4 squared is 16
5 squared is 25
6 squared is 36
7 squared is 49
8 squared is 64
9 squared is 81
10 squared is 100
The following example shows how to loop over a simple integer range.
let function1() =
for i in 1 .. 10 do
printf "%d " i
printfn ""
function1()
1 2 3 4 5 6 7 8 9 10
The following example shows how to loop over a range with a skip of 2, which includes every other element of
the range.
let function2() =
for i in 1 .. 2 .. 10 do
printf "%d " i
printfn ""
function2()
1 3 5 7 9
let function3() =
for c in 'a' .. 'z' do
printf "%c " c
printfn ""
function3()
a b c d e f g h i j k l m n o p q r s t u v w x y z
The following example shows how to use a negative skip value for a reverse iteration.
let function4() =
for i in 10 .. -1 .. 1 do
printf "%d " i
printfn " ... Lift off!"
function4()
The beginning and ending of the range can also be expressions, such as functions, as in the following code.
let function5 x y =
for i in (beginning x y) .. (ending x y) do
printf "%d " i
printfn ""
function5 10 4
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
The next example shows the use of a wildcard character (_) when the element is not needed in the loop.
Note You can use for...in in sequence expressions and other computation expressions, in which case a
customized version of the for...in expression is used. For more information, see Sequences, Asynchronous
Workflows, and Computation Expressions.
See Also
F# Language Reference
Loops: for...to Expression
Loops: while...do Expression
Loops: while...do Expression
7/29/2017 • 1 min to read • Edit Online
The while...do expression is used to perform iterative execution (looping) while a specified test condition is true.
Syntax
while test-expression do
body-expression
Remarks
The test-expression is evaluated; if it is true , the body-expression is executed and the test expression is evaluated
again. The body-expression must have type unit . If the test expression is false , the iteration ends.
The following example illustrates the use of the while...do expression.
open System
lookForValue 10 20
The output of the previous code is a stream of random numbers between 1 and 20, the last of which is 10.
13 19 8 18 16 2 10
Found a 10!
NOTE
You can use while...do in sequence expressions and other computation expressions, in which case a customized version
of the while...do expression is used. For more information, see Sequences, Asynchronous Workflows, and Computation
Expressions.
See Also
F# Language Reference
Loops: for...in Expression
Loops: for...to Expression
Assertions
8/10/2017 • 1 min to read • Edit Online
The assert expression is a debugging feature that you can use to test an expression. Upon failure in Debug mode,
an assertion generates a system error dialog box.
Syntax
assert condition
Remarks
The assert expression has type bool -> unit .
In the previous syntax, condition represents a Boolean expression that is to be tested. If the expression evaluates to
true , execution continues unaffected. If it evaluates to false , a system error dialog box is generated. The error
dialog box has a caption that contains the string Assertion Failed. The dialog box contains a stack trace that
indicates where the assertion failure occurred.
Assertion checking is enabled only when you compile in Debug mode; that is, if the constant DEBUG is defined. In
the project system, by default, the DEBUG constant is defined in the Debug configuration but not in the Release
configuration.
The assertion failure error cannot be caught by using F# exception handling.
NOTE
The assert function resolves to System.Diagnostics.Debug.Assert.
Example
The following code example illustrates the use of the assert expression.
See Also
F# Language Reference
Exception Handling
7/29/2017 • 1 min to read • Edit Online
This section contains information about exception handling support in the F# language.
Related Topics
TITLE DESCRIPTION
Exceptions: The try...with Expression Describes the language construct that supports exception
handling.
Exceptions: The try...finally Expression Describes the language construct that enables you to execute
clean-up code as the stack unwinds when an exception is
thrown.
Exceptions: The invalidArg Function Describes how to generate an invalid argument exception.
Exception Types
7/29/2017 • 1 min to read • Edit Online
There are two categories of exceptions in F#: .NET exception types and F# exception types. This topic describes
how to define and use F# exception types.
Syntax
exception exception-type of argument-type
Remarks
In the previous syntax, exception-type is the name of a new F# exception type, and argument-type represents the
type of an argument that can be supplied when you raise an exception of this type. You can specify multiple
arguments by using a tuple type for argument-type.
A typical definition for an F# exception resembles the following.
You can generate an exception of this type by using the raise function, as follows.
You can use an F# exception type directly in the filters in a try...with expression, as shown in the following
example.
let function1 x y =
try
if x = y then raise (Error1("x"))
else raise (Error2("x", 10))
with
| Error1(str) -> printfn "Error1 %s" str
| Error2(str, i) -> printfn "Error2 %s %d" str i
function1 10 10
function1 9 2
The exception type that you define with the exception keyword in F# is a new type that inherits from
System.Exception .
See Also
Exception Handling
Exceptions: the raise Function
Exception Hierarchy
Exceptions: The try...with Expression
7/29/2017 • 3 min to read • Edit Online
This topic describes the try...with expression, the expression that is used for exception handling in the F#
language.
Syntax
try
expression1
with
| pattern1 -> expression2
| pattern2 -> expression3
...
Remarks
The try...with expression is used to handle exceptions in F#. It is similar to the try...catch statement in C#. In
the preceding syntax, the code in expression1 might generate an exception. The try...with expression returns a
value. If no exception is thrown, the whole expression returns the value of expression1. If an exception is thrown,
each pattern is compared in turn with the exception, and for the first matching pattern, the corresponding
expression, known as the exception handler, for that branch is executed, and the overall expression returns the
value of the expression in that exception handler. If no pattern matches, the exception propagates up the call stack
until a matching handler is found. The types of the values returned from each expression in the exception
handlers must match the type returned from the expression in the try block.
Frequently, the fact that an error occurred also means that there is no valid value that can be returned from the
expressions in each exception handler. A frequent pattern is to have the type of the expression be an option type.
The following code example illustrates this pattern.
let divide1 x y =
try
Some (x / y)
with
| :? System.DivideByZeroException -> printfn "Division by zero!"; None
Exceptions can be .NET exceptions, or they can be F# exceptions. You can define F# exceptions by using the
exception keyword.
You can use a variety of patterns to filter on the exception type and other conditions; the options are summarized
in the following table.
PATTERN DESCRIPTION
:? exception-type as identifier Matches the specified .NET exception type, but gives the
exception a named value.
PATTERN DESCRIPTION
identifier Matches any exception and binds the name to the exception
object. Equivalent to :? System.Exception asidentifier
Examples
The following code examples illustrate the use of the various exception handler patterns.
let function1 x y =
try
if x = y then raise (Error1("x"))
else raise (Error2("x", 10))
with
| Error1(str) -> printfn "Error1 %s" str
| Error2(str, i) -> printfn "Error2 %s %d" str i
function1 10 10
function1 9 2
NOTE
The try...with construct is a separate expression from the try...finally expression. Therefore, if your code requires
both a with block and a finally block, you will have to nest the two expressions.
NOTE
You can use try...with in asynchronous workflows and other computation expressions, in which case a customized
version of the try...with expression is used. For more information, see Asynchronous Workflows, and Computation
Expressions.
See Also
Exception Handling
Exception Types
Exceptions: The try...finally Expression
Exceptions: The try...finally Expression
7/29/2017 • 1 min to read • Edit Online
The try...finally expression enables you to execute clean-up code even if a block of code throws an exception.
Syntax
try
expression1
finally
expression2
Remarks
The try...finally expression can be used to execute the code in expression2 in the preceding syntax regardless
of whether an exception is generated during the execution of expression1.
The type of expression2 does not contribute to the value of the whole expression; the type returned when an
exception does not occur is the last value in expression1. When an exception does occur, no value is returned and
the flow of control transfers to the next matching exception handler up the call stack. If no exception handler is
found, the program terminates. Before the code in a matching handler is executed or the program terminates, the
code in the finally branch is executed.
The following code demonstrates the use of the try...finally expression.
let divide x y =
let stream : System.IO.FileStream = System.IO.File.Create("test.txt")
let writer : System.IO.StreamWriter = new System.IO.StreamWriter(stream)
try
writer.WriteLine("test1");
Some( x / y )
finally
writer.Flush()
printfn "Closing stream"
stream.Close()
let result =
try
divide 100 0
with
| :? System.DivideByZeroException -> printfn "Exception handled."; None
Closing stream
Exception handled.
As you can see from the output, the stream was closed before the outer exception was handled, and the file
test.txt contains the text test1 , which indicates that the buffers were flushed and written to disk even though
the exception transferred control to the outer exception handler.
Note that the try...with construct is a separate construct from the try...finally construct. Therefore, if your
code requires both a with block and a finally block, you have to nest the two constructs, as in the following
code example.
let function1 x y =
try
try
if x = y then raise (InnerError("inner"))
else raise (OuterError("outer"))
with
| InnerError(str) -> printfn "Error1 %s" str
finally
printfn "Always print this."
let function2 x y =
try
function1 x y
with
| OuterError(str) -> printfn "Error2 %s" str
In the context of computation expressions, including sequence expressions and asynchronous workflows,
try...finally expressions can have a custom implementation. For more information, see Computation Expressions.
See Also
Exception Handling
Exceptions: The try...with Expression
Exceptions: the raise Function
7/29/2017 • 1 min to read • Edit Online
The raise function is used to indicate that an error or exceptional condition has occurred. Information about the
error is captured in an exception object.
Syntax
raise (expression)
Remarks
The raise function generates an exception object and initiates a stack unwinding process. The stack unwinding
process is managed by the common language runtime (CLR), so the behavior of this process is the same as it is in
any other .NET language. The stack unwinding process is a search for an exception handler that matches the
generated exception. The search starts in the current try...with expression, if there is one. Each pattern in the
with block is checked, in order. When a matching exception handler is found, the exception is considered handled;
otherwise, the stack is unwound and with blocks up the call chain are checked until a matching handler is found.
Any finally blocks that are encountered in the call chain are also executed in sequence as the stack unwinds.
The raise function is the equivalent of throw in C# or C++. Use reraise in a catch handler to propagate the
same exception up the call chain.
The following code examples illustrate the use of the raise function to generate an exception.
let function1 x y =
try
try
if x = y then raise (InnerError("inner"))
else raise (OuterError("outer"))
with
| InnerError(str) -> printfn "Error1 %s" str
finally
printfn "Always print this."
let function2 x y =
try
function1 x y
with
| OuterError(str) -> printfn "Error2 %s" str
The raise function can also be used to raise .NET exceptions, as shown in the following example.
let divide x y =
if (y = 0) then raise (System.ArgumentException("Divisor cannot be zero!"))
else
x / y
See Also
Exception Handling
Exception Types
Exceptions: The try...with Expression
Exceptions: The try...finally Expression
Exceptions: The failwith Function
Exceptions: The invalidArg Function
7/29/2017 • 1 min to read • Edit Online
title: "Exceptions: The failwith Function (F#) description: Learn how the 'failwith' function generates an F# exception.
keywords: visual f#, f#, functional programming author: cartermp ms.author: phcart ms.date: 05/16/2016 ms.topic:
language-reference ms.prod: .net ms.technology: devlang-fsharp ms.devlang: fsharp
ms.assetid: 2e0c1f28-cc6c-4ecd-bb93-3816c4dd7cd3
Exceptions: The failwith Function
The failwith function generates an F# exception.
Syntax
failwith error-message-string
Remarks
The error-message-string in the previous syntax is a literal string or a value of type string . It becomes the
Message property of the exception.
The exception that is generated by failwith is a System.Exception exception, which is a reference that has the
name Failure in F# code. The following code illustrates the use of failwith to throw an exception.
let divideFailwith x y =
if (y = 0) then failwith "Divisor cannot be zero."
else
x / y
let testDivideFailwith x y =
try
divideFailwith x y
with
| Failure(msg) -> printfn "%s" msg; 0
See Also
Exception Handling
Exception Types
Exceptions: The try...with Expression
Exceptions: The try...finally Expression
Exceptions: the raise Function
Exceptions: The invalidArg Function
7/29/2017 • 1 min to read • Edit Online
Syntax
invalidArg parameter-name error-message-string
Remarks
The parameter-name in the previous syntax is a string with the name of the parameter whose argument was
invalid. The error-message-string is a literal string or a value of type string . It becomes the Message property of
the exception object.
The exception generated by invalidArg is a System.ArgumentException exception. The following code illustrates the
use of invalidArg to throw an exception.
December
January
System.ArgumentException: Month parameter out of range.
See Also
Exception Handling
Exception Types
Exceptions: The try...with Expression
Exceptions: The try...finally Expression
Exceptions: the raise Function
Exceptions: The failwith Function
Attributes
7/29/2017 • 3 min to read • Edit Online
Syntax
[<target:attribute-name(arguments)>]
Remarks
In the previous syntax, the target is optional and, if present, specifies the kind of program entity that the attribute
applies to. Valid values for target are shown in the table that appears later in this document.
The attribute-name refers to the name (possibly qualified with namespaces) of a valid attribute type, with or
without the suffix Attribute that is usually used in attribute type names. For example, the type
ObsoleteAttribute can be shortened to just Obsolete in this context.
The arguments are the arguments to the constructor for the attribute type. If an attribute has a default
constructor, the argument list and parentheses can be omitted. Attributes support both positional arguments and
named arguments. Positional arguments are arguments that are used in the order in which they appear. Named
arguments can be used if the attribute has public properties. You can set these by using the following syntax in
the argument list.
*property-name* = *property-value*
Such property initializations can be in any order, but they must follow any positional arguments. Following is an
example of an attribute that uses positional arguments and property initializations.
open System.Runtime.InteropServices
[<DllImport("kernel32", SetLastError=true)>]
extern bool CloseHandle(nativeint handle)
In this example, the attribute is DllImportAttribute , here used in shortened form. The first argument is a
positional parameter and the second is a property.
Attributes are a .NET programming construct that enables an object known as an attribute to be associated with a
type or other program element. The program element to which an attribute is applied is known as the attribute
target. The attribute usually contains metadata about its target. In this context, metadata could be any data about
the type other than its fields and members.
Attributes in F# can be applied to the following programming constructs: functions, methods, assemblies,
modules, types (classes, records, structures, interfaces, delegates, enumerations, unions, and so on), constructors,
properties, fields, parameters, type parameters, and return values. Attributes are not allowed on let bindings
inside classes, expressions, or workflow expressions.
Typically, the attribute declaration appears directly before the declaration of the attribute target. Multiple attribute
declarations can be used together, as follows.
[<Owner("Jason Carlson")>]
[<Company("Microsoft")>]
type SomeType1 =
Typically encountered attributes include the Obsolete attribute, attributes for security considerations, attributes
for COM support, attributes that relate to ownership of code, and attributes indicating whether a type can be
serialized. The following example demonstrates the use of the Obsolete attribute.
open System
let newFunction x y =
x + 2 * y
For the attribute targets assembly and module , you apply the attributes to a top-level do binding in your
assembly. You can include the word assembly or module in the attribute declaration, as follows.
open System.Reflection
[<assembly:AssemblyVersionAttribute("1.0.0.0")>]
do
printfn "Executing..."
If you omit the attribute target for an attribute applied to a do binding, the F# compiler attempts to determine
the attribute target that makes sense for that attribute. Many attribute classes have an attribute of type
System.AttributeUsageAttribute that includes information about the possible targets supported for that attribute.
If the System.AttributeUsageAttribute indicates that the attribute supports functions as targets, the attribute is
taken to apply to the main entry point of the program. If the System.AttributeUsageAttribute indicates that the
attribute supports assemblies as targets, the compiler takes the attribute to apply to the assembly. Most attributes
do not apply to both functions and assemblies, but in cases where they do, the attribute is taken to apply to the
program's main function. If the attribute target is specified explicitly, the attribute is applied to the specified target.
Although you do not usually need to specify the attribute target explicitly, valid values for target in an attribute
are shown in the following table, along with examples of usage.
See Also
F# Language Reference
Resource Management: The use Keyword
7/29/2017 • 3 min to read • Edit Online
This topic describes the keyword use and the using function, which can control the initialization and release of
resources.
Resources
The term resource is used in more than one way. Yes, resources can be data that an application uses, such as
strings, graphics, and the like, but in this context, resources refers to software or operating system resources, such
as graphics device contexts, file handles, network and database connections, concurrency objects such as wait
handles, and so on. The use of these resources by applications involves the acquisition of the resource from the
operating system or other resource provider, followed by the later release of the resource to the pool so that it can
be provided to another application. Problems occur when applications do not release resources back to the
common pool.
Managing Resources
To efficiently and responsibly manage resources in an application, you must release resources promptly and in a
predictable manner. The .NET Framework helps you do this by providing the System.IDisposable interface. A type
that implements System.IDisposable has the System.IDisposable.Dispose method, which correctly frees resources.
Well-written applications guarantee that System.IDisposable.Dispose is called promptly when any object that
holds a limited resource is no longer needed. Fortunately, most .NET languages provide support to make this
easier, and F# is no exception. There are two useful language constructs that support the dispose pattern: the use
binding and the using function.
use Binding
The use keyword has a form that resembles that of the let binding:
use value = expression
It provides the same functionality as a let binding but adds a call to Dispose on the value when the value goes
out of scope. Note that the compiler inserts a null check on the value, so that if the value is null , the call to
Dispose is not attempted.
The following example shows how to close a file automatically by using the use keyword.
open System.IO
using Function
The using function has the following form:
using (expression1) function-or-lambda
In a using expression, expression1 creates the object that must be disposed. The result of expression1 (the object
that must be disposed) becomes an argument, value, to function-or-lambda, which is either a function that expects
a single remaining argument of a type that matches the value produced by expression1, or a lambda expression
that expects an argument of that type. At the end of the execution of the function, the runtime calls Dispose and
frees the resources (unless the value is null , in which case the call to Dispose is not attempted).
The following example demonstrates the using expression with a lambda expression.
open System.IO
writetofile2 "abc2.txt" "The quick sly fox jumped over the lazy brown dog."
Note that the function could be a function that has some arguments applied already. The following code example
demonstrates this. It creates a file that contains the string XYZ .
The using function and the use binding are nearly equivalent ways to accomplish the same thing. The using
keyword provides more control over when Dispose is called. When you use using , Dispose is called at the end
of the function or lambda expression; when you use the use keyword, Dispose is called at the end of the
containing code block. In general, you should prefer to use use instead of the using function.
See Also
F# Language Reference
Namespaces
7/29/2017 • 4 min to read • Edit Online
A namespace lets you organize code into areas of related functionality by enabling you to attach a name to a
grouping of program elements.
Syntax
namespace [parent-namespaces.]identifier
Remarks
If you want to put code in a namespace, the first declaration in the file must declare the namespace. The contents
of the entire file then become part of the namespace.
Namespaces cannot directly contain values and functions. Instead, values and functions must be included in
modules, and modules are included in namespaces. Namespaces can contain types, modules.
Namespaces can be declared explicitly with the namespace keyword, or implicitly when declaring a module. To
declare a namespace explicitly, use the namespace keyword followed by the namespace name. The following
example shows a code file that declares a namespace Widgets with a type and a module included in that
namespace.
namespace Widgets
type MyWidget1 =
member this.WidgetName = "Widget1"
module WidgetsModule =
let widgetName = "Widget2"
If the entire contents of the file are in one module, you can also declare namespaces implicitly by using the
module keyword and providing the new namespace name in the fully qualified module name. The following
example shows a code file that declares a namespace Widgets and a module WidgetsModule , which contains a
function.
module Widgets.WidgetModule
let widgetFunction x y =
printfn "%A %A" x y
The following code is equivalent to the preceding code, but the module is a local module declaration. In that case,
the namespace must appear on its own line.
namespace Widgets
module WidgetModule =
let widgetFunction x y =
printfn "%A %A" x y
If more than one module is required in the same file in one or more namespaces, you must use local module
declarations. When you use local module declarations, you cannot use the qualified namespace in the module
declarations. The following code shows a file that has a namespace declaration and two local module declarations.
In this case, the modules are contained directly in the namespace; there is no implicitly created module that has
the same name as the file. Any other code in the file, such as a do binding, is in the namespace but not in the
inner modules, so you need to qualify the module member widgetFunction by using the module name.
namespace Widgets
module WidgetModule1 =
let widgetFunction x y =
printfn "Module1 %A %A" x y
module WidgetModule2 =
let widgetFunction x y =
printfn "Module2 %A %A" x y
module useWidgets =
do
WidgetModule1.widgetFunction 10 20
WidgetModule2.widgetFunction 5 6
Module1 10 20
Module2 5 6
Nested Namespaces
When you create a nested namespace, you must fully qualify it. Otherwise, you create a new top-level namespace.
Indentation is ignored in namespace declarations.
The following example shows how to declare a nested namespace.
namespace Outer
namespace global
type SomeType() =
member this.SomeMember = 0
You can also use global to reference the top-level .NET namespace, for example, to resolve name conflicts with
other namespaces.
global.System.Console.WriteLine("Hello World!")
##
F# 4.1 introduces the notion of namespaces which allow for all contained code to be mutually recursive. This is
done via namespace rec . Use of namespace rec can alleviate some pains in not being able to write mutually
referential code between types and modules. The following is an example of this:
member self.Peel() = BananaHelpers.peel self // Note the dependency on the BananaHelpers module.
member self.SqueezeJuiceOut() = raise (DontSqueezeTheBananaException self) // This member depends on the
exception above.
module BananaHelpers =
let peel (b : Banana) =
let flip banana =
match banana.Orientation with
| Up ->
banana.Orientation <- Down
banana
| Down -> banana
Note that the exception DontSqueezeTheBananaException and the class Banana both refer to each other.
Additionally, the module BananaHelpers and the class Banana also refer to each other. This would not be possible
to express in F# if you removed the rec keyword from the MutualReferences namespace.
This feature is also available for top-level Modules in F# 4.1 or higher.
See Also
F# Language Reference
Modules
F# RFC FS-1009 - Allow mutually referential types and modules over larger scopes within files
Modules
7/29/2017 • 6 min to read • Edit Online
In the context of the F# language, a module is a grouping of F# code, such as values, types, and function values,
in an F# program. Grouping code in modules helps keep related code together and helps avoid name conflicts in
your program.
Syntax
// Top-level module declaration.
module [accessibility-modifier] [qualified-namespace.]module-name
declarations
// Local module declaration.
module [accessibility-modifier] module-name =
declarations
Remarks
An F# module is a grouping of F# code constructs such as types, values, function values, and code in do
bindings. It is implemented as a common language runtime (CLR) class that has only static members. There are
two types of module declarations, depending on whether the whole file is included in the module: a top-level
module declaration and a local module declaration. A top-level module declaration includes the whole file in the
module. A top-level module declaration can appear only as the first declaration in a file.
In the syntax for the top-level module declaration, the optional qualified-namespace is the sequence of nested
namespace names that contains the module. The qualified namespace does not have to be previously declared.
You do not have to indent declarations in a top-level module. You do have to indent all declarations in local
modules. In a local module declaration, only the declarations that are indented under that module declaration are
part of the module.
If a code file does not begin with a top-level module declaration or a namespace declaration, the whole contents
of the file, including any local modules, becomes part of an implicitly created top-level module that has the same
name as the file, without the extension, with the first letter converted to uppercase. For example, consider the
following file.
module Program
let x = 40
If you have multiple modules in a file, you must use a local module declaration for each module. If an enclosing
namespace is declared, these modules are part of the enclosing namespace. If an enclosing namespace is not
declared, the modules become part of the implicitly created top-level module. The following code example shows
a code file that contains multiple modules. The compiler implicitly creates a top-level module named
Multiplemodules , and MyModule1 and MyModule2 are nested in that top-level module.
// In the file multiplemodules.fs.
// MyModule1
module MyModule1 =
// Indent all program elements within modules that are declared with an equal sign.
let module1Value = 100
let module1Function x =
x + 10
// MyModule2
module MyModule2 =
If you have multiple files in a project or in a single compilation, or if you are building a library, you must include
a namespace declaration or module declaration at the top of the file. The F# compiler only determines a module
name implicitly when there is only one file in a project or compilation command line, and you are creating an
application.
The accessibility-modifier can be one of the following: public , private , internal . For more information, see
Access Control. The default is public.
You can open the module or one or more of the namespaces to simplify the code. For more information about
opening namespaces and modules, see Import Declarations: The open Keyword.
The following code example shows a top-level module that contains all the code up to the end of the file.
module Arithmetic
let add x y =
x + y
let sub x y =
x - y
To use this code from another file in the same project, you either use qualified names or you open the module
before you use the functions, as shown in the following examples.
Nested Modules
Modules can be nested. Inner modules must be indented as far as outer module declarations to indicate that they
are inner modules, not new modules. For example, compare the following two examples. Module Z is an inner
module in the following code.
module Y =
let x = 1
module Z =
let z = 5
module Y =
let x = 1
module Z =
let z = 5
Module Z is also a sibling module in the following code, because it is not indented as far as other declarations
in module Y .
module Y =
let x = 1
module Z =
let z = 5
Finally, if the outer module has no declarations and is followed immediately by another module declaration, the
new module declaration is assumed to be an inner module, but the compiler will warn you if the second module
definition is not indented farther than the first.
module Y =
module Z =
let z = 5
If you want all the code in a file to be in a single outer module and you want inner modules, the outer module
does not require the equal sign, and the declarations, including any inner module declarations, that will go in the
outer module do not have to be indented. Declarations inside the inner module declarations do have to be
indented. The following code shows this case.
// The top-level module declaration can be omitted if the file is named
// TopLevel.fs or topLevel.fs, and the file is the only file in an
// application.
module TopLevel
let topLevelX = 5
module Inner1 =
let inner1X = 1
module Inner2 =
let inner2X = 5
member self.Peel() = BananaHelpers.peel self // Note the dependency on the BananaHelpers module.
member self.SqueezeJuiceOut() = raise (DontSqueezeTheBananaException self) // This member depends on
the exception above.
Note that the exception DontSqueezeTheBananaException and the class Banana both refer to each other.
Additionally, the module BananaHelpers and the class Banana also refer to each other. This would not be
possible to express in F# if you removed the rec keyword from the RecursiveModule module.
This capability is also possible in Namespaces with F# 4.1.
See Also
F# Language Reference Namespaces F# RFC FS-1009 - Allow mutually referential types and modules over larger
scopes within files
Import Declarations: The open Keyword
7/29/2017 • 3 min to read • Edit Online
NOTE
The API reference links in this article will take you to MSDN. The docs.microsoft.com API reference is not complete.
An import declaration specifies a module or namespace whose elements you can reference without using a fully
qualified name.
Syntax
open module-or-namespace-name
Remarks
Referencing code by using the fully qualified namespace or module path every time can create code that is hard to
write, read, and maintain. Instead, you can use the open keyword for frequently used modules and namespaces so
that when you reference a member of that module or namespace, you can use the short form of the name instead
of the fully qualified name. This keyword is similar to the using keyword in C#, using namespace in Visual C++,
and Imports in Visual Basic.
The module or namespace provided must be in the same project or in a referenced project or assembly. If it is not,
you can add a reference to the project, or use the -reference command - line option (or its abbreviation, -r ).
For more information, see Compiler Options.
The import declaration makes the names available in the code that follows the declaration, up to the end of the
enclosing namespace, module, or file.
When you use multiple import declarations, they should appear on separate lines.
The following code shows the use of the open keyword to simplify code.
The F# compiler does not emit an error or warning when ambiguities occur when the same name occurs in more
than one open module or namespace. When ambiguities occur, F# gives preference to the more recently opened
module or namespace. For example, in the following code, empty means Seq.empty , even though empty is
located in both the List and Seq modules.
open List
open Seq
printfn "%A" empty
Therefore, be careful when you open modules or namespaces such as List or Seq that contain members that
have identical names; instead, consider using the qualified names. You should avoid any situation in which the
code is dependent upon the order of the import declarations.
NAMESPACE DESCRIPTION
AutoOpen Attribute
You can apply the AutoOpen attribute to an assembly if you want to automatically open a namespace or module
when the assembly is referenced. You can also apply the AutoOpen attribute to a module to automatically open
that module when the parent module or namespace is opened. For more information, see Core.AutoOpenAttribute
Class.
RequireQualifiedAccess Attribute
Some modules, records, or union types may specify the RequireQualifiedAccess attribute. When you reference
elements of those modules, records, or unions, you must use a qualified name regardless of whether you include
an import declaration. If you use this attribute strategically on types that define commonly used names, you help
avoid name collisions and thereby make code more resilient to changes in libraries. For more information, see
Core.RequireQualifiedAccessAttribute Class.
See Also
# Language Reference
Namespaces
Modules
Signatures
7/29/2017 • 4 min to read • Edit Online
A signature file contains information about the public signatures of a set of F# program elements, such as types,
namespaces, and modules. It can be used to specify the accessibility of these program elements.
Remarks
For each F# code file, you can have a signature file, which is a file that has the same name as the code file but with
the extension .fsi instead of .fs. Signature files can also be added to the compilation command-line if you are using
the command line directly. To distinguish between code files and signature files, code files are sometimes referred
to as implementation files. In a project, the signature file should precede the associated code file.
A signature file describes the namespaces, modules, types, and members in the corresponding implementation
file. You use the information in a signature file to specify what parts of the code in the corresponding
implementation file can be accessed from code outside the implementation file, and what parts are internal to the
implementation file. The namespaces, modules, and types that are included in the signature file must be a subset
of the namespaces, modules, and types that are included in the implementation file. With some exceptions noted
later in this topic, those language elements that are not listed in the signature file are considered private to the
implementation file. If no signature file is found in the project or command line, the default accessibility is used.
For more information about the default accessibility, see Access Control.
In a signature file, you do not repeat the definition of the types and the implementations of each method or
function. Instead, you use the signature for each method and function, which acts as a complete specification of
the functionality that is implemented by a module or namespace fragment. The syntax for a type signature is the
same as that used in abstract method declarations in interfaces and abstract classes, and is also shown by
IntelliSense and by the F# interpreter fsi.exe when it displays correctly compiled input.
If there is not enough information in the type signature to indicate whether a type is sealed, or whether it is an
interface type, you must add an attribute that indicates the nature of the type to the compiler. Attributes that you
use for this purpose are described in the following table.
ATTRIBUTE DESCRIPTION
[<Sealed>] For a type that has no abstract members, or that should not
be extended.
The compiler produces an error if the attributes are not consistent between the signature and the declaration in
the implementation file.
Use the keyword val to create a signature for a value or function value. The keyword type introduces a type
signature.
You can generate a signature file by using the --sig compiler option. Generally, you do not write .fsi files
manually. Instead, you generate .fsi files by using the compiler, add them to your project, if you have one, and edit
them by removing methods and functions that you do not want to be accessible.
There are several rules for type signatures:
Type abbreviations in an implementation file must not match a type without an abbreviation in a signature
file.
Records and discriminated unions must expose either all or none of their fields and constructors, and the
order in the signature must match the order in the implementation file. Classes can reveal some, all, or
none of their fields and methods in the signature.
Classes and structures that have constructors must expose the declarations of their base classes (the
inherits declaration). Also, classes and structures that have constructors must expose all of their abstract
methods and interface declarations.
Interface types must reveal all their methods and interfaces.
The rules for value signatures are as follows:
Modifiers for accessibility ( public , internal , and so on) and the inline and mutable modifiers in the
signature must match those in the implementation.
The number of generic type parameters (either implicitly inferred or explicitly declared) must match, and
the types and type constraints in generic type parameters must match.
If the Literal attribute is used, it must appear in both the signature and the implementation, and the same
literal value must be used for both.
The pattern of parameters (also known as the arity) of signatures and implementations must be consistent.
The following code example shows an example of a signature file that has namespace, module, function value, and
type signatures together with the appropriate attributes. It also shows the corresponding implementation file.
// Module1.fsi
namespace Library1
module Module1 =
val function1 : int -> int
type Type1 =
new : unit -> Type1
member method1 : unit -> unit
member method2 : unit -> unit
[<Sealed>]
type Type2 =
new : unit -> Type2
member method1 : unit -> unit
member method2 : unit -> unit
[<Interface>]
type InterfaceType1 =
abstract member method1 : int -> int
abstract member method2 : string -> unit
module Module1 =
let function1 x = x + 1
type Type1() =
member type1.method1() =
printfn "test1.method1"
member type1.method2() =
printfn "test1.method2"
[<Sealed>]
type Type2() =
member type2.method1() =
printfn "test1.method1"
member type1.method2() =
printfn "test1.method2"
[<Interface>]
type InterfaceType1 =
abstract member method1 : int -> int
abstract member method2 : string -> unit
See Also
F# Language Reference
Access Control
Compiler Options
Units of Measure
7/29/2017 • 7 min to read • Edit Online
Floating point and signed integer values in F# can have associated units of measure, which are typically used to
indicate length, volume, mass, and so on. By using quantities with units, you enable the compiler to verify that
arithmetic relationships have the correct units, which helps prevent programming errors.
Syntax
[<Measure>] type unit-name [ = measure ]
Remarks
The previous syntax defines unit-name as a unit of measure. The optional part is used to define a new measure in
terms of previously defined units. For example, the following line defines the measure cm (centimeter).
[<Measure>] type cm
The following line defines the measure ml (milliliter) as a cubic centimeter ( cm^3 ).
In the previous syntax, measure is a formula that involves units. In formulas that involve units, integral powers are
supported (positive and negative), spaces between units indicate a product of the two units, * also indicates a
product of units, and / indicates a quotient of units. For a reciprocal unit, you can either use a negative integer
power or a / that indicates a separation between the numerator and denominator of a unit formula. Multiple
units in the denominator should be surrounded by parentheses. Units separated by spaces after a / are
interpreted as being part of the denominator, but any units following a * are interpreted as being part of the
numerator.
You can use 1 in unit expressions, either alone to indicate a dimensionless quantity, or together with other units,
such as in the numerator. For example, the units for a rate would be written as 1/s , where s indicates seconds.
Parentheses are not used in unit formulas. You do not specify numeric conversion constants in the unit formulas;
however, you can define conversion constants with units separately and use them in unit-checked computations.
Unit formulas that mean the same thing can be written in various equivalent ways. Therefore, the compiler
converts unit formulas into a consistent form, which converts negative powers to reciprocals, groups units into a
single numerator and a denominator, and alphabetizes the units in the numerator and denominator.
For example, the unit formulas kg m s^-2 and m /s s * kg are both converted to kg m/s^2 .
You use units of measure in floating point expressions. Using floating point numbers together with associated
units of measure adds another level of type safety and helps avoid the unit mismatch errors that can occur in
formulas when you use weakly typed floating point numbers. If you write a floating point expression that uses
units, the units in the expression must match.
You can annotate literals with a unit formula in angle brackets, as shown in the following examples.
1.0<cm>
55.0<miles/hour>
You do not put a space between the number and the angle bracket; however, you can include a literal suffix such
as f , as in the following example.
Such an annotation changes the type of the literal from its primitive type (such as float ) to a dimensioned type,
such as float<cm> or, in this case, float<miles/hour> . A unit annotation of <1> indicates a dimensionless
quantity, and its type is equivalent to the primitive type without a unit parameter.
The type of a unit of measure is a floating point or signed integral type together with an extra unit annotation,
indicated in brackets. Thus, when you write the type of a conversion from g (grams) to kg (kilograms), you
describe the types as follows.
Units of measure are used for compile-time unit checking but are not persisted in the run-time environment.
Therefore, they do not affect performance.
Units of measure can be applied to any type, not just floating point types; however, only floating point types,
signed integral types, and decimal types support dimensioned quantities. Therefore, it only makes sense to use
units of measure on the primitive types and on aggregates that contain these primitive types.
The following example illustrates the use of units of measure.
// Mass, grams.
[<Measure>] type g
// Mass, kilograms.
[<Measure>] type kg
// Weight, pounds.
[<Measure>] type lb
// Distance, meters.
[<Measure>] type m
// Distance, cm
[<Measure>] type cm
// Distance, inches.
[<Measure>] type inch
// Distance, feet
[<Measure>] type ft
// Time, seconds.
[<Measure>] type s
// Force, Newtons.
[<Measure>] type N = kg m / s
// Pressure, bar.
[<Measure>] type bar
// Pressure, Pascals
[<Measure>] type Pa = N / m^2
// Volume, milliliters.
[<Measure>] type ml
// Volume, liters.
[<Measure>] type L
The following code example illustrates how to convert from a dimensionless floating point number to a
dimensioned floating point value. You just multiply by 1.0, applying the dimensions to the 1.0. You can abstract
this into a function like degreesFahrenheit .
Also, when you pass dimensioned values to functions that expect dimensionless floating point numbers, you must
cancel out the units or cast to float by using the float operator. In this example, you divide by 1.0<degC> for
the arguments to printf because printf expects dimensionless quantities.
[<Measure>] type degC // temperature, Celsius/Centigrade
[<Measure>] type degF // temperature, Fahrenheit
The following example session shows the outputs from and inputs to this code.
// Distance, meters.
[<Measure>] type m
// Time, seconds.
[<Measure>] type s
let v1 = 3.1<m/s>
let v2 = 2.7<m/s>
let x1 = 1.2<m>
let t1 = 1.0<s>
Units at Runtime
Units of measure are used for static type checking. When floating point values are compiled, the units of measure
are eliminated, so the units are lost at run time. Therefore, any attempt to implement functionality that depends
on checking the units at run time is not possible. For example, implementing a ToString function to print out the
units is not possible.
Conversions
To convert a type that has units (for example, float<'u> ) to a type that does not have units, you can use the
standard conversion function. For example, you can use float to convert to a float value that does not have
units, as shown in the following code.
[<Measure>]
type cm
let length = 12.0<cm>
let x = float length
To convert a unitless value to a value that has units, you can multiply by a 1 or 1.0 value that is annotated with the
appropriate units. However, for writing interoperability layers, there are also some explicit functions that you can
use to convert unitless values to values with units. These are in the Microsoft.FSharp.Core.LanguagePrimitives
module. For example, to convert from a unitless float to a float<cm> , use FloatWithMeasure, as shown in the
following code.
open Microsoft.FSharp.Core
let height:float<cm> = LanguagePrimitives.FloatWithMeasure x
See Also
F# Language Reference
XML Documentation
7/29/2017 • 3 min to read • Edit Online
You can produce documentation from triple-slash (///) code comments in F#. XML comments can precede
declarations in code files (.fs) or signature (.fsi) files.
Recommended Tags
There are two ways to write XML documentation comments. One is to just write the documentation directly in a
triple-slash comment, without using XML tags. If you do this, the entire comment text is taken as the summary
documentation for the code construct that immediately follows. Use this method when you want to write only a
brief summary for each construct. The other method is to use XML tags to provide more structured
documentation. The second method enables you to specify separate notes for a short summary, additional
remarks, documentation for each parameter and type parameter and exceptions thrown, and a description of the
return value. The following table describes XML tags that are recognized in F# XML code comments.
<param name="name">description</param> Specifies the name and description for a function or method
parameter.
<typeparam name="name">description</typeparam> Specifies the name and description for a type parameter.
<exception cref="type">description</exception> Specifies the type of exception that can be generated and the
circumstances under which it is thrown.
TAG SYNTAX DESCRIPTION
<seealso cref="reference"/> Specifies a See Also link to the documentation for another
type. The reference is the name as it appears in the XML
documentation file. See Also links usually appear at the
bottom of a documentation page.
Example
Description
The following is a typical XML documentation comment in a signature file.
Code
/// <summary>Builds a new string whose characters are the results of applying the function <c>mapping</c>
/// to each of the characters of the input string and concatenating the resulting
/// strings.</summary>
/// <param name="mapping">The function to produce a string from each character of the input string.</param>
///<param name="str">The input string.</param>
///<returns>The concatenated string.</returns>
///<exception cref="System.ArgumentNullException">Thrown when the input string is null.</exception>
val collect : (char -> string) -> string -> string
Example
Description
The following example shows the alternative method, without XML tags. In this example, the entire text in the
comment is considered a summary. Note that if you do not specify a summary tag explicitly, you should not
specify other tags, such as param or returns tags.
Code
/// Creates a new string whose characters are the result of applying
/// the function mapping to each of the characters of the input string
/// and concatenating the resulting strings.
val collect : (char -> string) -> string -> string
See Also
F# Language Reference
Compiler Options
Lazy Computations
7/29/2017 • 1 min to read • Edit Online
Lazy computations are computations that are not evaluated immediately, but are instead evaluated when the result
is needed. This can help to improve the performance of your code.
Syntax
let identifier = lazy ( expression )
Remarks
In the previous syntax, expression is code that is evaluated only when a result is required, and identifier is a value
that stores the result. The value is of type Lazy<'T> , where the actual type that is used for 'T is determined from
the result of the expression.
Lazy computations enable you to improve performance by restricting the execution of a computation to only those
situations in which a result is needed.
To force the computation to be performed, you call the method Force . Force causes the execution to be
performed only one time. Subsequent calls to Force return the same result, but do not execute any code.
The following code illustrates the use of lazy computation and the use of Force . In this code, the type of result is
Lazy<int> , and the Force method returns an int .
let x = 10
let result = lazy (x + 10)
printfn "%d" (result.Force())
Lazy evaluation, but not the Lazy type, is also used for sequences. For more information, see Sequences.
See Also
F# Language Reference
LazyExtensions module
Computation Expressions
8/10/2017 • 10 min to read • Edit Online
Computation expressions in F# provide a convenient syntax for writing computations that can be sequenced
and combined using control flow constructs and bindings. They can be used to provide a convenient syntax for
monads, a functional programming feature that can be used to manage data, control, and side effects in
functional programs.
Built-in Workflows
Sequence expressions are an example of a computation expression, as are asynchronous workflows and query
expressions. For more information, see Sequences, Asynchronous Workflows, and Query Expressions.
Certain features are common to both sequence expressions and asynchronous workflows and illustrate the
basic syntax for a computation expression:
builder-name { expression }
The previous syntax specifies that the given expression is a computation expression of a type specified by
builder-name. The computation expression can be a built-in workflow, such as seq or async , or it can be
something you define. The builder-name is the identifier for an instance of a special type known as the builder
type. The builder type is a class type that defines special methods that govern the way the fragments of the
computation expression are combined, that is, code that controls how the expression executes. Another way to
describe a builder class is to say that it enables you to customize the operation of many F# constructs, such as
loops and bindings.
In computation expressions, two forms are available for some common language constructs. You can invoke the
variant constructs by using a ! (bang) suffix on certain keywords, such as let! , do! , and so on. These special
forms cause certain functions defined in the builder class to replace the ordinary built-in behavior of these
operations. These forms resemble the yield! form of the yield keyword that is used in sequence expressions.
For more information, see Sequences.
Bind M<'T> * ('T -> M<'U>) -> M<'U> Called for let! and do! in
computation expressions.
For seq<'T> * ('T -> M<'U>) -> M<'U> Called for for...do expressions in
or computation expressions.
TryFinally M<'T> * (unit -> unit) -> M<'T> Called for try...finally
expressions in computation
expressions.
TryWith M<'T> * (exn -> M<'T>) -> M<'T> Called for try...with expressions in
computation expressions.
Using 'T * ('T -> M<'U>) -> M<'U> when Called for use bindings in
'U :> IDisposable
computation expressions.
While (unit -> bool) * M<'T> -> M<'T> Called for while...do expressions in
computation expressions.
Many of the methods in a builder class use and return an M<'T> construct, which is typically a separately
defined type that characterizes the kind of computations being combined, for example, Async<'T> for
asynchronous workflows and Seq<'T> for sequence workflows. The signatures of these methods enable them
to be combined and nested with each other, so that the workflow object returned from one construct can be
passed to the next. The compiler, when it parses a computation expression, converts the expression into a series
of nested function calls by using the methods in the preceding table and the code in the computation
expression.
The nested expression is of the following form:
In the above code, the calls to Run and Delay are omitted if they are not defined in the computation
expression builder class. The body of the computation expression, here denoted as {| cexpr |} , is translated
into calls involving the methods of the builder class by the translations described in the following table. The
computation expression {| cexpr |} is defined recursively according to these translations where expr is an
F# expression and cexpr is a computation expression.
EXPRESSION TRANSLATION
{| let! pattern = expr in cexpr |} builder.Bind(expr, (fun pattern -> {| cexpr |}))
{| use pattern = expr in cexpr |} builder.Using(expr, (fun pattern -> {| cexpr |}))
{| if expr then cexpr0 else cexpr1 |} if expr then {| cexpr0 |} else {| cexpr1 |}
{| match expr with | pattern_i -> cexpr_i |} match expr with | pattern_i -> {| cexpr_i |}
{| try cexpr with | pattern_i -> expr_i |} builder.TryWith(builder.Delay({| cexpr |}), (fun
value -> match value with | pattern_i -> expr_i |
exn -> reraise exn)))
module Eventually =
// The bind for the computations. Append 'func' to the
// computation.
let rec bind func expr =
match expr with
| Done value -> NotYetDone (fun () -> func value)
| NotYetDone work -> NotYetDone (fun () -> bind func (work()))
type OkOrException<'T> =
| Ok of 'T
| Exception of System.Exception
Custom Operations
You can define a custom operation on a computation expression and use a custom operation as an operator in
a computation expression. For example, you can include a query operator in a query expression. When you
define a custom operation, you must define the Yield and For methods in the computation expression. To define
a custom operation, put it in a builder class for the computation expression, and then apply the
CustomOperationAttribute . This attribute takes a string as an argument, which is the name to be used in a
custom operation. This name comes into scope at the start of the opening curly brace of the computation
expression. Therefore, you shouldn’t use identifiers that have the same name as a custom operation in this
block. For example, avoid the use of identifiers such as all or last in query expressions.
See Also
F# Language Reference
Asynchronous Workflows
Sequences
Query Expressions
Asynchronous Workflows
7/29/2017 • 4 min to read • Edit Online
NOTE
The API reference link will take you to MSDN. The docs.microsoft.com API reference is not complete.
This topic describes support in F# for performing computations asynchronously, that is, without blocking
execution of other work. For example, asynchronous computations can be used to write applications that have
UIs that remain responsive to users as the application performs other work.
Syntax
async { expression }
Remarks
In the previous syntax, the computation represented by expression is set up to run asynchronously, that is,
without blocking the current computation thread when asynchronous sleep operations, I/O, and other
asynchronous operations are performed. Asynchronous computations are often started on a background thread
while execution continues on the current thread. The type of the expression is Async<'T> , where 'T is the type
returned by the expression when the return keyword is used. The code in such an expression is referred to as
an asynchronous block, or async block.
There are a variety of ways of programming asynchronously, and the Async class provides methods that
support several scenarios. The general approach is to create Async objects that represent the computation or
computations that you want to run asynchronously, and then start these computations by using one of the
triggering functions. The various triggering functions provide different ways of running asynchronous
computations, and which one you use depends on whether you want to use the current thread, a background
thread, or a .NET Framework task object, and whether there are continuation functions that should run when the
computation finishes. For example, to start an asynchronous computation on the current thread, you can use
Async.StartImmediate . When you start an asynchronous computation from the UI thread, you do not block the
main event loop that processes user actions such as keystrokes and mouse activity, so your application remains
responsive.
In addition to let! , you can use use! to perform asynchronous bindings. The difference between let! and
use! is the same as the difference between let and use . For use! , the object is disposed of at the close of
the current scope. Note that in the current release of the F# language, use! does not allow a value to be
initialized to null, even though use does.
Asynchronous Primitives
A method that performs a single asynchronous task and returns the result is called an asynchronous primitive,
and these are designed specifically for use with let! . Several asynchronous primitives are defined in the F#
core library. Two such methods for Web applications are defined in the module
Microsoft.FSharp.Control.WebExtensions : WebRequest.AsyncGetResponse and WebClient.AsyncDownloadString .
Both primitives download data from a Web page, given a URL. AsyncGetResponse produces a
System.Net.WebResponse object, and AsyncDownloadString produces a string that represents the HTML for a Web
page.
Several primitives for asynchronous I/O operations are included in the
Microsoft.FSharp.Control.CommonExtensions module. These extension methods of the System.IO.Stream class are
Stream.AsyncRead and Stream.AsyncWrite .
Additional asynchronous primitives are available in the F# PowerPack. You can also write your own
asynchronous primitives by defining a function whose complete body is enclosed in an async block.
To use asynchronous methods in the .NET Framework that are designed for other asynchronous models with
the F# asynchronous programming model, you create a function that returns an F# Async object. The F# library
has functions that make this easy to do.
One example of using asynchronous workflows is included here; there are many others in the documentation
for the methods of the Async class.
This example shows how to use asynchronous workflows to perform computations in parallel.
In the following code example, a function fetchAsync gets the HTML text returned from a Web request. The
fetchAsync function contains an asynchronous block of code. When a binding is made to the result of an
asynchronous primitive, in this case AsyncDownloadString , let! is used instead of let.
You use the function Async.RunSynchronously to execute an asynchronous operation and wait for its result. As
an example, you can execute multiple asynchronous operations in parallel by using the Async.Parallel function
together with the Async.RunSynchronously function. The Async.Parallel function takes a list of the Async
objects, sets up the code for each Async task object to run in parallel, and returns an Async object that
represents the parallel computation. Just as for a single operation, you call Async.RunSynchronously to start the
execution.
The runAll function launches three asynchronous workflows in parallel and waits until they have all
completed.
open System.Net
open Microsoft.FSharp.Control.WebExtensions
let runAll() =
urlList
|> Seq.map fetchAsync
|> Async.Parallel
|> Async.RunSynchronously
|> ignore
runAll()
See Also
F# Language Reference
Computation Expressions
Control.Async Class
Query Expressions
7/29/2017 • 41 min to read • Edit Online
NOTE
The API reference links in this article will take you to MSDN. The docs.microsoft.com API reference is not complete.
Query expressions enable you to query a data source and put the data in a desired form. Query expressions
provide support for LINQ in F#.
Syntax
query { expression }
Remarks
Query expressions are a type of computation expression similar to sequence expressions. Just as you specify a
sequence by providing code in a sequence expression, you specify a set of data by providing code in a query
expression. In a sequence expression, the yield keyword identifies data to be returned as part of the resulting
sequence. In query expressions, the select keyword performs the same function. In addition to the select
keyword, F# also supports a number of query operators that are much like the parts of a SQL SELECT statement.
Here is an example of a simple query expression, along with code that connects to the Northwind OData source.
// Use the OData type provider to create types that can be used to access the Northwind database.
// Add References to FSharp.Data.TypeProviders and System.Data.Services.Client
open Microsoft.FSharp.Data.TypeProviders
// A query expression.
let query1 =
query {
for customer in db.Customers do
select customer
}
// Print results
query1
|> Seq.iter (fun customer -> printfn "Company: %s Contact: %s" customer.CompanyName customer.ContactName)
In the previous code example, the query expression is in curly braces. The meaning of the code in the expression
is, return every customer in the Customers table in the database in the query results. Query expressions return a
type that implements IQueryable<T> and IEnumerable<T>, and so they can be iterated using the Seq module as
the example shows.
Every computation expression type is built from a builder class. The builder class for the query computation
expression is QueryBuilder . For more information, see Computation Expressions and Linq.QueryBuilder Class.
Query Operators
Query operators enable you to specify the details of the query, such as to put criteria on records to be returned,
or specify the sorting order of results. The query source must support the query operator. If you attempt to use
an unsupported query operator, System.NotSupportedException will be thrown.
Only expressions that can be translated to SQL are allowed in query expressions. For example, no function calls
are allowed in the expressions when you use the where query operator.
Table 1 shows available query operators. In addition, see Table2, which compares SQL queries and the
equivalent F# query expressions later in this topic. Some query operators aren't supported by some type
providers. In particular, the OData type provider is limited in the query operators that it supports due to
limitations in OData. For more information, see ODataService Type Provider (F#).
This table assumes a database in the following form:
The code in the tables that follow also assumes the following database connection code. Projects should add
references to System.Data, System.Data.Linq, and FSharp.Data.TypeProviders assemblies. The code that creates
this database is included at the end of this topic.
open System
open Microsoft.FSharp.Data.TypeProviders
open System.Data.Linq.SqlClient
open System.Linq
open Microsoft.FSharp.Linq
let db = schema.GetDataContext()
query {
for student in db.Student do
select student.Age.Value
contains 11
}
query {
for student in db.Student do
select student
count
}
query {
for number in data do
last
}
query {
for number in data do
where (number < 0)="" lastordefault=""
}="">
query {
for student in db.Student do
where (student.StudentID = 1)
select student
exactlyOne
}
`exactlyOneOrDefault` Selects the single, specific element of those selected so far, or
a default value if that element is not found.
query {
for student in db.Student do
where (student.StudentID = 1)
select student
exactlyOneOrDefault
}
query {
for student in db.Student do
select student
headOrDefault
}
query {
for student in db.Student do
select student
}
query {
for student in db.Student do
where (student.StudentID > 4)
select student
}
`minBy` Selects a value for each element selected so far and returns
the minimum resulting value.
query {
for student in db.Student do
minBy student.StudentID
}
`maxBy` Selects a value for each element selected so far and returns
the maximum resulting value.
query {
for student in db.Student do
maxBy student.StudentID
}
query {
for student in db.Student do
groupBy student.Age into g
select (g.Key, g.Count())
}
query {
for student in db.Student do
sortBy student.Name
select student
}
query {
for student in db.Student do
sortByDescending student.Name
select student
}
query {
for student in db.Student do
where student.Age.HasValue
sortBy student.Age.Value
thenBy student.Name
select student
}
`thenByDescending` Performs a subsequent ordering of the elements selected so
far in descending order by the given sorting key. This
operator may only be used after a `sortBy`,
`sortByDescending`, `thenBy`, or `thenByDescending`.
query {
for student in db.Student do
where student.Age.HasValue
sortBy student.Age.Value
thenByDescending student.Name
select student
}
`groupValBy` Selects a value for each element selected so far and groups
the elements by the given key.
query {
for student in db.Student do
groupValBy student.Name student.Age into g
select (g, g.Key, g.Count())
}
query {
for student in db.Student do
join selection in db.CourseSelection
on (student.StudentID =
selection.StudentID)
select (student, selection)
}
query {
for student in db.Student do
groupJoin courseSelection in
db.CourseSelection
on (student.StudentID =
courseSelection.StudentID) into g
for courseSelection in g do
join course in db.Course
on (courseSelection.CourseID =
course.CourseID)
select (student.Name, course.CourseName)
}
`leftOuterJoin` Correlates two sets of selected values based on matching
keys and groups the results. If any group is empty, a group
with a single default value is used instead. Note that the
order of the keys around the = sign in a join expression is
significant.
query {
for student in db.Student do
leftOuterJoin selection in
db.CourseSelection
on (student.StudentID =
selection.StudentID) into result
for selection in result.DefaultIfEmpty() do
select (student, selection)
}
`sumByNullable` Selects a nullable value for each element selected so far and
returns the sum of these values. If any nullable does not
have a value, it is ignored.
query {
for student in db.Student do
sumByNullable student.Age
}
`minByNullable` Selects a nullable value for each element selected so far and
returns the minimum of these values. If any nullable does
not have a value, it is ignored.
query {
for student in db.Student do
minByNullable student.Age
}
`maxByNullable` Selects a nullable value for each element selected so far and
returns the maximum of these values. If any nullable does
not have a value, it is ignored.
query {
for student in db.Student do
maxByNullable student.Age
}
`averageByNullable` Selects a nullable value for each element selected so far and
returns the average of these values. If any nullable does not
have a value, it is ignored.
query {
for student in db.Student do
averageByNullable (Nullable.float
student.Age)
}
`averageBy` Selects a value for each element selected so far and returns
the average of these values.
query {
for student in db.Student do
averageBy (float student.StudentID)
}
query {
for student in db.Student do
join selection in db.CourseSelection
on (student.StudentID =
selection.StudentID)
distinct
}
query {
for student in db.Student do
where
(query {
for courseSelection in
db.CourseSelection do
exists (courseSelection.StudentID =
student.StudentID) })
select student
}
query {
for student in db.Student do
find (student.Name = "Abercrombie, Kim")
}
`all` Determines whether all elements selected so far satisfy a
condition.
query {
for student in db.Student do
all (SqlMethods.Like(student.Name, "%,%"))
}
query {
for student in db.Student do
head
}
query {
for numbers in data do
nth 3
}
query {
for student in db.Student do
skip 1
}
query {
for number in data do
skipWhile (number < 3)="" select=""
student="" }="">
`sumBy` Selects a value for each element selected so far and returns
the sum of these values.
query {
for student in db.Student do
sumBy student.StudentID
}
`take` Selects a specified number of contiguous elements from
those selected so far.
query {
for student in db.Student do
select student
take 2
}
query {
for number in data do
takeWhile (number < 10)="" }="">
query {
for student in db.Student do
sortByNullable student.Age
select student
}
query {
for student in db.Student do
sortByNullableDescending student.Age
select student
}
query {
for student in db.Student do
sortBy student.Name
thenByNullable student.Age
select student
}
`thenByNullableDescending` Performs a subsequent ordering of the elements selected so
far in descending order by the given nullable sorting key.
This operator may only be used immediately after a `sortBy`,
`sortByDescending`, `thenBy`, or `thenByDescending`, or
their nullable variants.
query {
for student in db.Student do
sortBy student.Name
thenByNullableDescending student.Age
select student
}
`EXISTS`
// Find students who have signed up at least
SELECT * FROM Student one course.
WHERE EXISTS query {
(SELECT * FROM CourseSelection for student in db.Student do
WHERE CourseSelection.StudentID = where
Student.StudentID) (query {
for courseSelection in
db.CourseSelection do
exists (courseSelection.StudentID =
student.StudentID) })
select student
}
Grouping
// Group by age and count.
SELECT Student.Age, COUNT( * ) FROM Student query {
GROUP BY Student.Age for n in db.Student do
groupBy n.Age into g
select (g.Key, g.Count())
}
// OR
query {
for n in db.Student do
groupValBy n.Age n.Age into g
select (g.Key, g.Count())
}
`DISTINCT`
// Join with distinct.
SELECT DISTINCT StudentID FROM CourseSelection query {
for student in db.Student do
join selection in db.CourseSelection
on (student.StudentID =
selection.StudentID)
distinct
}
Distinct count.
// Join with distinct and count.
SELECT DISTINCT COUNT(StudentID) FROM query {
CourseSelection for n in db.Student do
join e in db.CourseSelection
on (n.StudentID = e.StudentID)
distinct
count
}
`BETWEEN`
// Selecting students with ages between 10 and
SELECT * FROM Student 15.
WHERE Student.Age BETWEEN 10 AND 15 query {
for student in db.Student do
where (student.Age ?>= 10 && student.Age ?<
15)="" select="" student="" }="">
`OR`
// Selecting students with age that's either 11
SELECT * FROM Student or 12.
WHERE Student.Age = 11 OR Student.Age = 12 query {
for student in db.Student do
where (student.Age.Value = 11 ||
student.Age.Value = 12)
select student
}
let query2 =
query {
for n in db.LastStudent do
select (n.Name, n.Age)
}
query2.Union (query1)
let query2 =
query {
for n in db.LastStudent do
select (n.Name, n.Age)
}
query1.Intersect(query2)
`CASE` condition.
// Using if statement to alter results for
SELECT student.StudentID, special value.
CASE Student.Age query {
WHEN -1 THEN 100 for student in db.Student do
ELSE Student.Age select
END, (if student.Age.HasValue &&
Student.Age student.Age.Value = -1 then
FROM Student (student.StudentID,
System.Nullable(100), student.Age)
else (student.StudentID, student.Age,
student.Age))
}
Multiple cases.
// Using if statement to alter results for
SELECT Student.StudentID, special values.
CASE Student.Age query {
WHEN -1 THEN 100 for student in db.Student do
WHEN 0 THEN 1000 select
ELSE Student.Age (if student.Age.HasValue &&
END, student.Age.Value = -1 then
Student.Age (student.StudentID,
FROM Student System.Nullable(100), student.Age)
elif student.Age.HasValue &&
student.Age.Value = 0 then
(student.StudentID,
System.Nullable(1000), student.Age)
else (student.StudentID, student.Age,
student.Age))
}
Multiple tables.
// Multiple table select.
SELECT * FROM Student, Course query {
for student in db.Student do
for course in db.Course do
select (student, course)
}
Multiple joins.
// Multiple joins.
SELECT Student.Name, Course.CourseName query {
FROM Student for student in db.Student do
JOIN CourseSelection join courseSelection in db.CourseSelection
ON CourseSelection.StudentID = on (student.StudentID =
Student.StudentID courseSelection.StudentID)
JOIN Course join course in db.Course
ON Course.CourseID = CourseSelection.CourseID on (courseSelection.CourseID =
course.CourseID)
select (student.Name, course.CourseName)
}
The following code can be used to create the sample database for these examples.
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
USE [master];
GO
USE MyDatabase;
USE MyDatabase;
GO
The following code contains the sample code that appears in this topic.
#if INTERACTIVE
#r "FSharp.Data.TypeProviders.dll"
#r "System.Data.dll"
#r "System.Data.Linq.dll"
#endif
open System
open Microsoft.FSharp.Data.TypeProviders
open System.Data.Linq.SqlClient
open System.Linq
let db = schema.GetDataContext()
type Nullable<'T when 'T : ( new : unit -> 'T) and 'T : struct and 'T :> ValueType > with
member this.Print() =
if this.HasValue then this.Value.ToString()
else "NULL"
open Microsoft.FSharp.Linq
printfn "\nExists."
query {
for student in db.Student do
where
(query {
for courseSelection in db.CourseSelection do
exists (courseSelection.StudentID = student.StudentID) })
select student
}
|> Seq.iter (fun student -> printfn "%A" student.Name)
printfn "\nGroup students by age and print counts of number of students at each age with more than 1
student."
query {
for student in db.Student do
groupBy student.Age into group
where (group.Count() > 1)
select (group.Key, group.Count())
}
|> Seq.iter (fun (age, ageCount) ->
printfn "Age: %s Count: %d" (age.Print()) ageCount)
printfn "\nGroup students by age and count number of students at each age, and display all with count > 1 in
descending order of count."
query {
for student in db.Student do
groupBy student.Age into g
where (g.Count() > 1)
sortByDescending (g.Count())
select (g.Key, g.Count())
}
|> Seq.iter (fun (age, myCount) ->
printfn "Age: %s" (age.Print())
printfn "Count: %d" myCount)
printfn "\nLook for students with Name match _e%% pattern and take first two."
query {
for student in db.Student do
where (SqlMethods.Like( student.Name, "_e%") )
select student
take 2
}
|> Seq.iter (fun student -> printfn "%s" student.Name)
printfn "\nLook for students with name matching [^abc]%% pattern and select ID."
query {
for n in db.Student do
where (SqlMethods.Like( n.Name, "[^abc]%") )
select n.StudentID
}
|> Seq.iter (fun id -> printfn "%d" id)
printfn "\n Selecting students with certain ages, taking account of possibility of nulls."
query {
for student in db.Student do
where
((student.Age.HasValue && student.Age.Value = 11) ||
(student.Age.HasValue && student.Age.Value = 12))
sortByDescending student.Name
select student.Name
take 2
}
|> Seq.iter (fun name -> printfn "%s" name)
query2.Union (query1)
|> Seq.iter (fun (name, age) -> printfn "%s %s" name (age.Print()))
query1.Intersect(query2)
|> Seq.iter (fun (name, age) -> printfn "%s %s" name (age.Print()))
And here is the full output when this code is run in F# Interactive.
minByNullable
Minimum age: 10
maxByNullable
Maximum age: 14
averageBy
Average student ID: 4.500000
averageByNullable
Average age: 12
Count of students:
Student count: 8
Exists.
"Abercrombie, Kim"
"Abolrous, Hazen"
"Hance, Jim"
"Adams, Terry"
"Hansen, Claus"
"Perham, Tom"
Group students by age and print counts of number of students at each age with more than 1 student.
Age: 12 Count: 3
Group students by age and count number of students at each age, and display all with count > 1 in descending
order of count.
Age: 12
Count: 3
Look for students with Name match _e% pattern and take first two.
Penor, Lori
Perham, Tom
Look for students with name matching [^abc]% pattern and select ID.
3
5
6
7
8
Multiple Joins
Abercrombie, Kim Trigonometry
Abercrombie, Kim Algebra II
Abercrombie, Kim English
Abolrous, Hazen Trigonometry
Abolrous, Hazen English
Abolrous, Hazen French
Abolrous, Hazen Algebra II
Hance, Jim Trigonometry
Hance, Jim Algebra I
Adams, Terry Trigonometry
Adams, Terry English
Adams, Terry Trigonometry
Hansen, Claus Algebra II
Hansen, Claus Trigonometry
Perham, Tom Algebra II
type schema
val db : schema.ServiceTypes.SimpleDataContextTypes.MyDatabase1
val student : System.Data.Linq.Table<schema.ServiceTypes.Student>
val data : int list = [1; 5; 7; 11; 18; 21]
type Nullable<'T
when 'T : (new : unit -> 'T) and 'T : struct and
'T :> System.ValueType> with
member Print : unit -> string
val num : int = 21
val student2 : schema.ServiceTypes.Student
val student3 : schema.ServiceTypes.Student
val student4 : schema.ServiceTypes.Student
val student5 : int = 1
val student6 : int = 8
val idList : int list = [1; 2; 5; 10]
val idQuery : seq<int>
val names : string [] = [|"a"; "b"; "c"|]
module Queries = begin
val query1 : System.Linq.IQueryable<string * System.Nullable<int>>
val query2 : System.Linq.IQueryable<string * System.Nullable<int>>
end
module Queries2 = begin
val query1 : System.Linq.IQueryable<string * System.Nullable<int>>
val query2 : System.Linq.IQueryable<string * System.Nullable<int>>
end
See Also
F# Language Reference
Linq.QueryBuilder Class
Computation Expressions
Code Quotations
7/29/2017 • 7 min to read • Edit Online
NOTE
The API reference link will take you to MSDN. The docs.microsoft.com API reference is not complete.
This topic describes code quotations, a language feature that enables you to generate and work with F# code
expressions programmatically. This feature lets you generate an abstract syntax tree that represents F# code. The
abstract syntax tree can then be traversed and processed according to the needs of your application. For example,
you can use the tree to generate F# code or generate code in some other language.
Quoted Expressions
A quoted expression is an F# expression in your code that is delimited in such a way that it is not compiled as part
of your program, but instead is compiled into an object that represents an F# expression. You can mark a quoted
expression in one of two ways: either with type information or without type information. If you want to include
type information, you use the symbols <@ and @> to delimit the quoted expression. If you do not need type
information, you use the symbols <@@ and @@> . The following code shows typed and untyped quotations.
open Microsoft.FSharp.Quotations
// A typed code quotation.
let expr : Expr<int> = <@ 1 + 1 @>
// An untyped code quotation.
let expr2 : Expr = <@@ 1 + 1 @@>
Traversing a large expression tree is faster if you do not include type information. The resulting type of an
expression quoted with the typed symbols is Expr<'T> , where the type parameter has the type of the expression
as determined by the F# compiler's type inference algorithm. When you use code quotations without type
information, the type of the quoted expression is the non-generic type Expr. You can call the Raw property on the
typed Expr class to obtain the untyped Expr object.
There are a variety of static methods that allow you to generate F# expression objects programmatically in the
Expr class without using quoted expressions.
Note that a code quotation must include a complete expression. For a let binding, for example, you need both
the definition of the bound name and an additional expression that uses the binding. In verbose syntax, this is an
expression that follows the in keyword. At the top-level in a module, this is just the next expression in the
module, but in a quotation, it is explicitly required.
Therefore, the following expression is not valid.
// Not valid:
// <@ let f x = x + 1 @>
To use code quotations, you must add an import declaration (by using the open keyword) that opens the
Microsoft.FSharp.Quotations namespace.
The F# PowerPack provides support for evaluating and executing F# expression objects.
Expr Type
An instance of the Expr type represents an F# expression. Both the generic and the non-generic Expr types are
documented in the F# library documentation. For more information, see Microsoft.FSharp.Quotations Namespace
and Quotations.Expr Class.
Splicing Operators
Splicing enables you to combine literal code quotations with expressions that you have created programmatically
or from another code quotation. The % and %% operators enable you to add an F# expression object into a code
quotation. You use the % operator to insert a typed expression object into a typed quotation; you use the %%
operator to insert an untyped expression object into an untyped quotation. Both operators are unary prefix
operators. Thus if expr is an untyped expression of type Expr , the following code is valid.
And if expr is a typed quotation of type Expr<int> , the following code is valid.
Example
Description
The following example illustrates the use of code quotations to put F# code into an expression object and then
print the F# code that represents the expression. A function println is defined that contains a recursive function
print that displays an F# expression object (of type Expr ) in a friendly format. There are several active patterns
in the Microsoft.FSharp.Quotations.Patterns and Microsoft.FSharp.Quotations.DerivedPatterns modules that can
be used to analyze expression objects. This example does not include all the possible patterns that might appear
in an F# expression. Any unrecognized pattern triggers a match to the wildcard pattern ( _ ) and is rendered by
using the ToString method, which, on the Expr type, lets you know the active pattern to add to your match
expression.
Code
module Print
open Microsoft.FSharp.Quotations
open Microsoft.FSharp.Quotations.Patterns
open Microsoft.FSharp.Quotations.DerivedPatterns
let a = 2
println exprLambda
println exprCall
println <@@ let f x = x + 10 in f 10 @@>
Output
fun (x:System.Int32) -> x + 1
a + 1
let f = fun (x:System.Int32) -> x + 10 in f 10
Example
Description
You can also use the three active patterns in the ExprShape module to traverse expression trees with fewer active
patterns. These active patterns can be useful when you want to traverse a tree but you do not need all the
information in most of the nodes. When you use these patterns, any F# expression matches one of the following
three patterns: ShapeVar if the expression is a variable, ShapeLambda if the expression is a lambda expression, or
ShapeCombination if the expression is anything else. If you traverse an expression tree by using the active patterns
as in the previous code example, you have to use many more patterns to handle all possible F# expression types,
and your code will be more complex. For more information, see
ExprShape.ShapeVar|ShapeLambda|ShapeCombination Active Pattern.
The following code example can be used as a basis for more complex traversals. In this code, an expression tree is
created for an expression that involves a function call, add . The SpecificCall active pattern is used to detect any
call to add in the expression tree. This active pattern assigns the arguments of the call to the exprList value. In
this case, there are only two, so these are pulled out and the function is called recursively on the arguments. The
results are inserted into a code quotation that represents a call to mul by using the splice operator ( %% ). The
println function from the previous example is used to display the results.
The code in the other active pattern branches just regenerates the same expression tree, so the only change in the
resulting expression is the change from add to mul .
Code
module Module1
open Print
open Microsoft.FSharp.Quotations
open Microsoft.FSharp.Quotations.DerivedPatterns
open Microsoft.FSharp.Quotations.ExprShape
let add x y = x + y
let mul x y = x * y
Output
1 + Module1.add(2,Module1.add(3,4))
1 + Module1.mul(2,Module1.mul(3,4))
See Also
F# Language Reference
The Fixed Keyword
8/3/2017 • 1 min to read • Edit Online
F# 4.1 introduces the fixed keyword, which allows you to "pin" a local onto the stack to prevent it from being
collected or moved during garbage-collection. It is used for low-level programming scenarios.
Syntax
use ptr = fixed expression
Remarks
This extends the syntax of expressions to allow extracting a pointer and binding it to a name which is prevented
from being collected or moved during garbage-collection.
A pointer from an expression is fixed via the fixed keyword is bound to an identifier via the use keyword. The
semantics of this are similar to resource management via the use keyword. The pointer is fixed while it is in scope,
and once it is out of scope, it is no longer fixed. fixed cannot be used outside the context of a use binding. You
must bind the pointer to a name with use .
Use of fixed must occur within an expression in a function or a method. It cannot be used at a script-level or
module-level scope.
Like all pointer code, this is an unsafe feature and will emit a warning when used.
Example
open Microsoft.FSharp.NativeInterop
let pnt = { X = 1; Y = 2 }
printfn "pnt before - X: %d Y: %d" pnt.X pnt.Y // prints 1 and 2
doPointerWork()
See Also
NativePtr Module
Compiler Directives
7/29/2017 • 3 min to read • Edit Online
Preprocessor Directives
A preprocessor directive is prefixed with the # symbol and appears on a line by itself. It is interpreted by the
preprocessor, which runs before the compiler itself.
The following table lists the preprocessor directives that are available in F#.
DIRECTIVE DESCRIPTION
# [line] int, Indicates the original source code line and file name, for
# [line] int string, debugging. This feature is provided for tools that generate F#
# [line] int verbatim-string source code.
The effect of disabling a warning applies to the entire file, including portions of the file that precede the directive.|
NOTE
The behavior of the conditional compilation directives is not the same as it is in other languages. For example, you cannot
use Boolean expressions involving symbols, and true and false have no special meaning. Symbols that you use in the
if directive must be defined by the command line or in the project settings; there is no define preprocessor directive.
The following code illustrates the use of the #if , #else , and #endif directives. In this example, the code contains
two versions of the definition of function1 . When VERSION1 is defined by using the -define compiler option, the
code between the #if directive and the #else directive is activated. Otherwise, the code between #else and
#endif is activated.
#if VERSION1
let function1 x y =
printfn "x: %d y: %d" x y
x + 2 * y
#else
let function1 x y =
printfn "x: %d y: %d" x y
x - 2*y
#endif
There is no #define preprocessor directive in F#. You must use the compiler option or project settings to define
the symbols used by the #if directive.
Conditional compilation directives can be nested. Indentation is not significant for preprocessor directives.
Line Directives
When building, the compiler reports errors in F# code by referencing line numbers on which each error occurs.
These line numbers start at 1 for the first line in a file. However, if you are generating F# source code from another
tool, the line numbers in the generated code are generally not of interest, because the errors in the generated F#
code most likely arise from another source. The #line directive provides a way for authors of tools that generate
F# source code to pass information about the original line numbers and source files to the generated F# code.
When you use the #line directive, file names must be enclosed in quotation marks. Unless the verbatim token (
@ ) appears in front of the string, you must escape backslash characters by using two backslash characters instead
of one in order to use them in the path. The following are valid line tokens. In these examples, assume that the
original file Script1 results in an automatically generated F# code file when it is run through a tool, and that the
code at the location of these directives is generated from some tokens at line 25 in file Script1 .
# 25
#line 25
#line 25 "C:\\Projects\\MyProject\\MyProject\\Script1"
#line 25 @"C:\Projects\MyProject\MyProject\Script1"
# 25 @"C:\Projects\MyProject\MyProject\Script1"
These tokens indicate that the F# code generated at this location is derived from some constructs at or near line
25 in Script1 .
Compiler Directives
Compiler directives resemble preprocessor directives, because they are prefixed with a # sign, but instead of being
interpreted by the preprocessor, they are left for the compiler to interpret and act on.
The following table lists the compiler directive that is available in F#.
DIRECTIVE DESCRIPTION
See Also
F# Language Reference
Compiler Options
Compiler Options
8/16/2017 • 8 min to read • Edit Online
This topic describes compiler command-line options for the F# compiler, fsc.exe. The compilation
environment can also be controlled by setting the project properties.
-d:<string>
--keyfile:<filename> Specifies the name of a public key file for signing the
generated assembly.
--mlcompatibility Ignores warnings that appear when you use features that
are designed for compatibility with other versions of ML.
--platform:<platform-name> Specifies that the generated code will only run on the
specified platform (x86, Itanium, or x64), or, if the
platform-name anycpu is chosen, specifies that the
generated code can run on any platform.
--staticlink:<assembly-name> Statically links the given assembly and all referenced DLLs
that depend on this assembly. Use the assembly name,
not the DLL name.
--target:[exe | winexe | library | module ] <output- Specifies the type and file name of the generated compiled
filename> code.
exe means a console application.
winexe means a Windows application, which differs
from the console application in that it does not
have standard input/output streams (stdin, stdout,
and stderr) defined.
library is an assembly without an entry point.
module is a .NET Framework module (.netmodule),
which can later be combined with other modules
into an assembly.
This compiler option is equivalent to the C# compiler
option of the same name. For more information, see
/target (C# Compiler Options).
Related Topics
TITLE DESCRIPTION
Project Properties Reference Describes the UI for projects, including project property
pages that provide build options.
Source Line, File, and Path Identifiers
7/29/2017 • 1 min to read • Edit Online
The identifiers __LINE__ , __SOURCE_DIRECTORY__ and __SOURCE_FILE__ are built-in values that enable you to access
the source line number, directory and file name in your code.
Syntax
__LINE__
__SOURCE_DIRECTORY__
__SOURCE_FILE__
Remarks
Each of these values has type string .
The following table summarizes the source line, file, and path identifiers that are available in F#. These identifiers
are not preprocessor macros; they are built-in values that are recognized by the compiler.
__SOURCE_FILE__ Evaluates to the current source file name and its path,
considering #line directives.
For more information about the #line directive, see Compiler Directives.
Example
The following code example demonstrates the use of these values.
let printSourceLocation() =
printfn "Line: %s" __LINE__
printfn "Source Directory: %s" __SOURCE_DIRECTORY__
printfn "Source File: %s" __SOURCE_FILE__
printSourceLocation()
Output:
Line: 4
Source Directory: C:\Users\username\Documents\Visual Studio 2017\Projects\SourceInfo\SourceInfo
Source File: C:\Users\username\Documents\Visual Studio 2017\Projects\SourceInfo\SourceInfo\Program.fs
See Also
Compiler Directives
F# Language Reference
Caller information
8/14/2017 • 2 min to read • Edit Online
By using Caller Info attributes, you can obtain information about the caller to a method. You can obtain file path of
the source code, the line number in the source code, and the member name of the caller. This information is helpful
for tracing, debugging, and creating diagnostic tools.
To obtain this information, you use attributes that are applied to optional parameters, each of which has a default
value. The following table lists the Caller Info attributes that are defined in the System.Runtime.CompilerServices
namespace:
Example
The following example shows how you might use these attributes to trace a caller.
open System.Diagnostics
open System.Runtime.CompilerServices
type Tracer() =
member __.DoTrace(msg: string,
[<CallerMemberName>] ?memberName: string,
[<CallerFilePath>] ?path: string
[<CallerLineNumber>] ?line: int) =
Trace.WriteLine(sprintf "Message: %s" message)
match (memberName, path, line) with
| Some m, Some p, Some l ->
Trace.WriteLine(sprintf "Member name: %s" m)
Trace.WriteLine(sprintf "Source file path: %s" p)
Trace.WriteLine(sprintf "Source line number: %d" l)
| _,_,_ -> ()
Remarks
Caller Info attributes can only be applied to optional parameters. You must supply an explicit value for each
optional parameter. The Caller Info attributes cause the compiler to write the proper value for each optional
parameter decorated with a Caller Info attribute.
Caller Info values are emitted as literals into the Intermediate Language (IL) at compile time. Unlike the results of
the StackTrace property for exceptions, the results aren't affected by obfuscation.
You can explicitly supply the optional arguments to control the caller information or to hide caller information.
Member names
You can use the CallerMemberName attribute to avoid specifying the member name as a String argument to the
called method. By using this technique, you avoid the problem that Rename Refactoring doesn't change the
String values. This benefit is especially useful for the following tasks:
Method, property, or event The name of the method, property, or event from which the
call originated.
User-defined operators or conversions The generated name for the member, for example,
"op_Addition".
Attribute constructor The name of the member to which the attribute is applied. If
the attribute is any element within a member (such as a
parameter, a return value, or a generic type parameter), this
result is the name of the member that's associated with that
element.
No containing member (for example, assembly-level or The default value of the optional parameter.
attributes that are applied to types)
See also
Attributes
Named arguments
Optional parameters
Verbose Syntax
7/29/2017 • 2 min to read • Edit Online
There are two forms of syntax available for many constructs in the F# language: verbose syntax and lightweight
syntax. The verbose syntax is not as commonly used, but has the advantage of being less sensitive to indentation.
The lightweight syntax is shorter and uses indentation to signal the beginning and end of constructs, rather than
additional keywords like begin , end , in , and so on. The default syntax is the lightweight syntax. This topic
describes the syntax for F# constructs when lightweight syntax is not enabled. Verbose syntax is always enabled,
so even if you enable lightweight syntax, you can still use verbose syntax for some constructs. You can disable
lightweight syntax by using the #light "off" directive.
Table of Constructs
The following table shows the lightweight and verbose syntax for F# language constructs in contexts where there
is a difference between the two forms. In this table, angle brackets (<>) enclose user-supplied syntax elements.
Refer to the documentation for each language construct for more detailed information about the syntax used
within these constructs.
nested `let` bindings ``` let f x = let a = 1 let b = 2 x + a + b ``` let f x = let a = 1 in let b = 2 in x + a
``` + b ```
`for...do` ``` for counter = start to finish do ... ``` ``` for counter = start to finish do ...
done ```
`while...do` ``` while do ... ``` ``` while do ... done ```
`for...in` ``` for var in start .. finish do ... ``` ``` for var in start .. finish do ... done ```
class ``` type () = ... ``` ``` type () = class ... end ```
structure ``` [] type = ... ``` ``` type = struct ... end ```
discriminated union ``` type = | ... | ... ... ``` ``` type = | ... | ... ... with end ```
interface ``` type = ... ``` ``` type = interface ... end ```
object expression ``` { new with } ``` ``` { new with end } ```
interface implementation ``` interface with ``` ``` interface with end ```
type extension ``` type with ``` ``` type with end ```
module ``` module = ... ``` ``` module = begin ... end ```
See Also
F# Language Reference
Compiler Directives
Code Formatting Guidelines
Code Formatting Guidelines
7/29/2017 • 7 min to read • Edit Online
This topic summarizes code indentation guidelines for F#. Because the F# language is sensitive to line breaks and
indentation, it is not just a readability issue, aesthetic issue, or coding standardization issue to format your code
correctly. You must format your code correctly for it to compile correctly.
Top-level context
When you break long lines, the continuation of the line must be indented farther than the enclosing construct. For
example, function arguments must be indented farther than the first character of the function name, as shown in
the following code.
let myFunction1 a b = a + b
let myFunction2(a, b) = a + b
let someFunction param1 param2 =
let result = myFunction1 param1
param2
result * 100
let someOtherFunction param1 param2 =
let result = myFunction2(param1,
param2)
result * 100
Indentation in Modules
Code in a local module must be indented relative to the module, but code in a top-level module does not have to
be indented. Namespace elements do not have to be indented.
The following code examples illustrate this.
// Program1.fs
// A is a top-level module.
module A
let function1 a b = a - b * b
// Program2.fs
// A1 and A2 are local modules.
module A1 =
let function1 a b = a*a + b*b
module A2 =
let function2 a b = a*a - b*b
let abs1 x =
if (x >= 0)
then
x
else
-x
The exception to the offside rule applies only to the then and else keywords. Therefore, although it is not an
error to indent the then and else further, failing to indent the lines of code in a then block produces a warning.
This is illustrated in the following lines of code.
For code in an else block, an additional special rule applies. The warning in the previous example occurs only on
the code in the then block, not on the code in the else block. This allows you to write code that checks for
various conditions at the beginning of a function without forcing the rest of the code for the function, which might
be in an else block, to be indented. Thus, you can write the following without producing a warning.
let abs4 x =
if (x >= 0) then x else
-x
Another exception to the rule that contexts end when a line is not indented as far as a previous line is for infix
operators, such as + and |> . Lines that start with infix operators are permitted to begin (1 + oplength) columns
before the normal position without triggering an end to the context, where oplength is the number of characters
that make up the operator. This causes the first token after the operator to align with the previous line.
For example, in the following code, the + symbol is permitted to be indented two columns less than the previous
line.
Although indentation usually increases as the level of nesting becomes higher, there are several constructs in
which the compiler allows you to reset the indentation to a lower column position.
The constructs that permit a reset of column position are as follows:
Bodies of anonymous functions. In the following code, the print expression starts at a column position that
is farther to the left than the fun keyword. However, the line must not start at a column to the left of the
start of the previous indentation level (that is, to the left of the L in List ).
See Also
F# Language Reference
Visual Basic Guide
8/31/2017 • 1 min to read • Edit Online
Visual Basic is engineered for productively building type-safe and object-oriented applications. Visual Basic
enables developers to target Windows, Web, and mobile devices. As with all languages targeting the Microsoft
.NET Framework, programs written in Visual Basic benefit from security and language interoperability.
This generation of Visual Basic continues the tradition of giving you a fast and easy way to create .NET
Framework-based applications.
If you don't already have Visual Basic, you can acquire a version of Visual Studio that includes Visual Basic for
free from the Visual Studio site.
In This Section
Getting Started
Helps you begin working by listing what is new and what is available in various editions of the product.
Programming Concepts Presents the language concepts that are most useful to Visual Basic programmers.
Program Structure and Code Conventions
Contains documentation on the basic structure and code conventions of Visual Basic such as naming
conventions, comments in code, and limitations within Visual Basic.
Visual Basic Language Features
Provides links to topics that introduce and discuss important features of Visual Basic, including LINQ and XML
literals.
Visual Basic Reference
Contains the Visual Basic language and compiler information.
Developing Applications with Visual Basic
Discusses various aspects of development in Visual Basic, such as security, exception handling, and using the
.NET Framework class library.
COM Interop
Explains the interoperability issues associated with creating and using component object model (COM) objects
with Visual Basic.
Samples
Contains information about samples.
Walkthroughs
Provides links to step-by-step instructions for common scenarios.
Related Sections
Get Started Developing with Visual Studio
Provides links to topics that help you learn about the basics of Visual Studio.
.NET Framework Class Library
Provides entry to the library of classes, interfaces, and value types that are included in the Microsoft .NET
Framework SDK.
Get started with Visual Basic
8/30/2017 • 1 min to read • Edit Online
This section of the documentation helps you get started with Visual Basic application development.
Additional information
What's new for Visual Basic
Lists new features in each of the versions of Visual Basic .NET.
Visual Basic Breaking Changes in Visual Studio
Lists changes in this release that might prevent an application from compiling or change its run-time behavior.
Additional Resources for Visual Basic Programmers
Provides a list of Web sites and newsgroups that can help you find answers to common problems.
See also
Get Visual Basic
Provides download links for Visual Studio versions that include Visual basic support, including free versions.
Visual Basic Fundamentals for Absolute Beginners
Microsoft Virtual Academy course that teaches the fundamentals of Visual Basic programming.
Object-Oriented Programming
Provides links to pages that introduce object-oriented programming and describe how to create your own objects
and how to use objects to simplify your coding.
Samples
Provides links to sample code in Visual Basic.
Walkthroughs
Provides a list of Help pages that demonstrate aspects of the Visual Basic language.
Talk to Us
Covers how to receive support and give feedback.
Visual Studio
Provides links into the Visual Studio documentation.
C#
Provides links into the documentation on application development with Visual C#.
Visual C++
Provides links into the Visual C++ documentation.
Office and SharePoint Development
Provides information about using Microsoft Office and Visual Studio as part of a business application.
What's new for Visual Basic
7/29/2017 • 7 min to read • Edit Online
This topic lists key feature names for each version of Visual Basic, with detailed descriptions of the new and
enhanced features in the lastest version of the language.
Current Version
Visual Basic / Visual Studio .NET 2017
For new features, see Visual Basic 2017
Previous versions
Visual Basic / Visual Studio .NET 2015
For new features, see Visual Basic 14
Visual Basic / Visual Studio .NET 2013
Technology previews of the .NET Compiler Platform (“Roslyn”)
Visual Basic / Visual Studio .NET 2012
Async and await keywords, iterators, caller info attributes
You can then call the method and handle the returned tuple with code like the following.
For more information, see the "Literal assignments" section of the Byte, Integer, Long, Short, SByte, UInteger,
ULong, and UShort data types.
Support for C# reference return values
Starting with C# 7, C# supports reference return values. That is, when the calling method receives a value returned
by reference, it can change the value of the reference. Visual Basic does not allow you to author methods with
reference return values, but it does allow you to consume and modify the reference return values.
For example, the following Sentence class written in C# includes a FindNext method that finds the next word in a
sentence that begins with a specified substring. The string is returned as a reference return value, and a Boolean
variable passed by reference to the method indicates whether the search was successful. This means that the caller
can not only read the returned value; he or she can also modify it, and that modification is reflected in the
Sentence class.
using System;
return stringToReturn.Trim();
}
}
In its simplest form, you can modify the word found in the sentence by using code like the following. Note that you
are not assigning a value to the method, but rather to the expression that the method returns, which is the
reference return value.
A problem with this code, though, is that if a match is not found, the method returns the first word. Since the
example does not examine the value of the Boolean argument to determine whether a match is found, it modifies
the first word if there is no match. The following example corrects this by replacing the first word with itself if there
is no match.
Module Example
Public Sub Main()
Dim sentence As New Sentence("A time to see the world is now.")
Dim found = False
Dim returns = RefHelper(sentence.FindNext("A", found), "A good", found)
Console.WriteLine(sentence.GetSentence())
End Sub
Visual Basic 14
Nameof
You can get the unqualified string name of a type or member for use in an error message without hard coding a
string. This allows your code to remain correct when refactoring. This feature is also useful for hooking up model-
view-controller MVC links and firing property changed events.
String Interpolation
You can use string interpolation expressions to construct strings. An interpolated string expression looks like a
template string that contains expressions. An interpolated string is easier to understand with respect to arguments
than Composite Formatting.
Null-conditional Member Access and Indexing
You can test for null in a very light syntactic way before performing a member access ( ?. ) or index ( ?[] )
operation. These operators help you write less code to handle null checks, especially for descending into data
structures. If the left operand or object reference is null, the operations returns null.
Multi-line String Literals
String literals can contain newline sequences. You no longer need the old work around of using
<xml><![CDATA[...text with newlines...]]></xml>.Value
Comments
You can put comments after implicit line continuations, inside initializer expressions, and amongst LINQ expression
terms.
Smarter Fully-qualified Name Resolution
Given code such as Threading.Thread.Sleep(1000) , Visual Basic used to look up the namespace "Threading",
discover it was ambiguous between System.Threading and System.Windows.Threading, and then report an error.
Visual Basic now considers both possible namespaces together. If you show the completion list, the Visual Studio
editor lists members from both types in the completion list.
Year-first Date Literals
You can have date literals in yyyy-mm-dd format, #2015-03-17 16:10 PM# .
Readonly Interface Properties
You can implement readonly interface properties using a readwrite property. The interface guarantees minimum
functionality, and it does not stop an implementing class from allowing the property to be set.
TypeOf <expr> IsNot <type>
For more readability of your code, you can now use TypeOf with IsNot .
#Disable Warning <ID> and #Enable Warning <ID>
You can disable and enable specific warnings for regions within a source file.
XML Doc-comment Improvements
When writing doc comments, you get smart editor and build support for validating parameter names, proper
handling of crefs (generics, operators, etc.), colorizing, and refactoring.
Partial Module and Interface Definitions
In addition to classes and structs, you can declare partial modules and interfaces.
#Region Directives inside Method Bodies
You can put #Region…#End Region delimiters anywhere in a file, inside functions, and even spanning across
function bodies.
Overrides Definitions are Implicitly Overloads
If you add the Overrides modifier to a definition, the compiler implicitly adds Overloads so that you can type less
code in common cases.
CObj Allowed in Attributes Arguments
The compiler used to give an error that CObj(…) was not a constant when used in attribute constructions.
Declaring and Consuming Ambiguous Methods from Different Interfaces
Previously the following code yielded errors that prevented you from declaring IMock or from calling GetDetails
(if these had been declared in C#):
Interface ICustomer
Sub GetDetails(x As Integer)
End Interface
Interface ITime
Sub GetDetails(x As String)
End Interface
Now the compiler will use normal overload resolution rules to choose the most appropriate GetDetails to call,
and you can declare interface relationships in Visual Basic like those shown in the sample.
See also
What's New in Visual Studio 2017
Visual Basic Breaking Changes in Visual Studio
7/29/2017 • 1 min to read • Edit Online
For the latest documentation on Visual Studio 2017, see Visual Studio 2017 Documentation.
No changes in Visual Basic in Visual Studio 2015 will prevent an application that was created in Visual Basic in
Visual Studio 2013 from compiling or change the run-time behavior of such an application.
See Also
Arrays
LINQ
Lambda Expressions
For Each...Next Statement
Getting Started
When is a non-breaking language fix breaking?
Additional Resources for Visual Basic Programmers
7/29/2017 • 2 min to read • Edit Online
The following web sites provide guidance and can help you find answers to common problems.
Microsoft Resources
On the Web
TERM DEFINITION
Microsoft Visual Basic Developer Center Provides code samples, upgrade information, videos, free
downloads, and technical content.
Microsoft Visual Basic Team Blog Provides access to the Visual Basic team blog.
Microsoft patterns & practices Provides applied engineering guidance that includes
production quality source code and documentation.
Code Samples
TERM DEFINITION
Code Gallery Download and share sample applications and other resources
with the developer community.
CodePlex Hosts open source software projects. You can use CodePlex to
find open source software or create new projects to share with
the world.
Visual Basic Code Samples Provides application, web, and data samples in Visual Basic.
Forums
TERM DEFINITION
Visual Basic Language Discusses the Visual Basic language syntax and compiler.
Visual Basic Interop and Upgrade Discusses upgrading to Visual Basic and working with
interoperability features.
Visual Basic Power Packs Discusses the add-ins, controls, components, samples and
tools that are part of the Visual Basic Power Packs.
TERM DEFINITION
Visual Basic General Discusses issues with Visual Basic that are not discussed in
other forums.
I'm a VB Watch these interviews and discover what the experts love
about Visual Basic and Visual Studio.
Support
TERM DEFINITION
Microsoft Help and Support Provides access to Knowledge Base (KB) articles, downloads
and updates, support webcasts, and other services.
Third-Party Resources
The MSDN web site provides information on current third-party sites and newsgroups of interest. For the most
current list of resources available, see the MSDN Visual Basic Community Web site.
TERM DEFINITION
DevX Visual Basic Zone Provides in-depth technical articles for today's Visual Basic
developer.
See Also
Getting Started
Talk to Us
Developing Applications with Visual Basic
7/29/2017 • 1 min to read • Edit Online
This section covers conceptual documentation for the Visual Basic language.
In This Section
Programming in Visual Basic
Covers a variety of programming subjects.
Development with My
Discusses a new feature called My , which provides access to information and default object instances that are
related to an application and its run-time environment.
Accessing Data in Visual Basic Applications
Contains Help on accessing data in Visual Basic.
Creating and Using Components in Visual Basic
Defines the term component and discusses how and when to create components.
Printing and Reporting
Provides overviews and links to the relevant documentation related to printing and reporting.
Windows Forms Application Basics
Provides information about creating Windows Forms applications by using Visual Studio.
Customizing Projects and Extending My
Describes how you can customize project templates to provide additional My objects.
Related Sections
Visual Basic Programming Guide
Walks through the essential elements of programming with Visual Basic.
Visual Basic Language Reference
Contains reference documentation for the Visual Basic language.
Programming in Visual Basic
7/29/2017 • 1 min to read • Edit Online
This section discusses programming tasks that you may want to learn more about as you create your Visual Basic
application.
In this section
Accessing Computer Resources
Contains documentation on how to use the My.Computer object to access information about the computer on
which an application runs and how to control the computer.
Logging Information from the Application
Contains documentation on how to log information from your application using the My.Application.Log and
My.Log objects, and how to extend the application's logging capabilities.
See Also
Visual Basic Language Features
Programming Concepts
Collections
Developing Applications with Visual Basic
Accessing computer resources (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
The My.Computer object is one of the three central objects in My , providing access to information and commonly
used functionality. My.Computer provides methods, properties, and events for accessing the computer on which the
application is running. Its objects include:
Audio
Clipboard (ClipboardProxy)
Clock
FileSystem
Info
Keyboard
Mouse
Network
Ports
Registry (RegistryProxy)
In this section
Playing Sounds
Lists tasks associated with My.Computer.Audio , such as playing a sound in the background.
Storing Data to and Reading from the Clipboard
Lists tasks associated with My.Computer.Clipboard , such as reading data from or writing data to the Clipboard.
Getting Information about the Computer
Lists tasks associated with My.Computer.Info , such as determining a computer's full name or IP addresses.
Accessing the Keyboard
Lists tasks associated with My.Computer.Keyboard , such as determining whether CAPS LOCK is on.
Accessing the Mouse
Lists tasks associated with My.Computer.Mouse , such as determining whether a mouse is present.
Performing Network Operations
Lists tasks associated with My.Computer.Network , such as uploading or downloading files.
Accessing the Computer's Ports
Lists tasks associated with My.Computer.Ports , such as showing available serial ports or sending strings to serial
ports.
Reading from and Writing to the Registry
Lists tasks associated with My.Computer.Registry , such as reading data from or writing data to registry keys.
Logging Information from the Application (Visual
Basic)
7/29/2017 • 1 min to read • Edit Online
This section contains topics that cover how to log information from your application using the My.Application.Log
or My.Log object, and how to extend the application's logging capabilities.
The Log object provides methods for writing information to the application's log listeners, and the Log object's
advanced TraceSource property provides detailed configuration information. The Log object is configured by the
application's configuration file.
The My.Log object is available only for ASP.NET applications. For client applications, use My.Application.Log . For
more information, see Log.
Tasks
TO SEE
Write event information to the application's logs. How to: Write Log Messages
Write exception information to the application's logs. How to: Log Exceptions
Write trace information to the application's logs when the How to: Log Messages When the Application Starts or Shuts
application starts and shuts down. Down
Configure My.Application.Log to write information to a How to: Write Event Information to a Text File
text file.
Configure My.Application.Log to write information to an How to: Write to an Application Event Log
event log.
Change where My.Application.Log writes information. Walkthrough: Changing Where My.Application.Log Writes
Information
Determine where My.Application.Log writes information. Walkthrough: Determining Where My.Application.Log Writes
Information
Create a custom log listener for My.Application.Log . Walkthrough: Creating Custom Log Listeners
Filter the output of the My.Application.Log logs. Walkthrough: Filtering My.Application.Log Output
See Also
Microsoft.VisualBasic.Logging.Log
Working with Application Logs
Troubleshooting: Log Listeners
Accessing User Data (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
This section contains topics dealing with the My.User object and tasks that you can accomplish with it.
The My.User object provides access to information about the logged-on user by returning an object that
implements the IPrincipal interface.
Tasks
TO SEE
Get the user's domain name, if the application uses Windows CurrentPrincipal
authentication
See Also
User
Accessing Application Forms (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
The My.Forms object provides an easy way to access an instance of each Windows Form declared in the
application's project. You can also use properties of the My.Application object to access the application's splash
screen and main form, and get a list of the application's open forms.
Tasks
The following table lists examples showing how to access an application's forms.
TO SEE
See Also
OpenForms
SplashScreen
My.Forms Object
Accessing Application Web Services (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
The My.WebServices object provides an instance of each Web service referenced by the current project. Each
instance is instantiated on demand. You can access these Web services through the properties of the
My.WebServices object. The name of the property is the same as the name of the Web service that the property
accesses. Any class that inherits from SoapHttpClientProtocol is a Web service.
Tasks
The following table lists possible ways to access Web services referenced by an application.
TO SEE
Call a Web service asynchronously and handle an event when How to: Call a Web Service Asynchronously
it completes
See Also
My.WebServices Object
How to: Call a Web Service Asynchronously (Visual
Basic)
7/29/2017 • 1 min to read • Edit Online
This example attaches a handler to a Web service's asynchronous handler event, so that it can retrieve the result of
an asynchronous method call. This example used the DemoTemperatureService Web service at
http://www.xmethods.net.
When you reference a Web service in your project in the Visual Studio Integrated Development Environment (IDE),
it is added to the My.WebServices object, and the IDE generates a client proxy class to access a specified Web service
The proxy class allows you to call the Web service methods synchronously, where your application waits for the
function to complete. In addition, the proxy creates additional members to help call the method asynchronously.
For each Web service function, NameOfWebServiceFunction, the proxy creates a NameOfWebServiceFunction
Async subroutine, a NameOfWebServiceFunction Completed event, and a NameOfWebServiceFunction
CompletedEventArgs class. This example demonstrates how to use the asynchronous members to access the
getTemp function of the DemoTemperatureService Web service.
NOTE
This code does not work in Web applications, because ASP.NET does not support the My.WebServices object.
http://www.xmethods.net/sd/2001/DemoTemperatureService.wsdl
NOTE
You cannot use the Handles statement to associate an event handler with the My.WebServices object's events.
3. Add a field to track if the event handler has been added to the getTempCompleted event:
4. Add a method to add the event handler to the getTempCompleted event, if necessary, and to call the
getTempAsynch method:
Sub CallGetTempAsync(ByVal zipCode As Integer)
If Not handlerAttached Then
AddHandler My.WebServices.
TemperatureService.getTempCompleted,
AddressOf Me.TS_getTempCompleted
handlerAttached = True
End If
My.WebServices.TemperatureService.getTempAsync(zipCode)
End Sub
To call the getTemp Web method asynchronously, call the CallGetTempAsync method. When the Web
method finishes, its return value is passed to the getTempCompletedHandler event handler.
See Also
Accessing Application Web Services
My.WebServices Object
Accessing application settings (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
This section contains topics describing the My.Settings object and the tasks it enables you to accomplish.
My.Settings
The properties of the My.Settings object provide access to your application's settings. To add or remove settings,
use the Settings pane of the Project Designer.
The methods of the My.Settings object allow you to save the current user settings or revert the user settings to the
last saved values.
Tasks
The following table lists examples showing how to access an application's forms.
TO SEE
Update the value of a user setting How to: Change User Settings in Visual Basic
Display application and user settings in a property grid How to: Create Property Grids for User Settings in Visual Basic
Save updated user setting values How to: Persist User Settings in Visual Basic
Determine the values of user settings How to: Read Application Settings in Visual Basic
See also
Managing Application Settings (.NET)
My.Settings Object
Processing Drives, Directories, and Files (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
You can use Visual Basic to process drives, folders, and files with the My.Computer.FileSystem object, which provides
better performance and is easier to use than traditional methods such as the FileOpen and Write functions
(although they are still available). The following sections discuss these methods in detail.
In This Section
File Access with Visual Basic
Discusses how to use the My.Computer.FileSystem object to work with files, drives, and folders.
Basics of .NET Framework File I/O and the File System (Visual Basic)
Provides an overview of file I/O concepts in the .NET Framework, including streams, isolated storage, file events, file
attributes, and file access.
Walkthrough: Manipulating Files by Using .NET Framework Methods
Demonstrates how to use the .NET Framework to manipulate files and folders.
Walkthrough: Manipulating Files and Directories in Visual Basic
Demonstrates how to use the My.Computer.FileSystem object to manipulate files and folders.
Related Sections
Program Structure and Code Conventions
Provides guidelines for the physical structure and appearance of programs.
FileSystem
Reference documentation for the My.Computer.FileSystem object and its members.
Development with My (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
Visual Basic provides new features for rapid application development that improve productivity and ease of use
while delivering power. One of these features, called My , provides access to information and default object
instances that are related to the application and its run-time environment. This information is organized in a
format that is discoverable through IntelliSense and logically delineated according to use.
Top-level members of My are exposed as objects. Each object behaves similarly to a namespace or a class with
Shared members, and it exposes a set of related members.
This table shows the top-level My objects and their relationship to each other.
In This Section
Performing Tasks with My.Application, My.Computer, and My.User
Describes the three central My objects, My.Application , My.Computer , and My.User , which provide access to
information and functionality
Default Object Instances Provided by My.Forms and My.WebServices
Describes the My.Forms and My.WebServices objects, which provide access to forms, data sources, and XML Web
services used by your application.
Rapid Application Development with My.Resources and My.Settings
Describes the My.Resources and My.Settings objects, which provide access to an application's resources and
settings.
Overview of the Visual Basic Application Model
Describes the Visual Basic Application Startup/Shutdown model.
How My Depends on Project Type
Gives details on which My features are available in different project types.
See Also
ApplicationBase
Computer
User
My.Forms Object
My.WebServices Object
How My Depends on Project Type
Performing Tasks with My.Application, My.Computer,
and My.User (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
The three central My objects that provide access to information and commonly used functionality are
My.Application (ApplicationBase), My.Computer (Computer), and My.User (User). You can use these objects to
access information that is related to the current application, the computer that the application is installed on, or the
current user of the application, respectively.
' Displays a message box that shows the full command line for the
' application.
Dim args As String = ""
For Each arg As String In My.Application.CommandLineArgs
args &= arg & " "
Next
MsgBox(args)
In addition to retrieving information, the members exposed through these three objects also allow you to execute
methods related to that object. For instance, you can access a variety of methods to manipulate files or update the
registry through My.Computer .
File I/O is significantly easier and faster with My , which includes a variety of methods and properties for
manipulating files, directories, and drives. The TextFieldParser object allows you to read from large structured files
that have delimited or fixed-width fields. This example opens the TextFieldParser``reader and uses it to read from
C:\TestFolder1\test1.txt .
Dim reader =
My.Computer.FileSystem.OpenTextFieldParser("C:\TestFolder1\test1.txt")
reader.TextFieldType = Microsoft.VisualBasic.FileIO.FieldType.Delimited
reader.Delimiters = New String() {","}
Dim currentRow As String()
While Not reader.EndOfData
Try
currentRow = reader.ReadFields()
Dim currentField As String
For Each currentField In currentRow
MsgBox(currentField)
Next
Catch ex As Microsoft.VisualBasic.FileIO.MalformedLineException
MsgBox("Line " & ex.Message &
"is not valid and will be skipped.")
End Try
End While
My.Application allows you to change the culture for your application. The following example demonstrates how
this method can be called.
' Changes the current culture for the application to Jamaican English.
My.Application.ChangeCulture("en-JM")
See Also
ApplicationBase
Computer
User
How My Depends on Project Type
Default Object Instances Provided by My.Forms and
My.WebServices (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
The My.Forms and My.WebServices objects provide access to forms, data sources, and XML Web services used by
your application. They do this by providing collections of default instances of each of these objects.
Default Instances
A default instance is an instance of the class that is provided by the runtime and does not need to be declared and
instantiated using the Dim and New statements. The following example demonstrates how you might have
declared and instantiated an instance of a Form class called Form1 , and how you are now able to get a default
instance of this Form class through My.Forms .
' With My.Forms, you can directly call methods on the default
' instance()
My.Forms.Form1.Show()
The My.Forms object returns a collection of default instances for every Form class that exists in your project.
Similarly, My.WebServices provides a default instance of the proxy class for every Web service that you have
created a reference to in your application.
See Also
My.Forms Object
My.WebServices Object
How My Depends on Project Type
Rapid Application Development with My.Resources
and My.Settings (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
The My.Resources object provides access to the application's resources and allows you to dynamically retrieve
resources for your application.
Retrieving Resources
A number of resources such as audio files, icons, images, and strings can be retrieved through the My.Resources
object. For example, you can access the application's culture-specific resource files. The following example sets the
icon of the form to the icon named Form1Icon stored in the application's resource file.
Sub SetFormIcon()
Me.Icon = My.Resources.Form1Icon
End Sub
The My.Resources object exposes only global resources. It does not provide access to resource files associated with
forms. You must access the form resources from the form. For more information, see Walkthrough: Localizing
Windows Forms.
Similarly, the My.Settings object provides access to the application's settings and allows you to dynamically store
and retrieve property settings and other information for your application. For more information, see My.Resources
Object and My.Settings Object.
See Also
My.Resources Object
My.Settings Object
Accessing Application Settings
Overview of the Visual Basic Application Model
7/29/2017 • 3 min to read • Edit Online
Visual Basic provides a well-defined model for controlling the behavior of Windows Forms applications: the Visual
Basic Application model. This model includes events for handling the application's startup and shutdown, as well as
events for catching unhandled exceptions. It also provides support for developing single-instance applications. The
application model is extensible, so developers that need more control can customize its overridable methods.
By handling the StartupNextInstance event, you can control how your single-instance application behaves. For
example, Microsoft Outlook typically runs as a single-instance application; when Outlook is running and you
attempt to start Outlook again, focus shifts to the original instance but another instance does not open.
Availability
By default, the Visual Basic Application model is available for Windows Forms projects. If you configure the
application to use a different startup object, or start the application code with a custom Sub Main , then that object
or class may need to provide an implementation of the WindowsFormsApplicationBase class to use the application
model. For information about changing the startup object, see Application Page, Project Designer (Visual Basic).
See Also
WindowsFormsApplicationBase
Startup
StartupNextInstance
UnhandledException
Shutdown
NetworkAvailabilityChanged
WindowsFormsApplicationBase
Extending the Visual Basic Application Model
How My Depends on Project Type (Visual Basic)
7/29/2017 • 2 min to read • Edit Online
My exposes only those objects required by a particular project type. For example, the My.Forms object is available
in a Windows Forms application but not available in a console application. This topic describes which My objects
are available in different project types.
In a Web site project, My exposes objects that are relevant to a Web developer (such as the My.Request and
My.Response objects) while suppressing objects that are not relevant (such as the My.Forms object). The following
image shows the My object model in a Web site project:
Project Details
The following table shows which My objects are enabled by default for eight project types: Windows application,
class Library, console application, Windows control library, Web control library, Windows service, empty, and Web
site.
There are three versions of the My.Application object, two versions of the My.Computer object, and two versions
of My.User object; details about these versions are given in the footnotes after the table.
Yes 1
My.Application Yes 2 Yes 3 Yes 2 No Yes 3 No No
My.Log No No No No No No No Yes
My.Request No No No No No No No Yes
My.Response No No No No No No No Yes
Yes
My.WebServices Yes Yes Yes Yes Yes No No
1 Windows Forms version of My.Application . Derives from the console version (see Note 3); adds support for
interacting with the application's windows and provides the Visual Basic Application model.
2 Library version of My.Application . Provides the basic functionality needed by an application: provides members
for writing to the application log and accessing application information.
3 Console version of My.Application . Derives from the library version (see Note 2), and adds additional members
for accessing the application's command-line arguments and ClickOnce deployment information.
4 Windows version of My.Computer . Derives from the Server version (see Note 5), and provides access to useful
objects on a client machine, such as the keyboard, screen, and mouse.
5 Server version of My.Computer . Provides basic information about the computer, such as the name, access to the
clock, and so on.
6 Windows version of My.User . This object is associated with the thread's current identity.
7 Web version of My.User . This object is associated with the user identity of the application's current HTTP request.
See Also
ApplicationBase
Computer
Log
User
Customizing Which Objects are Available in My
Conditional Compilation
/define (Visual Basic)
My.Forms Object
My.Request Object
My.Response Object
My.WebServices Object
Accessing data in Visual Basic applications
7/29/2017 • 1 min to read • Edit Online
Visual Basic includes several new features to assist in developing applications that access data. Data-bound forms
for Windows applications are created by dragging items from the Data Sources Window onto the form. You bind
controls to data by dragging items from the Data Sources Window onto existing controls.
Related sections
Accessing Data in Visual Studio
Provides links to pages that discuss incorporating data access functionality into your applications.
Visual Studio data tools for .NET
Provides links to pages on creating applications that work with data, using Visual Studio.
LINQ
Provides links to topics that describe how to use LINQ with Visual Basic.
LINQ to SQL
Provides information about LINQ to SQL. Includes programming examples.
LINQ to SQL Tools in Visual Studio
Provides links to topics about how to create a LINQ to SQL object model in applications.
Work with datasets in n-tier applications
Provides links to topics about how to create multitiered data applications.
Add new connections
Provides links to pages on connecting your application to data with design-time tools and ADO.NET connection
objects, using Visual Studio.
Dataset Tools in Visual Studio
Provides links to pages describing how to load data into datasets and how to execute SQL statements and stored
procedures.
Bind controls to data in Visual Studio
Provides links to pages that explain how to display data on Windows Forms through data-bound controls.
Edit Data in Datasets
Provides links to pages describing how to manipulate the data in the data tables of a dataset.
Validate data in datasets
Provides links to pages describing how to add validation to a dataset during column and row changes.
Save data back to the database
Provides links to pages explaining how to send updated data from an application to the database.
ADO.NET
Describes the ADO.NET classes, which expose data-access services to the .NET Framework programmer.
Data in Office Solutions
Contains links to pages that explain how data works in Office solutions, including information about schema-
oriented programming, data caching, and server-side data access.
Creating and Using Components in Visual Basic
7/29/2017 • 2 min to read • Edit Online
Component Classes
The System.ComponentModel namespace provides classes that are used to implement the run-time and design-
time behavior of components and controls. This namespace includes the base classes and interfaces for
implementing attributes and type converters, binding to data sources, and licensing components.
The core component classes are:
Component. A base implementation for the IComponent interface. This class enables object sharing between
applications.
MarshalByValueComponent. A base implementation for the IComponent interface.
Container. The base implementation for the IContainer interface. This class encapsulates zero or more
components.
Some of the classes used for component licensing are:
License. The abstract base class for all licenses. A license is granted to a specific instance of a component.
LicenseManager. Provides properties and methods to add a license to a component and to manage a
LicenseProvider.
LicenseProvider. The abstract base class for implementing a license provider.
LicenseProviderAttribute. Specifies the LicenseProvider class to use with a class.
Classes commonly used for describing and persisting components.
TypeDescriptor. Provides information about the characteristics for a component, such as its attributes,
properties, and events.
EventDescriptor. Provides information about an event.
PropertyDescriptor. Provides information about a property.
Related Sections
Class vs. Component vs. Control
Defines component and control, and discusses the differences between them and classes.
Component Authoring
Roadmap for getting started with components.
Component Authoring Walkthroughs
Links to topics that provide step-by-step instruction for component programming.
Component Classes
Describes what makes a class a component, ways to expose component functionality, controlling access to
components, and controlling how component instances are created.
Troubleshooting Control and Component Authoring
Explains how to fix common problems.
See Also
How to: Access Design-Time Support in Windows Forms
How to: Extend the Appearance and Behavior of Controls in Design Mode
How to: Perform Custom Initialization for Controls in Design Mode
Printing and Reporting (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
Visual Basic offers several options for printing and reporting. The following topics provide overviews and links to
the relevant documentation related to printing and reporting.
In This Section
PrintForm Component
Provides an overview of the PrintForm component that enables printing the contents of a form.
How to: Print a Scrollable Form
Explains how to print a scrollable form by using the PrintForm component.
How to: Print Client and Non-Client Areas of a Form
Explains how to print both the client and non-client areas of a form by using the PrintForm component.
How to: Print the Client Area of a Form
Explains how to print the client area of a form by using the PrintForm component.
How to: Print a Form by Using the PrintForm Component
Explains how to print a basic form by using the PrintForm component.
Deploying Applications That Reference the PrintForm Component
Discusses how to deploy the PrintForm component together with an application.
Adding Printable Reports to Visual Studio Applications
Discusses options available for writing reports.
PrintForm Component (Visual Basic)
7/29/2017 • 3 min to read • Edit Online
The PrintForm component for Visual Basic enables you to print an image of a Windows Form at run time. Its
behavior replaces that of the PrintForm method in earlier versions of Visual Basic.
The PowerPack controls are no longer included in Visual Studio, but you can download them from the Download
Center.
The PrintOption parameter of the overloaded method determines the underlying implementation used to
print the form, whether the form's title bar, scroll bars, and border are printed, and whether scrollable parts
of the form are printed.
The PrintAction property is a key property of the PrintForm component. This property determines whether the
output is sent to a printer, displayed in a print preview window, or saved as an Encapsulated PostScript file. If the
PrintAction property is set to PrintToFile, the PrintFileName property specifies the path and file name.
The PrinterSettings property provides access to an underlying PrinterSettings object that enables you to specify
such settings as the printer to use and the number of copies to print. You can also query the printer's capabilities,
such as color or duplex support. This property does not appear in the Properties window; it can be accessed only
from code.
The Form property is used to specify the form to print when you invoke the PrintForm component
programmatically. If the component is added to a form at design time, that form is the default.
Key events for the PrintForm component include the following:
BeginPrint event. Occurs when the Print method is called and before the first page of the document prints.
EndPrint event. Occurs after the last page is printed.
QueryPageSettings event. Occurs immediately before each page is printed.
Remarks
If a form contains text or graphics drawn by Graphics methods, use the basic Print ( Print() ) method to print it.
Graphics may not render on some operating systems when the overloaded Print method is used.
If the width of a form is wider than the width of the paper in the printer, the right side of the form might be cut off.
When you design forms for printing, make sure that the form fits on standard-sized paper.
Example
The following example shows a common use of the PrintForm component.
See Also
Print
PrintAction
How to: Print a Form by Using the PrintForm Component
How to: Print the Client Area of a Form
How to: Print Client and Non-Client Areas of a Form
How to: Print a Scrollable Form
How to: Print a Scrollable Form (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
The PrintForm component enables you to quickly print an image of a form without using a PrintDocument
component. By default, only the currently visible part of the form is printed; if a user has resized the form at run
time, the image may not print as intended. The following procedure shows how to print the complete client area of
a scrollable form, even if the form has been resized.
The PowerPack controls are no longer included in Visual Studio, but you can download them from the Download
Center.
To print the complete client area of a scrollable form
1. In the Toolbox, click the Visual Basic PowerPacks tab and then drag the PrintForm component onto the
form.
The PrintForm component will be added to the component tray.
2. In the Properties window, set the PrintAction property to PrintToPrinter.
3. Add the following code in the appropriate event handler (for example, in the Click event handler for a
Print Button ).
PrintForm1.Print(Me, PowerPacks.Printing.PrintForm.PrintOption.Scrollable)
NOTE
On some operating systems, text or graphics drawn by Graphics methods may not print correctly. In this case, you
will not be able to print with the Scrollable parameter.
See Also
PrintAction
Print
PrintForm Component
How to: Print the Client Area of a Form
How to: Print Client and Non-Client Areas of a Form
How to: Print Client and Non-Client Areas of a Form
(Visual Basic)
7/29/2017 • 1 min to read • Edit Online
The PrintForm component enables you to quickly print an image of a form exactly as it appears on screen without
using a PrintDocument component. The following procedure shows how to print a form, including both the client
area and the non-client area. The non-client area includes the title bar, borders, and scroll bars.
The PowerPack controls are no longer included in Visual Studio, but you can download them from the Download
Center.
To print both the client and the non-client areas of a form
1. In the Toolbox, click the Visual Basic PowerPacks tab and then drag the PrintForm component onto the
form.
The PrintForm component is added to the component tray.
2. In the Properties window, set the PrintAction property to PrintToPrinter.
3. Add the following code in the appropriate event handler (for example, in the Click event handler for a
Print Button ).
PrintForm1.Print(Me, PowerPacks.Printing.PrintForm.PrintOption.FullWindow)
NOTE
On some operating systems, text or graphics drawn by Graphics methods may not print correctly. In this case, use
the compatible printing method:
PrintForm1.Print(Me, PowerPacks.Printing.PrintForm.PrintOption.CompatibleModeFullWindow ).
See Also
PrintAction
Print
PrintForm Component
How to: Print a Scrollable Form
How to: Print the Client Area of a Form (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
The PrintForm component enables you to quickly print an image of a form without using a PrintDocument
component. The following procedure shows how to print just the client area of a form, without the title bar,
borders, and scroll bars.
The PowerPack controls are no longer included in Visual Studio, but you can download them from the Download
Center.
To print the client area of a form
1. In the Toolbox, click the Visual Basic PowerPacks tab and then drag the PrintForm component onto the
form.
The PrintForm component is added to the component tray.
2. In the Properties window, set the PrintAction property to PrintToPrinter.
3. Add the following code in the appropriate event handler (for example, in the Click event handler for a
Print Button ).
PrintForm1.Print(Me, PowerPacks.Printing.PrintForm.PrintOption.ClientAreaOnly)
NOTE
On some operating systems, text or graphics drawn by Graphics methods may not print correctly. In this case, use
the compatible printing method:
PrintForm1.Print(Me, PowerPacks.Printing.PrintForm.PrintOption CompatibleModeClientAreaOnly).
See Also
PrintAction
Print
PrintForm Component
How to: Print Client and Non-Client Areas of a Form
How to: Print a Scrollable Form
How to: Print a Form by Using the PrintForm
Component (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
The PrintForm component enables you to quickly print an image of a form exactly as it appears on screen without
using a PrintDocument component. The following procedures show how to print a form to a printer, to a print
preview window, and to an Encapsulated PostScript file.
The PowerPack controls are no longer included in Visual Studio, but you can download them from the Download
Center.
To print a form to the default printer
1. In the Toolbox, click the Visual Basic PowerPacks tab and then drag the PrintForm component onto the
form.
The PrintForm component is added to the component tray.
2. In the Properties window, set the PrintAction property to PrintToPrinter.
3. Add the following code in the appropriate event handler (for example, in the Click event handler for a
Print Button ).
PrintForm1.Print()
PrintForm1.Print()
See Also
PrintAction
PrintFileName
How to: Print the Client Area of a Form
How to: Print Client and Non-Client Areas of a Form
How to: Print a Scrollable Form
PrintForm Component
Deploying applications that reference the PrintForm
component (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
If you want to deploy an application that references the PrintForm component, the component must be installed on
the destination computer.
The PowerPack controls are no longer included in Visual Studio, but you can download them from the Download
Center.
NOTE
To install bootstrapped components, the user might need administrative or similar user permissions on the computer. For
ClickOnce applications, this means that the user will need administrative permissions to install the application, regardless of
the security level specified by the application. After the application is installed, the user can run the application without
administrative permissions.
During installation, users will be prompted to install the PrintForm component if it is not present on the destination
computer.
As an alternative to bootstrapping, you can pre-deploy the PrintForm component by using an electronic software
distribution system like Microsoft Systems Management Server.
See also
How to: Install Prerequisites with a ClickOnce Application
PrintForm Component
Adding Printable Reports to Visual Studio
Applications
7/29/2017 • 6 min to read • Edit Online
Visual Studio supports a variety of reporting solutions to help you add rich data reporting to your Visual Basic
applications. You can create and add reports using ReportViewer controls, Crystal Reports, or SQL Server Reporting
Services.
NOTE
SQL Server Reporting Services is part of SQL Server 2005 rather than Visual Studio. Reporting Services not installed on your
system unless you have installed SQL Server 2005.
1. Drag a ReportViewer control from the Data tab of the Toolbox onto your form.
2. On the Project menu, choose Add New Item. In the Add New Item dialog box, select the Report icon and click Add.
The Report Designer opens in the development environment, and a report (.rdlc) file is added to the project.
3. Drag report items from the Toolbox on the report layout and arrange them as you want.
4. Drag fields from the Data Sources window to the report items in the report layout.
The Business Intelligence Development Studio adds project templates that are specific to SQL Server components.
To create reports, you can choose from the Report Server Project or Report Server Project Wizard templates.
You can specify data source connections and queries to a variety of data source types, including SQL Server, Oracle,
Analysis Services, XML, and SQL Server Integration Services. A Data tab, Layout tab, and Preview tab allow you to
define data, create a report layout, and preview the report all in the same workspace.
Report definitions that you build for the control or the report server can be reused in either technology.
An important part of Visual Basic is the ability to create Windows Forms applications that run locally on users'
computers. You can use Visual Studio to create the application and user interface using Windows Forms. A
Windows Forms application is built on classes from the System.Windows.Forms namespace.
TO SEE
Create a new Windows Forms application with Visual Studio Walkthrough: Creating a Simple Windows Form
Create custom controls How to: Inherit from the UserControl Class
TO SEE
Use the BindingSource component How to: Bind Windows Forms Controls with the BindingSource
Component Using the Designer
Work with ADO.NET data sources How to: Sort and Filter ADO.NET Data with the Windows
Forms BindingSource Component
Use the Data Sources window Walkthrough: Displaying Data on a Windows Form
Deploying Applications to Client Computers
Once you have written your application, you must send it to your users so that they can install and run it on their
own client computers. Using the ClickOnce technology, you can deploy your applications from within Visual Studio
by using just a few clicks and provide users with a URL pointing to your application on the Web. ClickOnce
manages all of the elements and dependencies in your application and ensures that the application is properly
installed on the client computer.
ClickOnce applications can be configured to run only when the user is connected to the network, or to run both
online and offline. When you specify that an application should support offline operation, ClickOnce adds a link to
your application in the user's Start menu, so that the user can open it without using the URL.
When you update your application, you publish a new deployment manifest and a new copy of your application to
your Web server. ClickOnce detects that there is an update available and upgrades the user's installation; no
custom programming is required to update old assemblies.
For a full introduction to ClickOnce, see ClickOnce Security and Deployment. For step-by-step information about
using these features, see the following Help topics:
TO SEE
Deploy an application with ClickOnce How to: Publish a ClickOnce Application using the Publish
Wizard
Update a ClickOnce deployment How to: Manage Updates for a ClickOnce Application
Manage security with ClickOnce How to: Enable ClickOnce Security Settings
TO SEE
Print the contents of a form How to: Print Graphics in Windows Forms
Learn more about Windows Forms security Security in Windows Forms Overview
See Also
WindowsFormsApplicationBase
Windows Forms Overview
My.Forms Object
Visual Basic Power Packs Controls
7/29/2017 • 1 min to read • Edit Online
Visual Basic Power Packs controls are additional Windows Forms controls. They are not included in Visual Studio.
You can download them, but they are provided as-is, without support.
In This Section
Line and Shape Controls
Introduces the Line and Shape controls and provides links to more information.
DataRepeater Control
Introduces the DataRepeater control and provides links to additional information.
Reference
Microsoft.VisualBasic.PowerPacks
DataRepeater Control (Visual Studio)
7/29/2017 • 1 min to read • Edit Online
The Visual Basic Power Packs DataRepeater control is a scrollable container for controls that display repeated data,
for example, rows in a database table. It can be used as an alternative to the DataGridView control when you need
more control over the layout of the data.
The PowerPack controls are no longer included in Visual Studio, but you can download them from the Download
Center.
In This Section
Introduction to the DataRepeater Control
Introduces and discusses the DataRepeater control.
How to: Display Bound Data in a DataRepeater Control
Demonstrates how to use the DataRepeater control to display data from a data source.
How to: Display Unbound Controls in a DataRepeater Control
Demonstrates how to use the DataRepeater control to display additional data.
How to: Change the Layout of a DataRepeater Control
Demonstrates how to change the orientation of a DataRepeater control.
How to: Change the Appearance of a DataRepeater Control
Demonstrates how to customize a DataRepeater control at design time and at run time.
How to: Display Item Headers in a DataRepeater Control
Demonstrates how to control the selection indicators on a DataRepeater control.
How to: Disable Adding and Deleting DataRepeater Items
Demonstrates how to prevent users from adding or deleting items in a DataRepeater control.
How to: Search Data in a DataRepeater Control
Demonstrates how to implement search capabilities in a DataRepeater control.
How to: Create a Master/Detail Form by Using Two DataRepeater Controls (Visual Studio)
Demonstrates how to display related records by using two DataRepeater controls.
Walkthrough: Displaying Data in a DataRepeater Control
Provides a start-to-finish demonstration of how to use a DataRepeater control.
Troubleshooting the DataRepeater Control
Describes potential problems and their solutions.
Reference
Microsoft.VisualBasic.PowerPacks
DataRepeater
Related Sections
Virtual Mode in the DataRepeater Control
Introduction to the DataRepeater Control (Visual
Studio)
7/29/2017 • 3 min to read • Edit Online
The Visual Basic Power Packs DataRepeater control is a scrollable container for controls that display repeated
data, for example, rows in a database table. It can be used as an alternative to the DataGridView control when you
need more control over the layout of the data. The DataRepeater "repeats" a group of related controls by creating
multiple instances in a scrolling view. This enables users to view several records at the same time.
Overview
At design time, the DataRepeater control consists of two sections. The outer section is the viewport, where the
scrolling data will be displayed at run time. The inner (top) section, known as the item template, is where you
position controls that will be repeated at run time, typically one control for each field in the data source. The
properties and controls in the item template are encapsulated in the ItemTemplate property.
At run time, the ItemTemplate is copied to a virtual DataRepeaterItem object that is used to display the data when
each record is scrolled into view. You can customize the display of individual records in the DrawItem event, for
example, highlighting a field based on the value that it contains. For more information, see How to: Change the
Appearance of a DataRepeater Control.
The most common use for a DataRepeater control is to display data from a database table or other bound data
source. In addition to ADO.NET data objects, the DataRepeater control can bind to any class that implements the
IList interface (including arrays), any class that implements the IListSource interface, any class that implements the
IBindingList interface, or any class that implements the IBindingListView interface.
Data Binding
Typically, you accomplish data binding by dragging fields from the Data Sources window onto the DataRepeater
control. For more information, see How to: Display Bound Data in a DataRepeater Control.
When working with large amounts of data, you can set the VirtualMode property to True to display a subset of
the available data. Virtual mode requires the implementation of a data cache from which the DataRepeater is
populated, and you must control all interactions with the data cache at run time. For more information, see Virtual
Mode in the DataRepeater Control.
You can also display unbound controls on a DataRepeater control. For example, you can display an image that is
repeated on each item. For more information, see How to: Display Unbound Controls in a DataRepeater Control.
Events
The most important events for the DataRepeater control are the DrawItem event, which is raised when new items
are scrolled into view, and the CurrentItemIndexChanged event, which is raised when an item is selected. You can
use the DrawItem event to change the appearance of the item. For example, you can highlight negative values.
Use the CurrentItemIndexChanged event to access the values of controls when an item is selected.
The DataRepeater control exposes all the standard control events in the Code Editor. However, some of the events
should not be used. Keyboard and mouse events such as KeyDown , Click , and MouseDown will not be raised at
run time because the DataRepeater control itself never has focus.
The DataRepeaterItem does not expose events at design time because it is created only at run time. If you want to
handle keyboard and mouse events, you can add a Panel control to the ItemTemplate at design time and then
handle the events for the Panel. For more information, see Troubleshooting the DataRepeater Control.
Customizations
There are many ways to customize the appearance and behavior of the DataRepeater control, both at run time
and at design time. Properties can be set to change colors, hide or modify the item headers, change the
orientation from vertical to horizontal, and much more. For more information, see How to: Change the
Appearance of a DataRepeater Control, How to: Display Item Headers in a DataRepeater Control, and How to:
Change the Layout of a DataRepeater Control.
Note that some properties apply to the DataRepeater control itself whereas others apply only to the
ItemTemplate. Make sure that you have the correct section of the control selected before you set properties. For
more information, see How to: Change the Appearance of a DataRepeater Control.
Other customizations include controlling the ability to add or delete records, adding search capabilities, and
displaying related data in a master and detail format. For more information, see How to: Disable Adding and
Deleting DataRepeater Items, How to: Search Data in a DataRepeater Control, and How to: Create a Master/Detail
Form by Using Two DataRepeater Controls (Visual Studio).
See Also
DataRepeater Control
Walkthrough: Displaying Data in a DataRepeater Control
Troubleshooting the DataRepeater Control
Virtual Mode in the DataRepeater Control (Visual
Studio)
7/29/2017 • 4 min to read • Edit Online
When you want to display large quantities of tabular data in a DataRepeater control, you can improve performance
by setting the VirtualMode property to True and explicitly managing the control's interaction with its data source.
The DataRepeater control provides several events that you can handle to interact with your data source and display
the data as needed at run time.
4. Implement a handler for the ItemValuePushed event to store the data. This event is raised when the user
commits changes to a child control of the DataRepeaterItem. The code will resemble the following example,
which is for a data source named Employees .
5. Implement a handler for each child control's KeyDown event and monitor the ESC key. Call the CancelEdit
method to prevent the ItemValuePushed event from being raised. The code will resemble the following
example.
6. Implement a handler for the NewItemNeeded event. This event is raised when the user adds a new item to
the DataRepeater control. The code will resemble the following example, which is for a data source named
Employees .
Employees.RemoveAt(e.ItemIndex)
End Sub
8. For control-level validation, optionally implement handlers for the Validating events of the child controls.
The code will resemble the following example.
See Also
ItemValuePushed
NewItemNeeded
ItemValueNeeded
Introduction to the DataRepeater Control
How to: Display Bound Data in a DataRepeater
Control (Visual Studio)
7/29/2017 • 2 min to read • Edit Online
The most common use of the DataRepeater control is to display bound data from a database or other data source.
In addition to bound controls, you may want to add other controls, such as a static label or an image that is
repeated on each item in the DataRepeater control. For more information, see How to: Display Unbound Controls
in a DataRepeater Control.
You can also bind to a data source at run time by setting the VirtualMode property to True and assigning a data
source to the DataSource property. In this case, you will need to manage all interaction with the data source. For
more information, see Virtual Mode in the DataRepeater Control.
NOTE
Your computer might show different names or locations for some of the Visual Studio user interface elements in the
following instructions. The Visual Studio edition that you have and the settings that you use determine these elements. For
more information, see Personalizing the IDE.
NOTE
If the Data Sources window is empty, add a data source to it. For more information, see Add new data sources.
4. In the Data Sources window, select the top-level node for the table that contains the data that you want to
bind.
5. Change the drop type of the table to Details by clicking Details in the drop-down list on the table node.
6. Select the table node and drag it onto the item template region of the DataRepeater control.
You can specify which types of controls are displayed for each field. For more information, see Set the
control to be created when dragging from the Data Sources window.
See Also
DataRepeater
Introduction to the DataRepeater Control
How to: Display Unbound Controls in a DataRepeater Control
How to: Create a Master/Detail Form by Using Two DataRepeater Controls (Visual Studio)
How to: Change the Appearance of a DataRepeater Control
Troubleshooting the DataRepeater Control
How to: Display Unbound Controls in a
DataRepeater Control (Visual Studio)
7/29/2017 • 1 min to read • Edit Online
In addition to bound controls, you may want to add other controls to a DataRepeater, such as a static label or an
image that is repeated on each item in the DataRepeater control.
NOTE
You must also have at least one bound control on the DataRepeater or nothing will be displayed at run time.
See Also
DataRepeater
Introduction to the DataRepeater Control
Troubleshooting the DataRepeater Control
How to: Display Bound Data in a DataRepeater Control
How to: Create a Master/Detail Form by Using Two DataRepeater Controls (Visual Studio)
How to: Change the Appearance of a DataRepeater Control
How to: Change the Layout of a DataRepeater
Control (Visual Studio)
7/29/2017 • 2 min to read • Edit Online
The DataRepeater control can be displayed in either a vertical (items scroll vertically) or horizontal (items scroll
horizontally) orientation. You can change the orientation at design time or at run time by changing the LayoutStyle
property. If you change the LayoutStyle property at run time, you may also want to resize the ItemTemplate and
reposition the child controls.
NOTE
If you reposition controls on the ItemTemplate at run time, you will need to call the BeginResetItemTemplate and
EndResetItemTemplate methods at the beginning and end of the code block that repositions the controls.
NOTE
You must select the outer border of the DataRepeater control by clicking in the lower region of the control, not in
the upper ItemTemplate region.
2. In most cases, you will want to add code similar to that shown in the Example section to resize the
ItemTemplate and rearrange controls to fit the new orientation.
Example
The following example shows how to respond to the LayoutStyleChanged event in an event handler. This example
requires that you have a DataRepeater control named DataRepeater1 on a form and that its ItemTemplate contain
two TextBox controls named TextBox1 and TextBox2 .
See Also
DataRepeater
LayoutStyle
BeginResetItemTemplate
EndResetItemTemplate
Introduction to the DataRepeater Control
Troubleshooting the DataRepeater Control
How to: Change the Appearance of a DataRepeater Control
How to: Change the Appearance of a DataRepeater
Control (Visual Studio)
7/29/2017 • 3 min to read • Edit Online
You can change the appearance of a DataRepeater control at design time by setting properties or at run time by
handling the DrawItem event.
Properties that you set at design time when the item template section of the control is selected will be repeated
for each DataRepeaterItem at run time. Appearance-related properties of the DataRepeater control itself will be
visible at run time only if a part of the container is left uncovered (for example, if the Padding property is set to a
large value).
At run time, appearance-related properties can be set based on conditions. For example, in a scheduling
application, you might change the background color of an item to warn users when an item is past due. In the
DrawItem event handler, if you set a property in a conditional statement such as If…Then , you must also use an
Else clause to specify the appearance when the condition is not met.
Example
Some common customizations for the DataRepeater control include displaying the rows in alternating colors and
changing the color of a field based on a condition. The following example shows how to perform these
customizations. This example assumes that you have a DataRepeater control that is bound to the Products table
in the Northwind database.
e.DataRepeaterItem.Controls(UnitsInStockTextBox.Name).
BackColor = Color.Red
Else
e.DataRepeaterItem.Controls(UnitsInStockTextBox.Name).
BackColor = Color.White
End If
End Sub
private void dataRepeater1_DrawItem(object sender,
Microsoft.VisualBasic.PowerPacks.DataRepeaterItemEventArgs e)
{
// Alternate the back color.
if ((e.DataRepeaterItem.ItemIndex % 2) != 0)
// Apply the secondary back color.
{
e.DataRepeaterItem.BackColor = Color.AliceBlue;
}
else
{
// Apply the default back color.
e.DataRepeaterItem.BackColor = Color.White;
}
// Change the color of out-of-stock items to red.
if (e.DataRepeaterItem.Controls["unitsInStockTextBox"].Text == "0")
{
e.DataRepeaterItem.Controls["unitsInStockTextBox"].BackColor = Color.Red;
}
else
{
e.DataRepeaterItem.Controls["unitsInStockTextBox"].BackColor = Color.White;
}
}
Note that for both of these customizations, you must provide code to set the properties for both sides of the
condition. If you do not specify the Else condition, you will see unexpected results at run time.
See Also
DataRepeater
DrawItem
Introduction to the DataRepeater Control
Troubleshooting the DataRepeater Control
How to: Display Bound Data in a DataRepeater Control
How to: Display Unbound Controls in a DataRepeater Control
How to: Display Item Headers in a DataRepeater Control
How to: Display Item Headers in a DataRepeater
Control (Visual Studio)
7/29/2017 • 2 min to read • Edit Online
The item header in a DataRepeater control provides a visual indicator when a DataRepeaterItem is selected. When
the LayoutStyle property is set to <xref:Microsoft.VisualBasic.PowerPacks.DataRepeaterLayoutStyles.Vertical> (the
default), the item header is displayed to the left of each item. When the LayoutStyle property is set to
<xref:Microsoft.VisualBasic.PowerPacks.DataRepeaterLayoutStyles.Horizontal>, the item header is displayed at the
top of each item.
When it is first selected, the item header is displayed in the color that is specified by the SelectionColor property,
and a white arrow icon is displayed.
NOTE
If you set the SelectionColor to White, the selection symbol will not be visible when the item is first selected.
When a field in the DataRepeaterItem has focus, the color of the item header changes to the ItemTemplate
background color and the arrow icon changes to black. If data is changed, a pencil symbol is displayed in the item
header.
The default width (or height when the LayoutStyle property is set to
<xref:Microsoft.VisualBasic.PowerPacks.DataRepeaterLayoutStyles.Horizontal>) of the item header is 15 pixels.
You can change the width by setting the ItemHeaderSize property.
NOTE
If the ItemHeaderSize property is set to a value that is less than 11, the indicator symbols in the item header will not be
displayed.
You can hide the item headers by setting the ItemHeaderVisible property to False. When ItemHeaderVisible is set
to False, the only indication that an item is selected is a dotted line around the perimeter of the DataRepeaterItem.
NOTE
You can also provide your own selection indicator by monitoring the IsCurrent property of the DataRepeaterItem in the
DrawItem event of the DataRepeater control. For more information, see IsCurrent.
NOTE
You must select the lower region of the control. If you select the item template section, a different set of properties
will appear in the Properties window.
2. In the Properties window, use the SelectionColor property to change the color of the item headers.
NOTE
If you set the SelectionColor to White, the selection symbol will not be visible when the item is first selected.
3. Use the ItemHeaderSize property to change the width (or height) of the item headers.
NOTE
If the ItemHeaderSize property is set to a value that is less than 11, the indicator symbols in the item header will not
be displayed.
NOTE
You must select the lower region of the control. If you select the item template section, a different set of properties
will appear in the Properties window.
See Also
DataRepeater
Introduction to the DataRepeater Control
How to: Change the Appearance of a DataRepeater Control
How to: Change the Layout of a DataRepeater Control
Troubleshooting the DataRepeater Control
How to: Disable Adding and Deleting DataRepeater
Items (Visual Studio)
7/29/2017 • 1 min to read • Edit Online
By default, users can add and delete items in a DataRepeater control. Users can add a new item by pressing
CTRL+N when a DataRepeaterItem has focus or by clicking the AddNewItem button on the BindingNavigator
control. Users can delete an item by pressing DELETE when a DataRepeaterItem has focus or by clicking the
DeleteItem button on the BindingNavigator control.
You can disable adding and/or deleting at design time or at run time.
To disable adding and deleting at design time
1. In the Windows Forms Designer, select the DataRepeater control.
NOTE
You must select the lower section of the control. If you select the item template section, a different set of properties
will be displayed.
if (bindingNavigatorDeleteItem.Enabled == true)
{
bindingNavigatorDeleteItem.Enabled = false;
}
dataRepeater1.AllowUserToAddItems = false;
dataRepeater1.AllowUserToDeleteItems = false;
bindingNavigatorAddNewItem.Enabled = false;
ordersBindingSource.AllowNew = false;
bindingNavigatorDeleteItem.Enabled = false;
DataRepeater1.AllowUserToAddItems = False
DataRepeater1.AllowUserToDeleteItems = False
BindingNavigatorAddNewItem.Enabled = False
ordersBindingSource.AllowNew = False
BindingNavigatorDeleteItem.Enabled = False
if (bindingNavigatorDeleteItem.Enabled == true)
{
bindingNavigatorDeleteItem.Enabled = false;
}
NOTE
This step is necessary because the BindingSource will enable the DeleteItem button every time that the current
record changes.
See Also
DataRepeater
Introduction to the DataRepeater Control
Troubleshooting the DataRepeater Control
How to: Search Data in a DataRepeater Control
(Visual Studio)
7/29/2017 • 1 min to read • Edit Online
When you are using a DataRepeater control that contains many records, you may want to let users search for a
specific record. Rather than searching the data in the control itself, you can implement a search by querying the
underlying BindingSource. If the item is found, you can then use the CurrentItemIndex property to select the item
and scroll it into view.
To implement search
1. Drag a TextBox control from the Toolbox onto the form that contains the DataRepeater control.
2. In the Properties window, change the Name property to SearchTextBox.
3. Drag a Button control from the Toolbox onto the form that contains the DataRepeater control.
4. In the Properties window, change the Name property to SearchButton. Change the Text property to
Search.
5. Double-click the Button control to open the Code Editor, and add the following code to the
SearchButton_Click event handler.
Replace ProductsBindingSource with the name of the BindingSource for your DataRepeater, and replace
ProductID with the name of the field that you want to search.
See Also
DataRepeater
Introduction to the DataRepeater Control
Troubleshooting the DataRepeater Control
How to: Change the Appearance of a DataRepeater Control
How to: Create a Master/Detail Form by Using Two
DataRepeater Controls (Visual Studio)
7/29/2017 • 1 min to read • Edit Online
You can display related data by using two or more DataRepeater controls to create a master/detail form. For
example, you might want to display a list of customers in one DataRepeater, and when the user selects a customer,
display a list of that customer's orders in a second DataRepeater.
You can display related data by dragging detail items that share the same master table node from the Data
Sources window onto a DataRepeater control. For example, if you have a data source that has a Customers table
and a related Orders table, you see both tables as top-level nodes in the tree view in the Data Sources window.
Expand the Customers node so that you can see the columns. Notice that the last column in the list is an
expandable node that represents the Orders table. This node represents the related orders for a customer.
NOTE
Your computer might show different names or locations for some of the Visual Studio user interface elements in the
following instructions. The Visual Studio edition that you have and the settings that you use determine these elements. For
more information, see Personalizing the IDE.
NOTE
If the Data Sources window is empty, add a data source to it. For more information, see Add new data sources.
4. In the Data Sources window, select the top-level node for the master table.
5. Change the drop type of the master table to Details by clicking Details in the drop-down list on the table
node.
6. Drag the master table node onto the item template region of the first DataRepeater control.
7. Expand the master table node and select the detail node for the related table.
8. Change the drop type of the detail table to Details by clicking Details in the drop-down list on the table
node.
9. Select this table node and drag it onto the item template region of the second DataRepeater control.
See Also
DataRepeater
Introduction to the DataRepeater Control
How to: Display Bound Data in a DataRepeater Control
How to: Display Related Data in a Windows Forms Application
How to: Change the Appearance of a DataRepeater Control
Troubleshooting the DataRepeater Control
Walkthrough: Displaying Data in a DataRepeater
Control (Visual Studio)
7/29/2017 • 7 min to read • Edit Online
This walkthrough provides a basic start-to-finish scenario for displaying bound data in a DataRepeater control.
Prerequisite
This walkthrough requires the Northwind sample database.
If you do not have this database on your development computer, you can download it from the Microsoft
Download Center. For instructions, see Downloading Sample Databases.
Overview
The first part of this walkthrough consists of four main tasks:
Creating a solution.
Adding a DataRepeater control.
Adding a data source.
Adding data-bound controls.
NOTE
Your computer might show different names or locations for some of the Visual Studio user interface elements in the
following instructions. The Visual Studio edition that you have and the settings that you use determine these elements. For
more information, see Personalizing the IDE.
NOTE
If a dialog box appears, click Yes to save the file to your project.
6. Click Next on the Save Connection String to the Application Configuration file page.
7. Expand the Tables node on the Choose Your Database Objects page.
8. Select the check boxes next to the Customers and Orders tables, and then click Finish.
NorthwindDataSet is added to your project and the Customers and Orders tables appear in the Data
Sources window.
At this point, you have a working application that will display a repeating list of customers. You can press F5 to run
the application, change the data, and add or delete customer records.
In the next optional steps, you will learn how to customize the DataRepeater control.
6. In the DrawItem event handler, add the following code to change the ForeColor of a label depending on a
condition:
if (e.DataRepeaterItem.Controls[regionTextBox.Name].Text == "")
{
e.DataRepeaterItem.Controls["regionLabel"].ForeColor = Color.Red;
}
else
{
e.DataRepeaterItem.Controls["regionLabel"].ForeColor = Color.Black;
}
dataRepeater1.AllowUserToAddItems = false;
dataRepeater1.AllowUserToDeleteItems = false;
bindingNavigatorAddNewItem.Enabled = false;
customersBindingSource.AllowNew = false;
bindingNavigatorDeleteItem.Enabled = false;
DataRepeater1.AllowUserToAddItems = False
DataRepeater1.AllowUserToDeleteItems = False
BindingNavigatorAddNewItem.Enabled = False
CustomersBindingSource.AllowNew = False
BindingNavigatorDeleteItem.Enabled = False
3. In the Class Name drop-down list, click BindingNavigatorDeleteItem. In the Method Name drop-down
list, click EnabledChanged.
4. Add the following code to the BindingNavigatorDeleteItem_EnabledChanged event handler:
if (bindingNavigatorDeleteItem.Enabled == true)
{
bindingNavigatorDeleteItem.Enabled = false;
}
NOTE
This step is necessary because the BindingSource will enable the DeleteItem button every time that the current
record changes.
5. Press F5 to run the application. Notice that the DeleteItem button is disabled and that you cannot delete
items by pressing the DELETE key.
int foundIndex;
string searchString;
searchString = searchTextBox.Text;
// Search for the string in the CustomerID field.
foundIndex = customersBindingSource.Find("CustomerID", searchString);
if (foundIndex > -1)
{
dataRepeater1.CurrentItemIndex = foundIndex;
}
else
{
MessageBox.Show("Item " + searchString + " not found.");
}
Dim foundIndex As Integer
Dim searchString As String
searchString = SearchTextBox.Text
' Search for the string in the CustomerID field.
foundIndex = CustomersBindingSource.Find("CustomerID",
searchString)
If foundIndex > -1 Then
DataRepeater1.CurrentItemIndex = foundIndex
Else
MsgBox("Item " & searchString & " not found.")
End If
6. Press F5 to run the application. Type a customer ID in SearchTextBox and click the Search button.
See Also
Introduction to 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: Display Item Headers in a DataRepeater Control
How to: Search Data in a DataRepeater Control
How to: Create a Master/Detail Form by Using Two DataRepeater Controls (Visual Studio)
How to: Change the Appearance of a DataRepeater Control
How to: Disable Adding and Deleting DataRepeater Items
Troubleshooting the DataRepeater Control
Troubleshooting the DataRepeater Control (Visual
Studio)
7/29/2017 • 3 min to read • Edit Online
This topic lists common issues that may occur when you are working with the DataRepeater control.
DataRepeater1.Top = ProductsBindingNavigator.Height
dataRepeater1.Top = productsBindingNavigator.Height;
See Also
Introduction to 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 (Visual Studio)
Line and Shape Controls (Visual Studio)
7/29/2017 • 1 min to read • Edit Online
The Visual Basic Power Packs Line and Shape controls are graphical controls that enable you to draw horizontal,
vertical, and diagonal lines, rectangles, squares, ovals, circles, and rectangles and squares with rounded corners on
a form or container.
The PowerPack controls are no longer included in Visual Studio, but you can download them from the Download
Center.
In This Section
Introduction to the Line and Shape Controls
Introduces and discusses the Line and Shape controls and describes the object model.
How to: Draw Lines with the LineShape Control
Demonstrates how to use the LineShape control to draw lines at design time and at run time.
How to: Draw Shapes with the OvalShape and RectangleShape Controls
Demonstrates how to use the OvalShape and RectangleShape controls to draw shapes at design time and at run
time.
How to: Enable Tabbing Between Shapes
Demonstrates how to enable users to move between shapes by using the keyboard.
Reference
Microsoft.VisualBasic.PowerPacks
Introduction to the Line and Shape Controls (Visual
Studio)
7/29/2017 • 2 min to read • Edit Online
The Visual Basic Power Packs Line and Shape controls are a set of three graphical controls that enable you to draw
lines and shapes on forms and containers. The LineShape control is used to draw horizontal, vertical, and diagonal
lines. The OvalShape control is used to draw circles and ovals, and the RectangleShape control is used to draw
rectangles and squares.
NOTE
Not all container controls support the Line and Shape controls. You cannot host a Line or Shape control on a
TableLayoutPanel or a FlowLayoutPanel.
See Also
Microsoft.VisualBasic.PowerPacks
How to: Draw Lines with the LineShape Control
How to: Draw Shapes with the OvalShape and RectangleShape Controls
How to: Enable Tabbing Between Shapes
How to: Draw Lines with the LineShape Control
(Visual Studio)
7/29/2017 • 1 min to read • Edit Online
You can use the LineShape control to draw horizontal, vertical, or diagonal lines on a form or container, both at
design time and at run time.
Note Your computer might show different names or locations for some of the Visual Studio user interface
elements in the following instructions. The Visual Studio edition that you have and the settings that you use
determine these elements. For more information, see Customizing Development Settings in Visual Studio.
To draw a line at design time
1. Drag the LineShape control from the Visual Basic PowerPacks tab in the Toolbox drag to a form or
container control.
2. Drag the sizing and move handles to size and position the line.
You can also size and position the line by changing the X1 , X2 , Y1 , and Y2 properties in the Properties
window.
3. In the Properties window, optionally set additional properties such as BorderStyle or BorderColor to
change the appearance of the line.
To draw a line at run time
1. On the Project menu, click Add Reference.
2. In the Add Reference dialog box, select Microsoft.VisualBasic.PowerPacks.VS, and then click OK.
3. In the Code Editor, add an Imports or using statement at the top of the module:
Imports Microsoft.VisualBasic.PowerPacks
using Microsoft.VisualBasic.PowerPacks;
See Also
LineShape
Introduction to the Line and Shape Controls
How to: Draw Shapes with the OvalShape and RectangleShape Controls
How to: Draw Shapes with the OvalShape and
RectangleShape Controls (Visual Studio)
7/29/2017 • 5 min to read • Edit Online
You can use the OvalShape control to draw circles or ovals on a form or container, both at design time and at run
time. You can use the RectangleShape control to draw squares, rectangles, or rectangles with rounded corners on a
form or container. You can also use this control to draw shapes both at design time and at run time.
You can customize the appearance of a shape by changing the width, color, and style of the border. The
background of a shape is transparent by default; you can customize the background to display a solid color, a
pattern, a gradient fill (transitioning from one color to another), or an image.
To draw a simple shape at design time
1. Drag the OvalShape or RectangleShape control from the Visual Basic PowerPacks tab (to install, see
Visual Basic Power Packs Controls)in the Toolbox to a form or container control.
2. Drag the sizing and move handles to size and position the shape.
You can also size and position the shape by changing the Size and Position properties in the Properties
window.
To create a rectangle with rounded corners, select the CornerRadius property in the Properties window
and set it to a value that is greater than 0.
3. In the Properties window, optionally set additional properties to change the appearance of the shape.
To draw a simple shape at run time
1. On the Project menu, click Add Reference.
2. In the Add Reference dialog box, select Microsoft.VisualBasic.PowerPacks.VS, and then click OK.
3. In the Code Editor, add an Imports or using statement at the top of the module:
Imports Microsoft.VisualBasic.PowerPacks
using Microsoft.VisualBasic.PowerPacks;
Customizing Shapes
When you use the default settings, the OvalShape and RectangleShape controls are displayed with a solid black
border that is one pixel wide and a transparent background. You can change the width, style, and color of the
border by setting properties. Additional properties enable you to change the background of a shape to a solid
color, a pattern, a gradient fill, or an image.
Before you change the background of a shape, you should know how several of the properties interact.
The BackColor property setting has no effect unless the BackStyle property is set to
<xref:Microsoft.VisualBasic.PowerPacks.BackStyle.Opaque>.
If the FillStyle property is set to <xref:Microsoft.VisualBasic.PowerPacks.FillStyle.Solid>, the FillColor
overrides the BackColor.
If the FillStyle property is set to a pattern value such as
<xref:Microsoft.VisualBasic.PowerPacks.FillStyle.Horizontal> or
<xref:Microsoft.VisualBasic.PowerPacks.FillStyle.Vertical>, the pattern will be displayed in the FillColor. The
background will be displayed in the BackColor, provided that the BackStyle property is set to
<xref:Microsoft.VisualBasic.PowerPacks.BackStyle.Opaque>.
In order to display a gradient fill, the FillStyle property must be set to
<xref:Microsoft.VisualBasic.PowerPacks.FillStyle.Solid> and the FillGradientStyle property must be set to a
value other than <xref:Microsoft.VisualBasic.PowerPacks.FillGradientStyle.None>.
Setting the BackgroundImage property to an image overrides all other background settings.
To draw a circle that has a custom border
1. Drag the OvalShape control from the Visual Basic PowerPacks tab in the Toolbox to a form or container
control.
2. In the Properties window, in the Size property, set Height and Width to equal values.
3. Set the BorderColor property to the color that you want.
4. Set the BorderStyle property to any value other than Solid .
5. Set the BorderWidth to the size that you want, in pixels.
To draw a circle that has a solid fill
1. Drag the OvalShape control from the Visual Basic PowerPacks tab in the Toolbox to a form or container
control.
2. In the Properties window, in the Size property, set Height and Width to equal values.
3. Set the BackColor property to the color that you want.
4. Set the BackStyle property to Opaque .
To draw a circle that has a patterned fill
1. Drag the OvalShape control from the Visual Basic PowerPacks tab in the Toolbox to a form or container
control.
2. In the Properties window, in the Size property, set Height and Width to equal values.
3. Set the BackColor property to the color that you want for the background.
4. Set the BackStyle property to Opaque .
5. Set the FillColor property to the color that you want for the pattern.
6. Set the FillStyle property to any value other than Transparent or Solid .
To draw a circle that has a gradient fill
1. Drag the OvalShape control from the Visual Basic PowerPacks tab in the Toolbox to a form or container
control.
2. In the Properties window, in the Size property, set Height and Width to equal values.
3. Set the FillColor property to the color that you want for the starting color.
4. Set the FillGradientColor property to the color that you want for the ending color.
5. Set the FillGradientStyle property to a value other than None .
To draw a circle that is filled with an image
1. Drag the OvalShape control from the Visual Basic PowerPacks tab in the Toolbox to a form or container
control.
2. In the Properties window, in the Size property, set Height and Width to equal values.
3. Select the BackgroundImage property and click the ellipsis button (...).
4. In the Select Resource dialog box, select an image to display. If no image resources are listed, click Import
to browse to the location of an image.
5. Click OK to insert the image.
See Also
OvalShape
RectangleShape
Introduction to the Line and Shape Controls
How to: Draw Lines with the LineShape Control
How to: Enable Tabbing Between Shapes (Visual
Studio)
7/29/2017 • 1 min to read • Edit Online
Line and shape controls do not have TabStop or TabIndex properties, but you can still enable tabbing among
them. In the following example, pressing both the CTRL and the TAB keys will tab between shapes; pressing only
the TAB key will tab between the buttons.
NOTE
Your computer might show different names or locations for some of the Visual Studio user interface elements in the
following instructions. The Visual Studio edition that you have and the settings that you use determine these elements. For
more information, see Customizing Development Settings in Visual Studio.
Imports Microsoft.VisualBasic.PowerPacks
using Microsoft.VisualBasic.PowerPacks;
Dim sh As Shape
' Check for the Control and Tab keys.
If e.KeyCode = Keys.Tab And e.Modifiers = Keys.Control Then
' Find the next shape in the order.
sh = ShapeContainer1.GetNextShape(sender, True)
' Select the next shape.
ShapeContainer1.SelectNextShape(sender, False, True)
End If
End Sub
See Also
How to: Draw Shapes with the OvalShape and RectangleShape Controls
How to: Draw Lines with the LineShape Control
Introduction to the Line and Shape Controls
Deploying applications that reference Power Packs
controls (Visual Studio)
7/29/2017 • 1 min to read • Edit Online
If you want to deploy an application that references the Power Packs controls (LineShape, OvalShape,
RectangleShape, or DataRepeater), the controls must be installed on the destination computer.
NOTE
To install bootstrapped components, the user might need administrative or similar user permissions on the computer. For
ClickOnce applications, this means that the user will need administrative permissions to install the application, regardless of
the security level specified by the application. After the application is installed, the user can run the application without
administrative permissions.
During installation, users will be prompted to install the Power Packs controls if they are not present on the
destination computer.
As an alternative to bootstrapping, you can pre-deploy the Power Packs controls by using an electronic software
distribution system such as Microsoft Systems Management Server.
See also
How to: Install Prerequisites with a ClickOnce Application
Visual Basic Power Packs Controls
Customizing Projects and Extending My with Visual
Basic
7/29/2017 • 1 min to read • Edit Online
You can customize project templates to provide additional My objects. This makes it easy for other developers to
find and use your objects.
In This Section
Extending the My Namespace in Visual Basic
Describes how to add custom members and values to the My namespace in Visual Basic.
Packaging and Deploying Custom My Extensions
Describes how to publish custom My namespace extensions by using Visual Studio templates.
Extending the Visual Basic Application Model
Describes how to specify your own extensions to the application model by overriding members of the
WindowsFormsApplicationBase class.
Customizing Which Objects are Available in My
Describes how to control which My objects are enabled by setting your project's _MYTYPE conditional-compilation
constant.
Related Sections
Development with My
Describes which My objects are available in different project types by default.
Overview of the Visual Basic Application Model
Describes Visual Basic's model for controlling the behavior of Windows Forms applications.
How My Depends on Project Type
Describes which My objects are available in different project types by default.
Conditional Compilation
Discusses how the compiler uses conditional-compilation to select particular sections of code to compile and
exclude other sections.
ApplicationBase
Describes the My object that provides properties, methods, and events related to the current application.
See Also
Developing Applications with Visual Basic
Extending the My Namespace in Visual Basic
7/29/2017 • 8 min to read • Edit Online
The My namespace in Visual Basic exposes properties and methods that enable you to easily take advantage of the
power of the .NET Framework. The My namespace simplifies common programming problems, often reducing a
difficult task to a single line of code. Additionally, the My namespace is fully extensible so that you can customize
the behavior of My and add new services to its hierarchy to adapt to specific application needs. This topic discusses
both how to customize existing members of the My namespace and how to add your own custom classes to the
My namespace.
Topic Contents
Customizing Existing My Namespace Members
Adding Members to My Objects
Adding Custom Objects to the My Namespace
Adding Members to the My Namespace
Adding Events to Custom My Objects
Design Guidelines
Designing Class Libraries for My
Packaging and Deploying Extensions
My.User.CurrentPrincipal = CustomPrincipal
Setting the CurrentPrincipal property on the My.User object changes the identity under which the application
runs. The My.User object, in turn, returns information about the newly specified user.
Imports System.Net.NetworkInformation
Namespace My
Return dnsAddressList
End Get
End Property
End Class
End Namespace
Namespace My
<HideModuleName()>
Module MyCustomModule
End Module
End Namespace
To add members to the My namespace, add properties as needed to the module. For each property added to the
My namespace, add a private field of type ThreadSafeObjectProvider(Of T) , where the type is the type returned by
your custom property. This field is used to create thread-safe object instances to be returned by the property by
calling the GetInstance method. As a result, each thread that is accessing the extended property receives its own
instance of the returned type. The following example adds a property named SampleExtension that is of type
SampleExtension to the My namespace:
Namespace My
<HideModuleName()>
Module MyCustomExtensions
Private _extension As New ThreadSafeObjectProvider(Of SampleExtension)
Friend ReadOnly Property SampleExtension() As SampleExtension
Get
Return _extension.GetInstance()
End Get
End Property
End Module
End Namespace
Namespace My
Partial Friend Class MyApplication
End Class
End Namespace
You can add event handlers for your custom My objects by adding custom event handlers to the MyApplication
class. Custom events enable you to add code that will execute when an event handler is added, removed, or the
event is raised. Note that the AddHandler code for a custom event runs only if code is added by a user to handle
the event. For example, consider that the SampleExtension object from the previous section has a Load event that
you want to add a custom event handler for. The following code example shows a custom event handler named
SampleExtensionLoad that will be invoked when the My.SampleExtension.Load event occurs. When code is added to
handle the new My.SampleExtensionLoad event, the AddHandler part of this custom event code is executed. The
MyApplication_SampleExtensionLoad method is included in the code example to show an example of an event
handler that handles the My.SampleExtensionLoad event. Note that the SampleExtensionLoad event will be available
when you select the My Application Events option in the left drop-down list above the Code Editor when you are
editing the ApplicationEvents.vb file.
Namespace My
End Sub
End Class
End Namespace
Design Guidelines
When you develop extensions to the My namespace, use the following guidelines to help minimize the
maintenance costs of your extension components.
Include only the extension logic. The logic included in the My namespace extension should include only
the code that is needed to expose the required functionality in the My namespace. Because your extension
will reside in user projects as source code, updating the extension component incurs a high maintenance
cost and should be avoided if possible.
Minimize project assumptions. When you create your extensions of the My namespace, do not assume a
set of references, project-level imports, or specific compiler settings (for example, Option Strict off).
Instead, minimize dependencies and fully qualify all type references by using the Global keyword. Also,
ensure that the extension compiles with Option Strict on to minimize errors in the extension.
Isolate the extension code. Placing the code in a single file makes your extension easily deployable as a
Visual Studio item template. For more information, see "Packaging and Deploying Extensions" later in this
topic. Placing all the My namespace extension code in a single file or a separate folder in a project will also
help users locate the My namespace extension.
These guidelines do not preclude general design principles for class libraries. Rather, they are recommendations
that are optimized for developers who are using Visual Basic and the My namespace. For general design principles
for creating class libraries, see Framework Design Guidelines.
See Also
Packaging and Deploying Custom My Extensions
Extending the Visual Basic Application Model
Customizing Which Objects are Available in My
My Extensions Page, Project Designer
Application Page, Project Designer (Visual Basic)
Partial
Packaging and deploying custom My extensions
(Visual Basic)
7/29/2017 • 4 min to read • Edit Online
Visual Basic provides an easy way for you to deploy your custom My namespace extensions by using Visual
Studio templates. If you are creating a project template for which your My extensions are an integral part of the
new project type, you can just include your custom My extension code with the project when you export the
template. For more information about exporting project templates, see How to: Create Project Templates.
If your custom My extension is in a single code file, you can export the file as an item template that users can add
to any type of Visual Basic project. You can then customize the item template to enable additional capabilities and
behavior for your custom My extension in a Visual Basic project. Those capabilities include the following:
Allowing users to manage your custom My extension from the My Extensions page of the Visual Basic
Project Designer.
Automatically adding your custom My extension when a reference to a specified assembly is added to a
project.
Hiding the My extension item template in the Add Item dialog box so that it is not included in the list of
project items.
This topic discusses how to package a custom My extension as a hidden item template that can be managed from
the My Extensions page of the Visual Basic Project Designer. The custom My extension can also be added
automatically when a reference to a specified assembly is added to a project.
NOTE
If your My namespace extension has a dependency on a particular assembly, you can customize your item template to
automatically install your My namespace extension when a reference to that assembly is added. As a result, you will want to
exclude that assembly reference when you export the code file as a Visual Studio item template.
<VBMyExtensionTemplate
ID="Microsoft.VisualBasic.Samples.MyExtensions.MyPrinterInfo"
Version="1.0.0.0"
AssemblyFullName="Microsoft.VisualBasic.PowerPacks.vs"
/>
The CustomData file contains a < VBMyExtensionTemplate> element that has attributes as listed in the following
table.
ATTRIBUTE DESCRIPTION
<CustomDataSignature>Microsoft.VisualBasic.MyExtension</CustomDataSignature>
You cannot modify files in a compressed folder (.zip file) directly. You must copy the .vstemplate file from the
compressed folder, modify it, and then replace the .vstemplate file in the compressed folder with your updated
copy.
The following example shows the contents of a .vstemplate file that has the <CustomDataSignature> element added.
<VSTemplate Version="2.0.0" xmlns="http://schemas.microsoft.com/developer/vstemplate/2005" Type="Item">
<TemplateData>
<DefaultName>MyCustomExtensionModule.vb</DefaultName>
<Name>MyPrinterInfo</Name>
<Description>Custom My Extensions Item Template</Description>
<ProjectType>VisualBasic</ProjectType>
<SortOrder>10</SortOrder>
<Icon>__TemplateIcon.ico</Icon>
<CustomDataSignature >Microsoft.VisualBasic.MyExtension</CustomDataSignature>
</TemplateData>
<TemplateContent>
<References />
<ProjectItem SubType="Code"
TargetFileName="$fileinputname$.vb"
ReplaceParameters="true"
>MyCustomExtensionModule.vb</ProjectItem>
</TemplateContent>
</VSTemplate>
See also
Extending the My Namespace in Visual Basic
Extending the Visual Basic Application Model
Customizing Which Objects are Available in My
My Extensions Page, Project Designer
Extending the Visual Basic Application Model
7/29/2017 • 4 min to read • Edit Online
You can add functionality to the application model by overriding the Overridable members of the
WindowsFormsApplicationBase class. This technique allows you to customize the behavior of the application
model and add calls to your own methods as the application starts up and shuts down.
The Visual Basic Application Model also provides the StartupNextInstance and UnhandledException events. The
following graphics show the mechanism for raising these events.
If the application is a single-instance application, and the application is already running, the subsequent instance of
the application calls the OnStartupNextInstance method on the original instance of the application, and then exits.
The OnStartupNextInstance(StartupNextInstanceEventArgs) constructor calls the UseCompatibleTextRendering
property to determine which text rendering engine to use for the application's forms. By default, the
UseCompatibleTextRendering property returns False , indicating that the GDI text rendering engine be used,
which is the default in Visual Basic 2005. You can override the UseCompatibleTextRendering property to return
True , which indicates that the GDI+ text rendering engine be used, which is the default in Visual Basic .NET 2002
and Visual Basic .NET 2003.
EnableVisualStyles If the application will use visual styles Enable XP visual styles check box
that match Windows XP.
See Also
ApplicationBase
Startup
StartupNextInstance
UnhandledException
Shutdown
NetworkAvailabilityChanged
NetworkAvailabilityChanged
Overview of the Visual Basic Application Model
Application Page, Project Designer (Visual Basic)
Customizing Which Objects are Available in My
(Visual Basic)
7/29/2017 • 2 min to read • Edit Online
This topic describes how you can control which My objects are enabled by setting your project's _MYTYPE
conditional-compilation constant. The Visual Studio Integrated Development Environment (IDE) keeps the
_MYTYPE conditional-compilation constant for a project in sync with the project's type.
/define:_MYTYPE=\"WindowsForms\"
This table shows what the _MYTYPE conditional-compilation constant is set to for several project types.
Web "Web"
Empty "Empty"
NOTE
All conditional-compilation string comparisons are case-sensitive, regardless of how the Option Compare statement is set.
By default, undefined conditional-compilation constants resolve to FALSE . You can specify values for the
undefined constants when compiling your project to override the default behavior.
NOTE
When _MYTYPE is set to "Custom", the project contains the My namespace, but it contains no objects. However, setting
_MYTYPE to "Empty" prevents the compiler from adding the My namespace and its objects.
This table describes the effects of the predefined values of the _MY compilation constants.
CONSTANT MEANING
See Also
ApplicationBase
Computer
Log
User
How My Depends on Project Type
Conditional Compilation
/define (Visual Basic)
My.Forms Object
My.Request Object
My.Response Object
My.WebServices Object
Programming Concepts (Visual Basic)
8/11/2017 • 1 min to read • Edit Online
In This Section
TITLE DESCRIPTION
Assemblies and the Global Assembly Cache (Visual Basic) Describes how to create and use assemblies.
Asynchronous Programming with Async and Await (Visual Describes how to write asynchronous solutions by using
Basic) Async and Await keywords. Includes a walkthrough.
Attributes overview (Visual Basic) Discusses how to provide additional information about
programming elements such as types, fields, methods, and
properties by using attributes.
Caller Information (Visual Basic) Describes how to obtain information about the caller of a
method. This information includes the file path and the line
number of the source code and the member name of the
caller.
Collections (Visual Basic) Describes some of the types of collections provided by the
.NET Framework. Demonstrates how to use simple collections
and collections of key/value pairs.
Covariance and Contravariance (Visual Basic) Shows how to enable implicit conversion of generic type
parameters in interfaces and delegates.
Expression Trees (Visual Basic) Explains how you can use expression trees to enable dynamic
modification of executable code.
Iterators (Visual Basic) Describes iterators, which are used to step through collections
and return elements one at a time.
Language-Integrated Query (LINQ) (Visual Basic) Discusses the powerful query capabilities in the language
syntax of Visual Basic, and themodel for querying relational
databases, XML documents, datasets, and in-memory
collections.
Serialization (Visual Basic) Describes key concepts in binary, XML, and SOAP serialization.
TITLE DESCRIPTION
Threading (Visual Basic) Provides an overview of the .NET threading model and shows
how to write code that performs multiple tasks at the same
time to improve the performance and responsiveness of your
applications.
Related Sections
Performance Tips Discusses several basic rules that may help you increase the
performance of your application.
Assemblies and the Global Assembly Cache (Visual
Basic)
7/29/2017 • 3 min to read • Edit Online
Assemblies form the fundamental unit of deployment, version control, reuse, activation scoping, and security
permissions for a .NET-based application. Assemblies take the form of an executable (.exe) file or dynamic link
library (.dll) file, and are the building blocks of the .NET Framework. They provide the common language runtime
with the information it needs to be aware of type implementations. You can think of an assembly as a collection of
types and resources that form a logical unit of functionality and are built to work together.
Assemblies can contain one or more modules. For example, larger projects may be planned in such a way that
several individual developers work on separate modules, all coming together to create a single assembly. For
more information about modules, see the topic How to: Build a Multifile Assembly.
Assemblies have the following properties:
Assemblies are implemented as .exe or .dll files.
You can share an assembly between applications by putting it in the global assembly cache. Assemblies
must be strong-named before they can be included in the global assembly cache. For more information,
see Strong-Named Assemblies.
Assemblies are only loaded into memory if they are required. If they are not used, they are not loaded. This
means that assemblies can be an efficient way to manage resources in larger projects.
You can programmatically obtain information about an assembly by using reflection. For more
information, see Reflection (Visual Basic).
If you want to load an assembly only to inspect it, use a method such as ReflectionOnlyLoadFrom.
Assembly Manifest
Within every assembly is an assembly manifest. Similar to a table of contents, the assembly manifest contains the
following:
The assembly's identity (its name and version).
A file table describing all the other files that make up the assembly, for example, any other assemblies you
created that your .exe or .dll file relies on, or even bitmap or Readme files.
An assembly reference list, which is a list of all external dependencies—.dlls or other files your application
needs that may have been created by someone else. Assembly references contain references to both global
and private objects. Global objects reside in the global assembly cache, an area available to other
applications, somewhat like the System32 directory. The Microsoft.VisualBasic namespace is an example of
an assembly in the global assembly cache. Private objects must be in a directory at either the same level as
or below the directory in which your application is installed.
Because assemblies contain information about content, versioning, and dependencies, the applications you create
with Visual Basic do not rely on Windows registry values to function properly. Assemblies reduce .dll conflicts and
make your applications more reliable and easier to deploy. In many cases, you can install a .NET-based application
simply by copying its files to the target computer.
For more information see Assembly Manifest.
Adding a Reference to an Assembly
To use an assembly, you must add a reference to it. Next, you use the Imports statement to choose the namespace
of the items you want to use. Once an assembly is referenced and imported, all the accessible classes, properties,
methods, and other members of its namespaces are available to your application as if their code were part of your
source file.
Creating an Assembly
Compile your application by building it from the command line using the command-line compiler. For details
about building assemblies from the command line, see Building from the Command Line.
NOTE
To build an assembly in Visual Studio, on the Build menu choose Build.
See Also
Assemblies in the Common Language Runtime
Friend Assemblies (Visual Basic)
How to: Share an Assembly with Other Applications (Visual Basic)
How to: Load and Unload Assemblies (Visual Basic)
How to: Determine If a File Is an Assembly (Visual Basic)
How to: Create and Use Assemblies Using the Command Line (Visual Basic)
Walkthrough: Embedding Types from Managed Assemblies in Visual Studio (Visual Basic)
Walkthrough: Embedding Type Information from Microsoft Office Assemblies in Visual Studio (Visual Basic)
Asynchronous Programming with Async and Await
(Visual Basic)
7/29/2017 • 16 min to read • Edit Online
You can avoid performance bottlenecks and enhance the overall responsiveness of your application by using
asynchronous programming. However, traditional techniques for writing asynchronous applications can be
complicated, making them difficult to write, debug, and maintain.
Visual Studio 2012 introduced a simplified approach, async programming, that leverages asynchronous support
in the .NET Framework 4.5 and higher as well as in the Windows Runtime. The compiler does the difficult work
that the developer used to do, and your application retains a logical structure that resembles synchronous code.
As a result, you get all the advantages of asynchronous programming with a fraction of the effort.
This topic provides an overview of when and how to use async programming and includes links to support topics
that contain details and examples.
Asynchrony proves especially valuable for applications that access the UI thread because all UI-related activity
usually shares one thread. If any process is blocked in a synchronous application, all are blocked. Your application
stops responding, and you might conclude that it has failed when instead it's just waiting.
When you use asynchronous methods, the application continues to respond to the UI. You can resize or minimize
a window, for example, or you can close the application if you don't want to wait for it to finish.
The async-based approach adds the equivalent of an automatic transmission to the list of options that you can
choose from when designing asynchronous operations. That is, you get all the benefits of traditional
asynchronous programming but with much less effort from the developer.
The following example shows an async method. Almost everything in the code should look completely familiar to
you. The comments call out the features that you add to create the asynchrony.
You can find a complete Windows Presentation Foundation (WPF) example file at the end of this topic, and you
can download the sample from Async Sample: Example from "Asynchronous Programming with Async and
Await".
' GetStringAsync returns a Task(Of String). That means that when you await the
' task you'll get a string (urlContents).
Dim getStringTask As Task(Of String) = client.GetStringAsync("http://msdn.microsoft.com")
' You can do work here that doesn't rely on the string from GetStringAsync.
DoIndependentWork()
If AccessTheWebAsync doesn't have any work that it can do between calling GetStringAsync and awaiting its
completion, you can simplify your code by calling and awaiting in the following single statement.
The following characteristics summarize what makes the previous example an async method.
The method signature includes an Async modifier.
The name of an async method, by convention, ends with an "Async" suffix.
The return type is one of the following types:
Task<TResult> if your method has a return statement in which the operand has type TResult.
Task if your method has no return statement or has a return statement with no operand.
Sub if you're writing an async event handler.
For more information, see "Return Types and Parameters" later in this topic.
The method usually includes at least one await expression, which marks a point where the method can't
continue until the awaited asynchronous operation is complete. In the meantime, the method is suspended,
and control returns to the method's caller. The next section of this topic illustrates what happens at the
suspension point.
In async methods, you use the provided keywords and types to indicate what you want to do, and the compiler
does the rest, including keeping track of what must happen when control returns to an await point in a suspended
method. Some routine processes, such as loops and exception handling, can be difficult to handle in traditional
asynchronous code. In an async method, you write these elements much as you would in a synchronous solution,
and the problem is solved.
For more information about asynchrony in previous versions of the .NET Framework, see TPL and Traditional .NET
Framework Asynchronous Programming.
NOTE
If GetStringAsync (and therefore getStringTask ) is complete before AccessTheWebAsync awaits it, control
remains in AccessTheWebAsync . The expense of suspending and then returning to AccessTheWebAsync would be
wasted if the called asynchronous process ( getStringTask ) has already completed and AccessTheWebSync doesn't
have to wait for the final result.
Inside the caller (the event handler in this example), the processing pattern continues. The caller might do
other work that doesn't depend on the result from AccessTheWebAsync before awaiting that result, or the
caller might await immediately. The event handler is waiting for AccessTheWebAsync , and
AccessTheWebAsync is waiting for GetStringAsync .
7. GetStringAsync completes and produces a string result. The string result isn't returned by the call to
GetStringAsync in the way that you might expect. (Remember that the method already returned a task in
step 3.) Instead, the string result is stored in the task that represents the completion of the method,
getStringTask . The await operator retrieves the result from getStringTask . The assignment statement
assigns the retrieved result to urlContents .
8. When AccessTheWebAsync has the string result, the method can calculate the length of the string. Then the
work of AccessTheWebAsync is also complete, and the waiting event handler can resume. In the full example
at the end of the topic, you can confirm that the event handler retrieves and prints the value of the length
result.
If you are new to asynchronous programming, take a minute to consider the difference between synchronous and
asynchronous behavior. A synchronous method returns when its work is complete (step 5), but an async method
returns a task value when its work is suspended (steps 3 and 6). When the async method eventually completes its
work, the task is marked as completed and the result, if any, is stored in the task.
For more information about control flow, see Control Flow in Async Programs (Visual Basic).
Threads
Async methods are intended to be non-blocking operations. An Await expression in an async method doesn’t
block the current thread while the awaited task is running. Instead, the expression signs up the rest of the method
as a continuation and returns control to the caller of the async method.
The Async and Await keywords don't cause additional threads to be created. Async methods don't require
multithreading because an async method doesn't run on its own thread. The method runs on the current
synchronization context and uses time on the thread only when the method is active. You can use
System.Threading.Tasks.Task.Run to move CPU-bound work to a background thread, but a background thread
doesn't help with a process that's just waiting for results to become available.
The async-based approach to asynchronous programming is preferable to existing approaches in almost every
case. In particular, this approach is better than BackgroundWorker for IO-bound operations because the code is
simpler and you don't have to guard against race conditions. In combination with
System.Threading.Tasks.Task.Run, async programming is better than BackgroundWorker for CPU-bound
operations because async programming separates the coordination details of running your code from the work
that Task.Run transfers to the threadpool.
' . . .
' The method has no return statement.
End Function
Each returned task represents ongoing work. A task encapsulates information about the state of the asynchronous
process and, eventually, either the final result from the process or the exception that the process raises if it doesn't
succeed.
An async method can also be a Sub method. This return type is used primarily to define event handlers, where a
return type is required. Async event handlers often serve as the starting point for async programs.
An async method that’s a Sub procedure can’t be awaited, and the caller can't catch any exceptions that the
method throws.
An async method can't declare ByRef parameters, but the method can call methods that have such parameters.
For more information and examples, see Async Return Types (Visual Basic). For more information about how to
catch exceptions in async methods, see Try...Catch...Finally Statement.
Asynchronous APIs in Windows Runtime programming have one of the following return types, which are similar
to tasks:
IAsyncOperation, which corresponds to Task<TResult>
IAsyncAction, which corresponds to Task
IAsyncActionWithProgress
IAsyncOperationWithProgress
For more information and an example, see Quickstart: using the await operator for asynchronous programming.
Naming Convention
By convention, you append "Async" to the names of methods that have an Async modifier.
You can ignore the convention where an event, base class, or interface contract suggests a different name. For
example, you shouldn’t rename common event handlers, such as Button1_Click .
Walkthrough: Accessing the Web by Shows how to convert a synchronous Async Sample: Accessing the Web
Using Async and Await (Visual Basic) WPF solution to an asynchronous WPF Walkthrough
solution. The application downloads a
series of websites.
How to: Make Multiple Web Requests Demonstrates how to start several Async Sample: Make Multiple Web
in Parallel by Using Async and Await tasks at the same time. Requests in Parallel
(Visual Basic)
Async Return Types (Visual Basic) Illustrates the types that async
methods can return and explains when
each type is appropriate.
Control Flow in Async Programs (Visual Traces in detail the flow of control Async Sample: Control Flow in Async
Basic) through a succession of await Programs
expressions in an asynchronous
program.
Fine-Tuning Your Async Application Shows how to add the following Async Sample: Fine Tuning Your
(Visual Basic) functionality to your async solution: Application
WhenAny: Bridging between the .NET Shows how to bridge between Task Async Sample: Bridging between .NET
Framework and the Windows Runtime types in the .NET Framework and and Windows Runtime (AsTask and
IAsyncOperations in the Windows WhenAny)
Runtime so that you can use WhenAny
with a Windows Runtime method.
Async Cancellation: Bridging between Shows how to bridge between Task Async Sample: Bridging between .NET
the .NET Framework and the Windows types in the .NET Framework and and Windows Runtime (AsTask &
Runtime IAsyncOperations in the Windows Cancellation)
Runtime so that you can use
CancellationTokenSource with a
Windows Runtime method.
TITLE DESCRIPTION SAMPLE
Using Async for File Access (Visual Lists and demonstrates the benefits of
Basic) using async and await to access files.
Complete Example
The following code is the MainWindow.xaml.vb file from the Windows Presentation Foundation (WPF) application
that this topic discusses. You can download the sample from Async Sample: Example from "Asynchronous
Programming with Async and Await".
' Add an Imports statement and a reference for System.Net.Http
Imports System.Net.Http
Class MainWindow
' Mark the event handler with async so you can use Await in it.
Private Async Sub StartButton_Click(sender As Object, e As RoutedEventArgs)
ResultsTextBox.Text &=
String.Format(vbCrLf & "Length of the downloaded string: {0}." & vbCrLf, contentLength)
End Sub
' GetStringAsync returns a Task(Of String). That means that when you await the
' task you'll get a string (urlContents).
Dim getStringTask As Task(Of String) = client.GetStringAsync("http://msdn.microsoft.com")
' You can do work here that doesn't rely on the string from GetStringAsync.
DoIndependentWork()
Sub DoIndependentWork()
ResultsTextBox.Text &= "Working . . . . . . ." & vbCrLf
End Sub
End Class
' Working . . . . . . .
See Also
Await Operator
Async
Attributes overview (Visual Basic)
7/29/2017 • 4 min to read • Edit Online
Attributes provide a powerful method of associating metadata, or declarative information, with code (assemblies,
types, methods, properties, and so forth). After an attribute is associated with a program entity, the attribute can
be queried at run time by using a technique called reflection. For more information, see Reflection (Visual Basic).
Attributes have the following properties:
Attributes add metadata to your program. Metadata is information about the types defined in a program.
All .NET assemblies contain a specified set of metadata that describes the types and type members defined
in the assembly. You can add custom attributes to specify any additional information that is required. For
more information, see, Creating Custom Attributes (Visual Basic).
You can apply one or more attributes to entire assemblies, modules, or smaller program elements such as
classes and properties.
Attributes can accept arguments in the same way as methods and properties.
Your program can examine its own metadata or the metadata in other programs by using reflection. For
more information, see Accessing Attributes by Using Reflection (Visual Basic).
Using Attributes
Attributes can be placed on most any declaration, though a specific attribute might restrict the types of
declarations on which it is valid. In Visual Basic, an attribute is enclosed in angle brackets (< >). It must appear
immediately before the element to which it is applied, on the same line.
In this example, the SerializableAttribute attribute is used to apply a specific characteristic to a class:
Imports System.Runtime.InteropServices
<System.Runtime.InteropServices.DllImport("user32.dll")>
Sub SampleMethod()
End Sub
Imports System.Runtime.InteropServices
Sub MethodA(<[In](), Out()> ByVal x As Double)
End Sub
Sub MethodB(<Out(), [In]()> ByVal x As Double)
End Sub
Some attributes can be specified more than once for a given entity. An example of such a multiuse attribute is
ConditionalAttribute:
<Conditional("DEBUG"), Conditional("TEST1")>
Sub TraceMethod()
End Sub
NOTE
By convention, all attribute names end with the word "Attribute" to distinguish them from other items in the .NET
Framework. However, you do not need to specify the attribute suffix when using attributes in code. For example,
[DllImport] is equivalent to [DllImportAttribute] , but DllImportAttribute is the attribute's actual name in the
.NET Framework.
Attribute Parameters
Many attributes have parameters, which can be positional, unnamed, or named. Any positional parameters must
be specified in a certain order and cannot be omitted; named parameters are optional and can be specified in any
order. Positional parameters are specified first. For example, these three attributes are equivalent:
<DllImport("user32.dll")>
<DllImport("user32.dll", SetLastError:=False, ExactSpelling:=False)>
<DllImport("user32.dll", ExactSpelling:=False, SetLastError:=False)>
The first parameter, the DLL name, is positional and always comes first; the others are named. In this case, both
named parameters default to false, so they can be omitted. Refer to the individual attribute's documentation for
information on default parameter values.
Attribute Targets
The target of an attribute is the entity to which the attribute applies. For example, an attribute may apply to a
class, a particular method, or an entire assembly. By default, an attribute applies to the element that it precedes.
But you can also explicitly identify, for example, whether an attribute is applied to a method, or to its parameter,
or to its return value.
To explicitly identify an attribute target, use the following syntax:
<target : attribute-list>
The following example shows how to apply attributes to assemblies and modules. For more information, see
Common Attributes (Visual Basic).
Imports System.Reflection
<Assembly: AssemblyTitleAttribute("Production assembly 4"),
Module: CLSCompliant(True)>
Related Sections
For more information, see:
Creating Custom Attributes (Visual Basic)
Accessing Attributes by Using Reflection (Visual Basic)
How to: Create a C/C++ Union by Using Attributes (Visual Basic)
Common Attributes (Visual Basic)
Caller Information (Visual Basic)
See Also
Visual Basic Programming Guide
Reflection (Visual Basic)
Attributes
Expression Trees (Visual Basic)
7/29/2017 • 4 min to read • Edit Online
Expression trees represent code in a tree-like data structure, where each node is an expression, for example, a
method call or a binary operation such as x < y .
You can compile and run code represented by expression trees. This enables dynamic modification of executable
code, the execution of LINQ queries in various databases, and the creation of dynamic queries. For more
information about expression trees in LINQ, see How to: Use Expression Trees to Build Dynamic Queries (Visual
Basic).
Expression trees are also used in the dynamic language runtime (DLR) to provide interoperability between dynamic
languages and the .NET Framework and to enable compiler writers to emit expression trees instead of Microsoft
intermediate language (MSIL). For more information about the DLR, see Dynamic Language Runtime Overview.
You can have the C# or Visual Basic compiler create an expression tree for you based on an anonymous lambda
expression, or you can create expression trees manually by using the System.Linq.Expressions namespace.
' Manually build the expression tree for the lambda expression num => num < 5.
Dim numParam As ParameterExpression = Expression.Parameter(GetType(Integer), "num")
Dim five As ConstantExpression = Expression.Constant(5, GetType(Integer))
Dim numLessThanFive As BinaryExpression = Expression.LessThan(numParam, five)
Dim lambda1 As Expression(Of Func(Of Integer, Boolean)) =
Expression.Lambda(Of Func(Of Integer, Boolean))(
numLessThanFive,
New ParameterExpression() {numParam})
In .NET Framework 4 or later, the expression trees API also supports assignments and control flow expressions
such as loops, conditional blocks, and try-catch blocks. By using the API, you can create expression trees that are
more complex than those that can be created from lambda expressions by the Visual Basic compiler. The following
example demonstrates how to create an expression tree that calculates the factorial of a number.
Console.WriteLine(factorial)
' Prints 120.
For more information, see Generating Dynamic Methods with Expression Trees in Visual Studio 2010, which also
applies to later versions of Visual Studio.
' Invoking the delegate and writing the result to the console.
Console.WriteLine(result(4))
For more information, see How to: Execute Expression Trees (Visual Basic).
See Also
System.Linq.Expressions
How to: Execute Expression Trees (Visual Basic)
How to: Modify Expression Trees (Visual Basic)
Lambda Expressions
Dynamic Language Runtime Overview
Programming Concepts (Visual Basic)
Iterators (Visual Basic)
7/29/2017 • 10 min to read • Edit Online
An iterator can be used to step through collections such as lists and arrays.
An iterator method or get accessor performs a custom iteration over a collection. An iterator method uses the
Yield statement to return each element one at a time. When a Yield statement is reached, the current location in
code is remembered. Execution is restarted from that location the next time the iterator function is called.
You consume an iterator from client code by using a For Each…Next statement, or by using a LINQ query.
In the following example, the first iteration of the For Each loop causes execution to proceed in the SomeNumbers
iterator method until the first Yield statement is reached. This iteration returns a value of 3, and the current
location in the iterator method is retained. On the next iteration of the loop, execution in the iterator method
continues from where it left off, again stopping when it reaches a Yield statement. This iteration returns a value of
5, and the current location in the iterator method is again retained. The loop completes when the end of the iterator
method is reached.
Sub Main()
For Each number As Integer In SomeNumbers()
Console.Write(number & " ")
Next
' Output: 3 5 8
Console.ReadKey()
End Sub
The return type of an iterator method or get accessor can be IEnumerable, IEnumerable<T>, IEnumerator, or
IEnumerator<T>.
You can use an Exit Function or Return statement to end the iteration.
A Visual Basic iterator function or get accessor declaration includes an Iterator modifier.
Iterators were introduced in Visual Basic in Visual Studio 2012.
In this topic
Simple Iterator
Creating a Collection Class
Try Blocks
Anonymous Methods
Using Iterators with a Generic List
Syntax Information
Technical Implementation
Use of Iterators
NOTE
For all examples in the topic except the Simple Iterator example, include Imports statements for the System.Collections
and System.Collections.Generic namespaces.
Simple Iterator
The following example has a single Yield statement that is inside a For…Next loop. In Main , each iteration of the
For Each statement body creates a call to the iterator function, which proceeds to the next Yield statement.
Sub Main()
For Each number As Integer In EvenSequence(5, 18)
Console.Write(number & " ")
Next
' Output: 6 8 10 12 14 16 18
Console.ReadKey()
End Sub
Public days =
New String() {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"}
The following example creates a Zoo class that contains a collection of animals.
The For Each statement that refers to the class instance ( theZoo ) implicitly calls the GetEnumerator method. The
For Each statements that refer to the Birds and Mammals properties use the AnimalsForType named iterator
method.
Sub Main()
Dim theZoo As New Zoo()
theZoo.AddMammal("Whale")
theZoo.AddMammal("Rhinoceros")
theZoo.AddBird("Penguin")
theZoo.AddBird("Warbler")
Console.ReadKey()
End Sub
Try Blocks
Visual Basic allows a Yield statement in the Try block of a Try...Catch...Finally Statement. A Try block that has a
Yield statement can have Catch blocks, and can have a Finally block.
The following example includes Try , Catch , and Finally blocks in an iterator function. The Finally block in the
iterator function executes before the For Each iteration finishes.
Sub Main()
For Each number As Integer In Test()
Console.WriteLine(number)
Next
Console.WriteLine("For Each is done.")
' Output:
' 3
' 4
' Something happened. Yields are done.
' Finally is called.
' For Each is done.
Console.ReadKey()
End Sub
Anonymous Methods
In Visual Basic, an anonymous function can be an iterator function. The following example illustrates this.
The following example has a non-iterator method that validates the arguments. The method returns the result of an
anonymous iterator that describes the collection elements.
Sub Main()
For Each number As Integer In GetSequence(5, 10)
Console.Write(number & " ")
Next
' Output: 5 6 7 8 9 10
Console.ReadKey()
End Sub
If validation is instead inside the iterator function, the validation cannot be performed until the start of the first
iteration of the For Each body.
Sub Main()
Dim theStack As New Stack(Of Integer)
Console.ReadKey()
End Sub
Yield GetEnumerator()
End Function
Syntax Information
An iterator can occur as a method or get accessor. An iterator cannot occur in an event, instance constructor,
static constructor, or static destructor.
An implicit conversion must exist from the expression type in the Yield statement to the return type of the
iterator.
In Visual Basic, an iterator method cannot have any ByRef parameters.
In Visual Basic, "Yield" is not a reserved word and has special meaning only when it is used in an Iterator method
or get accessor.
Technical Implementation
Although you write an iterator as a method, the compiler translates it into a nested class that is, in effect, a state
machine. This class keeps track of the position of the iterator as long the For Each...Next loop in the client code
continues.
To see what the compiler does, you can use the Ildasm.exe tool to view the Microsoft intermediate language code
that is generated for an iterator method.
When you create an iterator for a class or struct, you do not have to implement the whole IEnumerator interface.
When the compiler detects the iterator, it automatically generates the Current , MoveNext , and Dispose methods
of the IEnumerator or IEnumerator<T> interface.
On each successive iteration of the For Each…Next loop (or the direct call to IEnumerator.MoveNext ), the next
iterator code body resumes after the previous Yield statement. It then continues to the next Yield statement
until the end of the iterator body is reached, or until an Exit Function or Return statement is encountered.
Iterators do not support the System.Collections.IEnumerator.Reset method. To re-iterate from the start, you must
obtain a new iterator.
For additional information, see the Visual Basic Language Specification.
Use of Iterators
Iterators enable you to maintain the simplicity of a For Each loop when you need to use complex code to populate
a list sequence. This can be useful when you want to do the following:
Modify the list sequence after the first For Each loop iteration.
Avoid fully loading a large list before the first iteration of a For Each loop. An example is a paged fetch to
load a batch of table rows. Another example is the EnumerateFiles method, which implements iterators
within the .NET Framework.
Encapsulate building the list in the iterator. In the iterator method, you can build the list and then yield each
result in a loop.
See Also
System.Collections.Generic
IEnumerable<T>
For Each...Next Statement
Yield Statement
Iterator
Language-Integrated Query (LINQ) (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
LINQ is a set of features that extends powerful query capabilities to the language syntax of Visual Basic. LINQ
introduces standard, easily-learned patterns for querying and updating data, and the technology can be extended
to support potentially any kind of data store. The .NET Framework includes LINQ provider assemblies that enable
the use of LINQ with .NET Framework collections, SQL Server databases, ADO.NET Datasets, and XML documents.
In This Section
Introduction to LINQ (Visual Basic)
Provides a general introduction to the kinds of applications that you can write and the kinds of problems that you
can solve with LINQ queries.
Getting Started with LINQ in Visual Basic
Describes the basic facts you should know in order to understand the Visual Basic documentation and samples.
Visual Studio IDE and Tools Support for LINQ (Visual Basic)
Describes Visual Studio's Object Relational Designer, debugger support for queries, and other IDE features related
to LINQ.
Standard Query Operators Overview (Visual Basic)
Provides an introduction to the standard query operators. It also provides links to topics that have more
information about each type of query operation.
LINQ to Objects (Visual Basic)
Includes links to topics that explain how to use LINQ to Objects to access in-memory data structures,
LINQ to XML (Visual Basic)
Includes links to topics that explain how to use LINQ to XML, which provides the in-memory document
modification capabilities of the Document Object Model (DOM), and supports LINQ query expressions.
LINQ to ADO.NET (Portal Page)
Provides an entry point for documentation about LINQ to DataSet, LINQ to SQL, and LINQ to Entities. LINQ to
DataSet enables you to build richer query capabilities into DataSet by using the same query functionality that is
available for other data sources. LINQ to SQL provides a run-time infrastructure for managing relational data as
objects. LINQ to Entities enables developers to write queries against the Entity Framework conceptual model by
using C#.
Enabling a Data Source for LINQ Querying
Provides an introduction to custom LINQ providers, LINQ expression trees, and other ways to extend LINQ.
Object-Oriented Programming (Visual Basic)
7/29/2017 • 10 min to read • Edit Online
Visual Basic provides full support for object-oriented programming including encapsulation, inheritance, and
polymorphism.
Encapsulation means that a group of related properties, methods, and other members are treated as a single unit
or object.
Inheritance describes the ability to create new classes based on an existing class.
Polymorphism means that you can have multiple classes that can be used interchangeably, even though each class
implements the same properties or methods in different ways.
This section describes the following concepts:
Classes and objects
Class members
Properties and fields
Methods
Constructors
Destructors
Events
Nested classes
Access modifiers and access levels
Instantiating classes
Shared classes and members
Anonymous types
Inheritance
Overriding members
Interfaces
Generics
Delegates
Visual Basic also provides a light version of classes called structures that are useful when you need to create large
array of objects and do not want to consume too much memory for that.
To define a structure:
Structure SampleStructure
End Structure
Class SampleClass
Public SampleField As String
End Class
Properties have get and set procedures, which provide more control on how values are set or returned.
Visual Basic allows you either to create a private field for storing the property value or use so-called auto-
implemented properties that create this field automatically behind the scenes and provide the basic logic for the
property procedures.
To define an auto-implemented property:
Class SampleClass
Public Property SampleProperty as String
End Class
If you need to perform some additional operations for reading and writing the property value, define a field for
storing the property value and provide the basic logic for storing and retrieving it:
Class SampleClass
Private m_Sample As String
Public Property Sample() As String
Get
' Return the value stored in the field.
Return m_Sample
End Get
Set(ByVal Value As String)
' Store the value in the field.
m_Sample = Value
End Set
End Property
End Class
Most properties have methods or procedures to both set and get the property value. However, you can create
read-only or write-only properties to restrict them from being modified or read. In Visual Basic you can use
ReadOnly and WriteOnly keywords. However, auto-implemented properties cannot be read-only or write-only.
NOTE
In Visual Basic, there are two ways to create a method: the Sub statement is used if the method does not return a value;
the Function statement is used if a method returns a value.
Class SampleClass
Public Function SampleFunc(ByVal SampleParam As String)
' Add code here
End Function
End Class
A class can have several implementations, or overloads, of the same method that differ in the number of
parameters or parameter types.
To overload a method:
In most cases you declare a method within a class definition. However, Visual Basic also supports extension
methods that allow you to add methods to an existing class outside the actual definition of the class.
For more information, see:
Function Statement
Sub Statement
Overloads
Extension Methods
Constructors
Constructors are class methods that are executed automatically when an object of a given type is created.
Constructors usually initialize the data members of the new object. A constructor can run only once when a class is
created. Furthermore, the code in the constructor always runs before any other code in a class. However, you can
create multiple constructor overloads in the same way as for any other method.
To define a constructor for a class:
Class SampleClass
Sub New(ByVal s As String)
// Add code here.
End Sub
End Class
For more information, see: Object Lifetime: How Objects Are Created and Destroyed.
Destructors
Destructors are used to destruct instances of classes. In the .NET Framework, the garbage collector automatically
manages the allocation and release of memory for the managed objects in your application. However, you may still
need destructors to clean up any unmanaged resources that your application creates. There can be only one
destructor for a class.
For more information about destructors and garbage collection in the .NET Framework, see Garbage Collection.
Events
Events enable a class or object to notify other classes or objects when something of interest occurs. The class that
sends (or raises) the event is called the publisher and the classes that receive (or handle) the event are called
subscribers. For more information about events, how they are raised and handled, see Events.
To declare events, use the Event Statement.
To raise events, use the RaiseEvent Statement.
To specify event handlers using a declarative way, use the WithEvents statement and the Handles clause.
To be able to dynamically add, remove, and change the event handler associated with an event, use the
AddHandler Statement and RemoveHandler Statement together with the AddressOf Operator.
Nested classes
A class defined within another class is called nested. By default, the nested class is private.
Class Container
Class Nested
' Add code here.
End Class
End Class
To create an instance of the nested class, use the name of the container class followed by the dot and then followed
by the name of the nested class:
Public The type or member can be accessed by any other code in the
same assembly or another assembly that references it.
Friend The type or member can be accessed by any code in the same
assembly, but not from another assembly.
Protected Friend The type or member can be accessed by any code in the same
assembly, or by any derived class in another assembly.
After instantiating a class, you can assign values to the instance's properties and fields and invoke class methods.
To assign values to properties during the class instantiation process, use object initializers:
To access the shared member, use the name of the class without creating an object of this class:
MsgBox(SampleClass.SampleString)
Shared modules in Visual Basic have shared members only and cannot be instantiated. Shared members also
cannot access non-shared properties, fields or methods
For more information, see:
Shared
Module Statement
Anonymous types
Anonymous types enable you to create objects without writing a class definition for the data type. Instead, the
compiler generates a class for you. The class has no usable name and contains the properties you specify in
declaring the object.
To create an instance of an anonymous type:
Inheritance
Inheritance enables you to create a new class that reuses, extends, and modifies the behavior that is defined in
another class. The class whose members are inherited is called the base class, and the class that inherits those
members is called the derived class. However, all classes in Visual Basic implicitly inherit from the Object class that
supports .NET class hierarchy and provides low-level services to all classes.
NOTE
Visual Basic doesn't support multiple inheritance. That is, you can specify only one base class for a derived class.
Class DerivedClass
Inherits BaseClass
End Class
By default all classes can be inherited. However, you can specify whether a class must not be used as a base class,
or create a class that can be used as a base class only.
To specify that a class cannot be used as a base class:
NotInheritable Class SampleClass
End Class
To specify that a class can be used as a base class only and cannot be instantiated:
Interfaces
Interfaces, like classes, define a set of properties, methods, and events. But unlike classes, interfaces do not provide
implementation. They are implemented by classes, and defined as separate entities from classes. An interface
represents a contract, in that a class that implements an interface must implement every aspect of that interface
exactly as it is defined.
To define an interface:
Generics
Classes, structures, interfaces and methods in .NET can include type parameters that define types of objects that
they can store or use. The most common example of generics is a collection, where you can specify the type of
objects to be stored in a collection.
To define a generic class:
Class SampleGeneric(Of T)
Public Field As T
End Class
Delegates
A delegate is a type that defines a method signature, and can provide a reference to any method with a compatible
signature. You can invoke (or call) the method through the delegate. Delegates are used to pass methods as
arguments to other methods.
NOTE
Event handlers are nothing more than methods that are invoked through delegates. For more information about using
delegates in event handling, see Events.
To create a delegate:
To create a reference to a method that matches the signature specified by the delegate:
Class SampleClass
' Method that matches the SampleDelegate signature.
Sub SampleSub(ByVal str As String)
' Add code here.
End Sub
' Method that instantiates the delegate.
Sub SampleDelegateSub()
Dim sd As SampleDelegate = AddressOf SampleSub
sd("Sample string")
End Sub
End Class
See also
Visual Basic Programming Guide
Reflection (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
Reflection provides objects (of type Type) that describe assemblies, modules and types. You can use reflection to
dynamically create an instance of a type, bind the type to an existing object, or get the type from an existing object
and invoke its methods or access its fields and properties. If you are using attributes in your code, reflection
enables you to access them. For more information, see Attributes.
Here's a simple example of reflection using the static method GetType - inherited by all types from the Object
base class - to obtain the type of a variable:
The following example uses reflection to obtain the full name of the loaded assembly.
Reflection Overview
Reflection is useful in the following situations:
When you have to access attributes in your program's metadata. For more information, see Retrieving
Information Stored in Attributes.
For examining and instantiating types in an assembly.
For building new types at runtime. Use classes in System.Reflection.Emit.
For performing late binding, accessing methods on types created at run time. See the topic Dynamically
Loading and Using Types.
Related Sections
For more information:
Reflection
Viewing Type Information
Reflection and Generic Types
System.Reflection.Emit
Retrieving Information Stored in Attributes
See Also
Visual Basic Programming Guide
Assemblies in the Common Language Runtime
Serialization (Visual Basic)
7/29/2017 • 3 min to read • Edit Online
Serialization is the process of converting an object into a stream of bytes in order to store the object or transmit it
to memory, a database, or a file. Its main purpose is to save the state of an object in order to be able to recreate it
when needed. The reverse process is called deserialization.
The object is serialized to a stream, which carries not just the data, but information about the object's type, such as
its version, culture, and assembly name. From that stream, it can be stored in a database, a file, or memory.
Uses for Serialization
Serialization allows the developer to save the state of an object and recreate it as needed, providing storage of
objects as well as data exchange. Through serialization, a developer can perform actions like sending the object to a
remote application by means of a Web Service, passing an object from one domain to another, passing an object
through a firewall as an XML string, or maintaining security or user-specific information across applications.
Making an Object Serializable
To serialize an object, you need the object to be serialized, a stream to contain the serialized object, and a
Formatter. System.Runtime.Serialization contains the classes necessary for serializing and deserializing objects.
Apply the SerializableAttribute attribute to a type to indicate that instances of this type can be serialized. A
SerializationException exception is thrown if you attempt to serialize but the type does not have the
SerializableAttribute attribute.
If you do not want a field within your class to be serializable, apply the NonSerializedAttribute attribute. If a field of
a serializable type contains a pointer, a handle, or some other data structure that is specific to a particular
environment, and the field cannot be meaningfully reconstituted in a different environment, then you may want to
make it nonserializable.
If a serialized class contains references to objects of other classes that are marked SerializableAttribute, those
objects will also be serialized.
Designer Serialization
Designer serialization is a special form of serialization that involves the kind of object persistence usually
associated with development tools. Designer serialization is the process of converting an object graph into a source
file that can later be used to recover the object graph. A source file can contain code, markup, or even SQL table
information.
Threading enables your Visual Basic program to perform concurrent processing so that you can do more than one
operation at a time. For example, you can use threading to monitor input from the user, perform background tasks,
and handle simultaneous streams of input.
Threads have the following properties:
Threads enable your program to perform concurrent processing.
The .NET Framework System.Threading namespace makes using threads easier.
Threads share the application's resources. For more information, see Using Threads and Threading.
By default, a Visual Basic program has one thread. However, auxiliary threads can be created and used to execute
code in parallel with the primary thread. These threads are often called worker threads.
Worker threads can be used to perform time-consuming or time-critical tasks without tying up the primary thread.
For example, worker threads are often used in server applications to fulfill incoming requests without waiting for
the previous request to be completed. Worker threads are also used to perform "background" tasks in desktop
applications so that the main thread--which drives user interface elements--remains responsive to user actions.
Threading solves problems with throughput and responsiveness, but it can also introduce resource-sharing issues
such as deadlocks and race conditions. Multiple threads are best for tasks that require different resources such as
file handles and network connections. Assigning multiple threads to a single resource is likely to cause
synchronization issues, and having threads frequently blocked when waiting for other threads defeats the purpose
of using multiple threads.
A common strategy is to use worker threads to perform time-consuming or time-critical tasks that do not require
many of the resources used by other threads. Naturally, some resources in your program must be accessed by
multiple threads. For these cases, the System.Threading namespace provides classes for synchronizing threads.
These classes include Mutex, Monitor, Interlocked, AutoResetEvent, and ManualResetEvent.
You can use some or all these classes to synchronize the activities of multiple threads, but some support for
threading is supported by the Visual Basic language. For example, the SyncLock Statement provides
synchronization features through implicit use of Monitor.
NOTE
Beginning 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.
Related Topics
TITLE DESCRIPTION
Multithreaded Applications (Visual Basic) Describes how to create and use threads.
TITLE DESCRIPTION
Parameters and Return Values for Multithreaded Procedures Describes how to pass and return parameters with
(Visual Basic) multithreaded applications.
Walkthrough: Multithreading with the BackgroundWorker Shows how to create a simple multithreaded application.
Component (Visual Basic)
Thread Synchronization (Visual Basic) Describes how to control the interactions of threads.
Thread Timers (Visual Basic) Describes how to run procedures on separate threads at fixed
intervals.
Thread Pooling (Visual Basic) Describes how to use a pool of worker threads that are
managed by the system.
How to: Use a Thread Pool (Visual Basic) Demonstrates synchronized use of multiple threads in the
thread pool.
This section introduces the typical Visual Basic program structure, provides a simple Visual Basic program, "Hello,
World", and discusses Visual Basic code conventions. Code conventions are suggestions that focus not on a
program's logic but on its physical structure and appearance. Following them makes your code easier to read,
understand, and maintain. Code conventions can include, among others:
Standardized formats for labeling and commenting code.
Guidelines for spacing, formatting, and indenting code.
Naming conventions for objects, variables, and procedures.
The following topics present a set of programming guidelines for Visual Basic programs, along with examples of
good usage.
In This Section
Structure of a Visual Basic Program
Provides an overview of the elements that make up a Visual Basic program.
Main Procedure in Visual Basic
Discusses the procedure that serves as the starting point and overall control for your application.
References and the Imports Statement
Discusses how to reference objects in other assemblies.
Namespaces in Visual Basic
Describes how namespaces organize objects within assemblies.
Visual Basic Naming Conventions
Includes general guidelines for naming procedures, constants, variables, arguments, and objects.
Visual Basic Coding Conventions
Reviews the guidelines used in developing the samples in this documentation.
Conditional Compilation
Describes how to compile particular blocks of code selectively while directing the compiler to ignore others.
How to: Break and Combine Statements in Code
Shows how to divide long statements into multiple lines and combine short statements on one line.
How to: Collapse and Hide Sections of Code
Shows how to collapse and hide sections of code in the Visual Basic code editor.
How to: Label Statements
Shows how to mark a line of code to identify it for use with statements such as On Error Goto .
Special Characters in Code
Shows how and where to use non-numeric and non-alphabetic characters.
Comments in Code
Discusses how to add descriptive comments to your code.
Keywords as Element Names in Code
Describes how to use brackets ( [] ) to delimit variable names that are also Visual Basic keywords.
Me, My, MyBase, and MyClass
Describes various ways to refer to elements of a Visual Basic program.
Visual Basic Limitations
Discusses the removal of known coding limits within Visual Basic.
Related Sections
Typographic and Code Conventions
Provides standard coding conventions for Visual Basic.
Writing Code
Describes features that make it easier for you to write and manage your code.
Structure of a Visual Basic Program
7/29/2017 • 3 min to read • Edit Online
A Visual Basic program is built up from standard building blocks. A solution comprises one or more projects. A
project in turn can contain one or more assemblies. Each assembly is compiled from one or more source files. A
source file provides the definition and implementation of classes, structures, modules, and interfaces, which
ultimately contain all your code.
For more information about these building blocks of a Visual Basic program, see Solutions and Projects and
Assemblies and the Global Assembly Cache.
The most common variety of this procedure is Sub Main() . For more information, see Main Procedure in Visual
Basic.
See Also
Main Procedure in Visual Basic
Visual Basic Naming Conventions
Visual Basic Limitations
Main Procedure in Visual Basic
7/29/2017 • 3 min to read • Edit Online
Every Visual Basic application must contain a procedure called Main . This procedure serves as the starting point
and overall control for your application. The .NET Framework calls your Main procedure when it has loaded your
application and is ready to pass control to it. Unless you are creating a Windows Forms application, you must
write the Main procedure for applications that run on their own.
Main contains the code that runs first. In Main , you can determine which form is to be loaded first when the
program starts, find out if a copy of your application is already running on the system, establish a set of variables
for your application, or open a database that the application requires.
NOTE
If you declare Main in a class, you must use the Shared keyword. In a module, Main does not need to be Shared .
The simplest way is to declare a Sub procedure that does not take arguments or return a value.
Module mainModule
Sub Main()
MsgBox("The Main procedure is starting the application.")
' Insert call to appropriate starting place in your code.
MsgBox("The application is terminating.")
End Sub
End Module
Main can also return an Integer value, which the operating system uses as the exit code for your
program. Other programs can test this code by examining the Windows ERRORLEVEL value. To return an
exit code, you must declare Main as a Function procedure instead of a Sub procedure.
Module mainModule
Function Main() As Integer
MsgBox("The Main procedure is starting the application.")
Dim returnValue As Integer = 0
' Insert call to appropriate starting place in your code.
' On return, assign appropriate value to returnValue.
' 0 usually means successful completion.
MsgBox("The application is terminating with error level " &
CStr(returnValue) & ".")
Return returnValue
End Function
End Module
Main can also take a String array as an argument. Each string in the array contains one of the command-
line arguments used to invoke your program. You can take different actions depending on their values.
Module mainModule
Function Main(ByVal cmdArgs() As String) As Integer
MsgBox("The Main procedure is starting the application.")
Dim returnValue As Integer = 0
' See if there are any arguments.
If cmdArgs.Length > 0 Then
For argNum As Integer = 0 To UBound(cmdArgs, 1)
' Insert code to examine cmdArgs(argNum) and take
' appropriate action based on its value.
Next argNum
End If
' Insert call to appropriate starting place in your code.
' On return, assign appropriate value to returnValue.
' 0 usually means successful completion.
MsgBox("The application is terminating with error level " &
CStr(returnValue) & ".")
Return returnValue
End Function
End Module
You can declare Main to examine the command-line arguments but not return an exit code, as follows.
Module mainModule
Sub Main(ByVal cmdArgs() As String)
MsgBox("The Main procedure is starting the application.")
Dim returnValue As Integer = 0
' See if there are any arguments.
If cmdArgs.Length > 0 Then
For argNum As Integer = 0 To UBound(cmdArgs, 1)
' Insert code to examine cmdArgs(argNum) and take
' appropriate action based on its value.
Next argNum
End If
' Insert call to appropriate starting place in your code.
MsgBox("The application is terminating.")
End Sub
End Module
See Also
MsgBox
Length
UBound
Structure of a Visual Basic Program
NIB: Visual Basic Version of Hello, World
/main
Shared
Sub Statement
Function Statement
Integer Data Type
String Data Type
References and the Imports Statement (Visual Basic)
7/29/2017 • 2 min to read • Edit Online
You can make external objects available to your project by choosing the Add Reference command on the Project
menu. References in Visual Basic can point to assemblies, which are like type libraries but contain more
information.
Aliasname refers to a short name you can use within code to refer to an imported namespace. Namespace is a
namespace available through either a project reference, through a definition within the project, or through a
previous Imports statement.
A module may contain any number of Imports statements. They must appear after any Option statements, if
present, but before any other code.
NOTE
Do not confuse project references with the Imports statement or the Declare statement. Project references make
external objects, such as objects in assemblies, available to Visual Basic projects. The Imports statement is used to simplify
access to project references, but does not provide access to these objects. The Declare statement is used to declare a
reference to an external procedure in a dynamic-link library (DLL).
Imports statements must always be the first lines immediately following any Option statements in a module. The
following code fragment shows how to import and assign an alias to the Microsoft.VisualBasic.ControlChars
module:
If an Imports statement does not include an alias name, elements defined within the imported namespace can be
used in the module without qualification. If the alias name is specified, it must be used as a qualifier for names
contained within that namespace.
See Also
ControlChars
Microsoft.VisualBasic
NIB How to: Add or Remove References By Using the Add Reference Dialog Box
Namespaces in Visual Basic
Assemblies and the Global Assembly Cache
How to: Create and Use Assemblies Using the Command Line
Imports Statement (.NET Namespace and Type)
Namespaces in Visual Basic
7/29/2017 • 5 min to read • Edit Online
Namespaces organize the objects defined in an assembly. Assemblies can contain multiple namespaces, which
can in turn contain other namespaces. Namespaces prevent ambiguity and simplify references when using large
groups of objects such as class libraries.
For example, the .NET Framework defines the ListBox class in the System.Windows.Forms namespace. The
following code fragment shows how to declare a variable using the fully qualified name for this class:
The following illustration shows two namespace hierarchies, both containing an object named ListBox .
By default, every executable file you create with Visual Basic contains a namespace with the same name as your
project. For example, if you define an object within a project named ListBoxProject , the executable file
ListBoxProject.exe contains a namespace called ListBoxProject .
Multiple assemblies can use the same namespace. Visual Basic treats them as a single set of names. For example,
you can define classes for a namespace called SomeNameSpace in an assembly named Assemb1 , and define
additional classes for the same namespace from an assembly named Assemb2 .
Fully qualified names prevent naming conflicts because they make it possible for the compiler to determine
which object is being used. However, the names themselves can get long and cumbersome. To get around this,
you can use the Imports statement to define an alias—an abbreviated name you can use in place of a fully
qualified name. For example, the following code example creates aliases for two fully qualified names, and uses
these aliases to define two objects.
If you use the Imports statement without an alias, you can use all the names in that namespace without
qualification, provided they are unique to the project. If your project contains Imports statements for
namespaces that contain items with the same name, you must fully qualify that name when you use it. Suppose,
for example, your project contained the following two Imports statements:
If you attempt to use Class1 without fully qualifying it, Visual Basic produces an error stating that the name
Class1 is ambiguous.
Namespace SpecialSpace
Namespace System
Class abc
Function getValue() As System.Int32
Dim n As System.Int32
Return n
End Function
End Class
End Namespace
End Namespace
As a result, the Visual Basic compiler cannot successfully resolve the reference to System.Int32, because
SpecialSpace.System does not define Int32 . You can use the Global keyword to start the qualification chain at
the outermost level of the .NET Framework class library. This allows you to specify the System namespace or any
other namespace in the class library. The following example illustrates this.
Namespace SpecialSpace
Namespace System
Class abc
Function getValue() As Global.System.Int32
Dim n As Global.System.Int32
Return n
End Function
End Class
End Namespace
End Namespace
You can use Global to access other root-level namespaces, such as Microsoft.VisualBasic, and any namespace
associated with your project.
The following examples use the Global keyword to declare a namespace out of the root namespace for the
project.
Namespace Global.Magnetosphere
End Namespace
Namespace Global
Namespace Magnetosphere
End Namespace
End Namespace
The following example has the Global keyword in the System.Text namespace declaration.
If the Global keyword was not present in the namespace declaration, StringBuilder could not be accessed
without specifying Global.System.Text.StringBuilder . For a project named ConsoleApplication1 , references to
System.Text would access ConsoleApplication1.System.Text if the Global keyword was not used.
Module Module1
Sub Main()
Dim encoding As New System.Text.TitanEncoding
Namespace Global.System.Text
Class TitanEncoding
End Class
End Namespace
See Also
ListBox
System.Windows.Forms
Assemblies and the Global Assembly Cache
How to: Create and Use Assemblies Using the Command Line
References and the Imports Statement
Imports Statement (.NET Namespace and Type)
Writing Code in Office Solutions
Visual Basic Naming Conventions
7/29/2017 • 1 min to read • Edit Online
When you name an element in your Visual Basic application, the first character of that name must be an
alphabetic character or an underscore. Note, however, that names beginning with an underscore are not
compliant with the Language Independence and Language-Independent Components (CLS).
The following suggestions apply to naming.
Begin each separate word in a name with a capital letter, as in FindLastRecord and RedrawMyForm .
Begin function and method names with a verb, as in InitNameArray or CloseDialog .
Begin class, structure, module, and property names with a noun, as in EmployeeName or CarAccessory .
Begin interface names with the prefix "I", followed by a noun or a noun phrase, like IComponent , or with an
adjective describing the interface's behavior, like IPersistable . Do not use the underscore, and use
abbreviations sparingly, because abbreviations can cause confusion.
Begin event handler names with a noun describing the type of event followed by the " EventHandler " suffix,
as in " MouseEventHandler ".
In names of event argument classes, include the " EventArgs " suffix.
If an event has a concept of "before" or "after," use a suffix in present or past tense, as in " ControlAdd " or "
ControlAdded ".
For long or frequently used terms, use abbreviations to keep name lengths reasonable, for example,
"HTML", instead of "Hypertext Markup Language". In general, variable names greater than 32 characters
are difficult to read on a monitor set to a low resolution. Also, make sure your abbreviations are consistent
throughout the entire application. Randomly switching in a project between "HTML" and "Hypertext
Markup Language" can lead to confusion.
Avoid using names in an inner scope that are the same as names in an outer scope. Errors can result if the
wrong variable is accessed. If a conflict occurs between a variable and the keyword of the same name, you
must identify the keyword by preceding it with the appropriate type library. For example, if you have a
variable called Date , you can use the intrinsic Date function only by calling System.DateTime.Date.
See Also
Keywords as Element Names in Code
Me, My, MyBase, and MyClass
Declared Element Names
Program Structure and Code Conventions
Visual Basic Language Reference
Visual Basic Coding Conventions
7/29/2017 • 6 min to read • Edit Online
Microsoft develops samples and documentation that follow the guidelines in this topic. If you follow the same
coding conventions, you may gain the following benefits:
Your code will have a consistent look, so that readers can better focus on content, not layout.
Readers understand your code more quickly because they can make assumptions based on previous
experience.
You can copy, change, and maintain the code more easily.
You help ensure that your code demonstrates "best practices" for Visual Basic.
Naming Conventions
For information about naming guidelines, see Naming Guidelines topic.
Do not use "My" or "my" as part of a variable name. This practice creates confusion with the My objects.
You do not have to change the names of objects in auto-generated code to make them fit the guidelines.
Layout Conventions
Insert tabs as spaces, and use smart indenting with four-space indents.
Use Pretty listing (reformatting) of code to reformat your code in the code editor. For more information,
see Options, Text Editor, Basic (Visual Basic).
Use only one statement per line. Don't use the Visual Basic line separator character (:).
Avoid using the explicit line continuation character "_" in favor of implicit line continuation wherever the
language allows it.
Use only one declaration per line.
If Pretty listing (reformatting) of code doesn't format continuation lines automatically, manually indent
continuation lines one tab stop. However, always left-align items in a list.
a As Integer,
b As Integer
Add at least one blank line between method and property definitions.
Commenting Conventions
Put comments on a separate line instead of at the end of a line of code.
Start comment text with an uppercase letter, and end comment text with a period.
Insert one space between the comment delimiter (') and the comment text.
Program Structure
When you use the Main method, use the default construct for new console applications, and use My for
command-line arguments.
Sub Main()
For Each argument As String In My.Application.CommandLineArgs
' Add code here to use the string variable.
Next
End Sub
Language Guidelines
String Data Type
To concatenate strings, use an ampersand (&).
Put the array designator on the type, not on the variable. For example, use the following syntax:
Use the { } syntax when you declare and initialize arrays of basic data types. For example, use the following
syntax:
With orderLog
.Log = "Application"
.Source = "Application Name"
.MachineName = "Computer Name"
End With
Use the Try...Catch and Using Statements when you use Exception Handling
Do not use On Error Goto .
Use the IsNot Keyword
Use the IsNot keyword instead of Not...Is Nothing .
New Keyword
Use short instantiation. For example, use the following syntax:
Use object initializers for new objects instead of the parameterless constructor:
Event Handling
Use Handles rather than AddHandler :
Private Sub ToolStripMenuItem1_Click() Handles ToolStripMenuItem1.Click
End Sub
When you define an event, use the short syntax, and let the compiler define the delegate:
Do not verify whether an event is Nothing (null) before you call the RaiseEvent method. RaiseEvent
checks for Nothing before it raises the event.
Using Shared Members
Call Shared members by using the class name, not from an instance variable.
Use XML Literals
XML literals simplify the most common tasks that you encounter when you work with XML (for example, load,
query, and transform). When you develop with XML, follow these guidelines:
Use XML literals to create XML documents and fragments instead of calling XML APIs directly.
Import XML namespaces at the file or project level to take advantage of the performance optimizations for
XML literals.
Use the XML axis properties to access elements and attributes in an XML document.
Use embedded expressions to include values and to create XML from existing values instead of using API
calls such as the Add method:
Return htmlDoc.ToString()
End Function
LINQ Queries
Use meaningful names for query variables:
Provide names for elements in a query to make sure that property names of anonymous types are correctly
capitalized using Pascal casing:
Rename properties when the property names in the result would be ambiguous. For example, if your query
returns a customer name and an order ID, rename them instead of leaving them as Name and ID in the
result:
Use type inference in the declaration of query variables and range variables:
Use Where clauses before other query clauses so that later query clauses operate on the filtered set of data:
Use the Join clause to explicitly define a join operation instead of using the Where clause to implicitly
define a join operation:
See Also
Secure Coding Guidelines
Conditional Compilation in Visual Basic
7/29/2017 • 2 min to read • Edit Online
In conditional compilation, particular blocks of code in a program are compiled selectively while others are
ignored.
For example, you may want to write debugging statements that compare the speed of different approaches to
the same programming task, or you may want to localize an application for multiple languages. Conditional
compilation statements are designed to run during compile time, not at run time.
You denote blocks of code to be conditionally compiled with the #If...Then...#Else directive. For example, to
create French- and German-language versions of the same application from the same source code, you embed
platform-specific code segments in #If...Then statements using the predefined constants FrenchVersion and
GermanVersion . The following example demonstrates how:
If you set the value of the FrenchVersion conditional compilation constant to True at compile time, the
conditional code for the French version is compiled. If you set the value of the GermanVersion constant to True ,
the compiler uses the German version. If neither is set to True , the code in the last Else block runs.
NOTE
Autocompletion will not function when editing code and using conditional compilation directives if the code is not part of
the current branch.
- Before creating your executable file, set constants in the Project Designer by following the steps provided in Managing
Project and Solution Properties.
- Use the /d switch to enter conditional compilation constants, as in the following example:
vbc MyProj.vb /d:conFrenchVersion=–1:conANSI=0
No space is required between the /d switch and the first constant. For more information, see /define (Visual Basic).
Command-line declarations override declarations entered in the Project Designer, but do not erase them. Arguments set in
Project Designer remain in effect for subsequent compilations.
When writing constants in the code itself, there are no strict rules as to their placement, since their scope is the entire module
in which they are declared.
- Place the constants in the declaration block of the module in which they are used. This helps keep your code organized and
easier to read.
Related Topics
TITLE DESCRIPTION
Program Structure and Code Conventions Provides suggestions for making your code easy to read and
maintain.
Reference
#Const Directive
#If...Then...#Else Directives
/define (Visual Basic)
How to: Break and Combine Statements in Code
(Visual Basic)
7/29/2017 • 1 min to read • Edit Online
When writing your code, you might at times create lengthy statements that necessitate horizontal scrolling in the
Code Editor. Although this doesn't affect the way your code runs, it makes it difficult for you or anyone else to
read the code as it appears on the monitor. In such cases, you should consider breaking the single long statement
into several lines.
To break a single statement into multiple lines
Use the line-continuation character, which is an underscore ( _ ), at the point at which you want the line to
break. The underscore must be immediately preceded by a space and immediately followed by a line
terminator (carriage return).
NOTE
In some cases, if you omit the line-continuation character, the Visual Basic compiler will implicitly continue the
statement on the next line of code. For a list of syntax elements for which you can omit the line-continuation
character, see "Implicit Line Continuation" in Statements.
In the following example, the statement is broken into four lines with line-continuation characters
terminating all but the last line.
cmd.CommandText = _
"SELECT * FROM Titles JOIN Publishers " _
& "ON Publishers.PubId = Titles.PubID " _
& "WHERE Publishers.State = 'CA'"
Using this sequence makes your code easier to read, both online and when printed.
The line-continuation character must be the last character on a line. You can't follow it with anything else
on the same line.
Some limitations exist as to where you can use the line-continuation character; for example, you can't use it
in the middle of an argument name. You can break an argument list with the line-continuation character,
but the individual names of the arguments must remain intact.
You can't continue a comment by using a line-continuation character. The compiler doesn't examine the
characters in a comment for special meaning. For a multiple-line comment, repeat the comment symbol (
' ) on each line.
Although placing each statement on a separate line is the recommended method, Visual Basic also allows you to
place multiple statements on the same line.
To place multiple statements on the same line
Separate the statements with a colon ( : ), as in the following example.
The #Region directive enables you to collapse and hide sections of code in Visual Basic files. The #Region directive
lets you specify a block of code that you can expand or collapse when using the Visual Studio code editor. The
ability to hide code selectively makes your files more manageable and easier to read. For more information, see
Outlining.
#Region directives support code block semantics such as #If...#End If . This means they cannot begin in one
block and end in another; the start and end must be in the same block. #Region directives are not supported within
functions.
To collapse and hide a section of code
Place the section of code between the #Region and #End Region statements, as in the following example:
The #Region block can be used multiple times in a code file; thus, users can define their own blocks of
procedures and classes that can, in turn, be collapsed. #Region blocks can also be nested within other
#Region blocks.
NOTE
Hiding code does not prevent it from being compiled and does not affect #If...#End If statements.
See Also
Conditional Compilation
#Region Directive
#If...Then...#Else Directives
Outlining
How to: Label Statements (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
Statement blocks are made up of lines of code delimited by colons. Lines of code preceded by an identifying string
or integer are said to be labeled. Statement labels are used to mark a line of code to identify it for use with
statements such as On Error Goto .
Labels may be either valid Visual Basic identifiers—such as those that identify programming elements—or integer
literals. A label must appear at the beginning of a line of source code and must be followed by a colon, regardless
of whether it is followed by a statement on the same line.
The compiler identifies labels by checking whether the beginning of the line matches any already-defined
identifier. If it does not, the compiler assumes it is a label.
Labels have their own declaration space and do not interfere with other identifiers. A label's scope is the body of
the method. Label declaration takes precedence in any ambiguous situation.
NOTE
Labels can be used only on executable statements inside methods.
See Also
Statements
Declared Element Names
Program Structure and Code Conventions
Special Characters in Code (Visual Basic)
7/29/2017 • 3 min to read • Edit Online
Sometimes you have to use special characters in your code, that is, characters that are not alphabetical or numeric.
The punctuation and special characters in the Visual Basic character set have various uses, from organizing
program text to defining the tasks that the compiler or the compiled program performs. They do not specify an
operation to be performed.
Parentheses
Use parentheses when you define a procedure, such as a Sub or Function . You must enclose all procedure
argument lists in parentheses. You also use parentheses for putting variables or arguments into logical groups,
especially to override the default order of operator precedence in a complex expression. The following example
illustrates this.
Dim a, b, c, d, e As Double
a = 3.2
b = 7.6
c = 2
d = b + c / a
e = (b + c) / a
Following execution of the previous code, the value of d is 8.225 and the value of e is 3. The calculation for d
uses the default precedence of / over + and is equivalent to d = b + (c / a) . The parentheses in the calculation
for e override the default precedence.
Separators
Separators do what their name suggests: they separate sections of code. In Visual Basic, the separator character is
the colon ( : ). Use separators when you want to include multiple statements on a single line instead of separate
lines. This saves space and improves the readability of your code. The following example shows three statements
separated by colons.
a = 3.2 : b = 7.6 : c = 2
For more information, see How to: Break and Combine Statements in Code.
The colon ( : ) character is also used to identify a statement label. For more information, see How to: Label
Statements.
Concatenation
Use the & operator for concatenation, or linking strings together. Do not confuse it with the + operator, which
adds together numeric values. If you use the + operator to concatenate when you operate on numeric values, you
can obtain incorrect results. The following example demonstrates this.
var1 = "10.01"
var2 = 11
resultA = var1 + var2
resultB = var1 & var2
Following execution of the previous code, the value of resultA is 21.01 and the value of resultB is "10.0111".
The three output lines of MsgBox all display the value 32856 . The first line uses the traditional access to property
index , the second makes use of the fact that index is the default property of class hasDefault , and the third uses
dictionary access to the class.
Note that the second operand of the ! operator must be a valid Visual Basic identifier not enclosed in double
quotation marks ( " " ). In other words, you cannot use a string literal or string variable. The following change to
the last line of the MsgBox call generates an error because "X" is an enclosed string literal.
"Dictionary access returns " & hD!"X")
NOTE
References to default collections must be explicit. In particular, you cannot use the ! operator on a late-bound variable.
See Also
Program Structure and Code Conventions
Type Characters
Comments in Code (Visual Basic)
7/29/2017 • 2 min to read • Edit Online
As you read the code examples, you often encounter the comment symbol ( ' ). This symbol tells the Visual Basic
compiler to ignore the text following it, or the comment. Comments are brief explanatory notes added to code for
the benefit of those reading it.
It is good programming practice to begin all procedures with a brief comment describing the functional
characteristics of the procedure (what it does). This is for your own benefit and the benefit of anyone else who
examines the code. You should separate the implementation details (how the procedure does it) from comments
that describe the functional characteristics. When you include implementation details in the description, remember
to update them when you update the function.
Comments can follow a statement on the same line, or occupy an entire line. Both are illustrated in the following
code.
If your comment requires more than one line, use the comment symbol on each line, as the following example
illustrates.
Commenting Guidelines
The following table provides general guidelines for what types of comments can precede a section of code. These
are suggestions; Visual Basic does not enforce rules for adding comments. Write what works best, both for you and
for anyone else who reads your code.
Purpose Describes what the procedure does (not how it does it)
Assumptions Lists each external variable, control, open file, or other element
accessed by the procedure
Effects Lists each affected external variable, control, or file, and the
effect it has (only if it is not obvious)
NOTE
You can also add comments to your code by preceding the text with the REM keyword. However, the ' symbol and the
Comment/Uncomment buttons are easier to use and require less space and memory.
See Also
Documenting Your Code With XML Comments
How to: Create XML Documentation
XML Comment Tags
Program Structure and Code Conventions
REM Statement
Keywords as Element Names in Code (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
Any program element — such as a variable, class, or member — can have the same name as a restricted keyword.
For example, you can create a variable named Loop . However, to refer to your version of it — which has the same
name as the restricted Loop keyword — you must either precede it with a full qualification string or enclose it in
square brackets ( [ ] ), as the following example shows.
' The following statement precedes Loop with a full qualification string.
sampleForm.Loop.Visible = True
' The following statement encloses Loop in square brackets.
[Loop].Visible = True
If you do not do either of these, then Visual Basic assumes use of the intrinsic Loop keyword and produces an
error, as in the following example:
' The following statement causes a compiler error.
Loop.Visible = True
You can use square brackets when referring to forms and controls, and when declaring a variable or defining a
procedure with the same name as a restricted keyword. It can be easy to forget to qualify names or include square
brackets, and thus introduce errors into your code and make it harder to read. For this reason, we recommend that
you not use restricted keywords as the names of program elements. However, if a future version of Visual Basic
defines a new keyword that conflicts with an existing form or control name, then you can use this technique when
updating your code to work with the new version.
NOTE
Your program also might include element names provided by other referenced assemblies. If these names conflict with
restricted keywords, then placing square brackets around them causes Visual Basic to interpret them as your defined
elements.
See Also
Visual Basic Naming Conventions
Program Structure and Code Conventions
Keywords
Me, My, MyBase, and MyClass in Visual Basic
7/29/2017 • 1 min to read • Edit Online
Me , My , MyBase , and MyClass in Visual Basic have similar names, but different purposes. This topic describes
each of these entities in order to distinguish them.
Me
The Me keyword provides a way to refer to the specific instance of a class or structure in which the code is
currently executing. Me behaves like either an object variable or a structure variable referring to the current
instance. Using Me is particularly useful for passing information about the currently executing instance of a class
or structure to a procedure in another class, structure, or module.
For example, suppose you have the following procedure in a module.
You can call this procedure and pass the current instance of the Form class as an argument by using the following
statement.
ChangeFormColor(Me)
My
The My feature provides easy and intuitive access to a number of .NET Framework classes, enabling the Visual
Basic user to interact with the computer, application, settings, resources, and so on.
MyBase
The MyBasekeyword behaves like an object variable referring to the base class of the current instance of a class.
MyBase is commonly used to access base class members that are overridden or shadowed in a derived class.
MyBase.New is used to explicitly call a base class constructor from a derived class constructor.
MyClass
The MyClass keyword behaves like an object variable referring to the current instance of a class as originally
implemented. MyClass is similar to Me , but all method calls on it are treated as if the method were
NotOverridable .
See Also
Inheritance Basics
Visual Basic Limitations
7/29/2017 • 1 min to read • Edit Online
Earlier versions of Visual Basic enforced boundaries in code, such as the length of variable names, the number of
variables allowed in modules, and module size. In Visual Basic .NET, these restrictions have been relaxed, giving
you greater freedom in writing and arranging your code.
Physical limits are dependent more on run-time memory than on compile-time considerations. If you use prudent
programming practices, and divide large applications into multiple classes and modules, then there is very little
chance of encountering an internal Visual Basic limitation.
The following are some limitations that you might encounter in extreme cases:
Name Length. There is a maximum number of characters for the name of every declared programming
element. This maximum applies to an entire qualification string if the element name is qualified. See
Declared Element Names.
Line Length. There is a maximum of 65535 characters in a physical line of source code. The logical source
code line can be longer if you use line continuation characters. See How to: Break and Combine Statements
in Code.
Array Dimensions. There is a maximum number of dimensions you can declare for an array. This limits
how many indexes you can use to specify an array element. See Array Dimensions in Visual Basic.
String Length. There is a maximum number of Unicode characters you can store in a single string. See
String Data Type.
Environment String Length. There is a maximum of 32768 characters for any environment string used as
a command-line argument. This is a limitation on all platforms.
See Also
Program Structure and Code Conventions
Visual Basic Naming Conventions
Visual Basic Language Features
7/29/2017 • 2 min to read • Edit Online
The following topics introduce and discuss the essential components of Visual Basic, an object-oriented
programming language. After creating the user interface for your application using forms and controls, you need
to write the code that defines the application's behavior. As with any modern programming language, Visual Basic
supports a number of common programming constructs and language elements.
If you have programmed in other languages, much of the material covered in this section might seem familiar.
While most of the constructs are similar to those in other languages, the event-driven nature of Visual Basic
introduces some subtle differences.
If you are new to programming, the material in this section serves as an introduction to the basic building blocks
for writing code. Once you understand the basics, you can create powerful applications using Visual Basic.
In This Section
Arrays
Discusses making your code more compact and powerful by declaring and using arrays, which hold multiple
related values.
Collection Initializers
Describes collection initializers, which enable you to create a collection and populate it with an initial set of values.
Constants and Enumerations
Discusses storing unchanging values for repeated use, including sets of related constant values.
Control Flow
Shows how to regulate the flow of your program's execution.
Data Types
Describes what kinds of data a programming element can hold and how that data is stored.
Declared Elements
Covers programming elements you can declare, their names and characteristics, and how the compiler resolves
references to them.
Delegates
Provides an introduction to delegates and how they are used in Visual Basic.
Early and Late Binding
Describes binding, which is performed by the compiler when an object is assigned to an object variable, and the
differences between early-bound and late-bound objects.
Error Types
Provides an overview of syntax errors, run-time errors, and logic errors.
Events
Shows how to declare and use events.
Interfaces
Describes what interfaces are and how you can use them in your applications.
LINQ
Provides links to topics that introduce Language-Integrated Query (LINQ) features and programming.
Objects and Classes
Provides an overview of objects and classes, how they are used, their relationships to each other, and the
properties, methods, and events they expose.
Operators and Expressions
Describes the code elements that manipulate value-holding elements, how to use them efficiently, and how to
combine them to yield new values.
Procedures
Describes Sub , Function , Property , and Operator procedures, as well as advanced topics such as recursive and
overloaded procedures.
Statements
Describes declaration and executable statements.
Strings
Provides links to topics that describe the basic concepts about using strings in Visual Basic.
Variables
Introduces variables and describes how to use them in Visual Basic.
XML
Provides links to topics that describe how to use XML in Visual Basic.
Related Sections
Collections
Describes some of the types of collections that are provided by the .NET Framework. Demonstrates how to use
simple collections and collections of key/value pairs.
Visual Basic Language Reference
Provides reference information on various aspects of Visual Basic programming.
Arrays in Visual Basic
7/29/2017 • 17 min to read • Edit Online
An array is a set of values that are logically related to each other, such as the number of students in each grade
in a grammar school. If you are looking for help on arrays in Visual Basic for Applications (VBA), see the
language reference.
By using an array, you can refer to these related values by the same name, and use a number that’s called an
index or subscript to tell them apart. The individual values are called the elements of the array. They’re
contiguous from index 0 through the highest index value.
In contrast to an array, a variable that contain a single value is called a scalar variable.
Some quick examples before explanation:
In this topic
Array Elements in a Simple Array
Creating an Array
Storing Values in an Array
Populating an Array with Initial Values
Nested Array Literals
Iterating Through an Array
Arrays as Return Values and Parameters
Jagged Arrays
Zero-Length Arrays
Array Size
Array Types and Other Types
Collections as an Alternative to Arrays
The array students in the preceding example contains seven elements. The indexes of the elements range from
0 through 6. Having this array is simpler than declaring seven variables.
The following illustration shows the array students . For each element of the array:
The index of the element represents the grade (index 0 represents kindergarten).
The value that’s contained in the element represents the number of students in that grade.
You can refer to the array as a whole by using just the array variable name without indexes.
The array students in the preceding example uses one index and is said to be one-dimensional. An array that
uses more than one index or subscript is called multidimensional. For more information, see the rest of this topic
and Array Dimensions in Visual Basic.
Creating an Array
You can define the size of an array several ways. You can supply the size when the array is declared, as the
following example shows.
You can also use a New clause to supply the size of an array when it’s created, as the following example shows.
cargoWeights = New Double(10) {}
atmospherePressures = New Short(2, 2, 4, 10) {}
inquiriesByYearMonthDay = New Byte(20)()() {}
If you have an existing array, you can redefine its size by using the Redim statement. You can specify that the
Redim statement should keep the values that are in the array, or you can specify that it create an empty array.
The following example shows different uses of the Redim statement to modify the size of an existing array.
' Assign a new array size and retain the current element values.
ReDim Preserve cargoWeights(20)
' Assign a new array size and retain only the first five element values.
ReDim Preserve cargoWeights(4)
' Assign a new array size and discard all current element values.
ReDim cargoWeights(15)
Dim i = 4
Dim j = 2
numbers(i + 1) = 0
matrix(3, j * 2) = j
The following example shows some statements that get values from arrays.
Dim v = 2
Dim i = 1
Dim j = 1
Dim k = 1
Dim wTotal As Double = 0.0
Dim sortedValues(5), rawValues(5), estimates(2, 2, 2) As Double
Dim lowestValue = sortedValues(0)
wTotal += (rawValues(v) ^ 2)
Dim firstGuess = estimates(i, j, k)
In the previous example, an error would occur if the number of elements in the nested array literals didn’t match.
An error would also occur if you explicitly declared the array variable to be other than two-dimensional.
NOTE
You can avoid an error when you supply nested array literals of different dimensions by enclosing the inner array literals in
parentheses. The parentheses force the array literal expression to be evaluated, and the resulting values are used with the
outer array literal, as the following code shows.
When you create a multidimensional array by using nested array literals, you can use type inference. When you
use type inference, the inferred type is the dominant type for all the values in all the array literals for a nesting
level. The following code example creates a two-dimensional array of type Double from values that are of type
Integer and Double .
For additional examples, see How to: Initialize an Array Variable in Visual Basic.
The following example iterates through a multidimensional array by using a For...Next statement. The
GetUpperBound method has a parameter that specifies the dimension. GetUpperBound(0) returns the high index
value for the first dimension, and GetUpperBound(1) returns the high index value for the second dimension.
The following example iterates through a one-dimensional array by using a For Each...Next Statement.
The following example iterates through a multidimensional array by using a For Each...Next statement.
However, you have more control over the elements of a multidimensional array if you use a nested For…Next
statement, as in a previous example, instead of a For Each…Next statement.
' Output:
' 10
' 20
' 30
In the following example, the GetNumbersMultiDim function returns an Integer(,) . This array type is a two
dimensional array of type Integer . The ShowNumbersMultiDim procedure accepts an Integer(,) argument.
' Output
' 1 2
' 3 4
' 5 6
Jagged Arrays
Jagged Arrays
An array that holds other arrays as elements is known as an array of arrays or a jagged array. A jagged array and
each element in a jagged array can have one or more dimensions. Sometimes the data structure in your
application is two-dimensional but not rectangular.
The following example has an array of months, each element of which is an array of days. Because different
months have different numbers of days, the elements don’t form a rectangular two-dimensional array.
Therefore, a jagged array is used instead of a multidimensional array.
Zero-Length Arrays
An array that contains no elements is also called a zero-length array. A variable that holds a zero-length array
doesn’t have the value Nothing . To create an array that has no elements, declare one of the array's dimensions
to be -1, as the following example shows.
You might need to create a zero-length array under the following circumstances:
Without risking a NullReferenceException exception, your code must access members of the Array class,
such as Length or Rank, or call a Visual Basic function such as UBound.
You want to keep the consuming code simpler by not having to check for Nothing as a special case.
Your code interacts with an application programming interface (API) that either requires you to pass a
zero-length array to one or more procedures or returns a zero-length array from one or more
procedures.
Array Size
The size of an array is the product of the lengths of all its dimensions. It represents the total number of elements
currently contained in the array.
The following example declares a three-dimensional array.
Dim prices(3, 4, 5) As Long
Size and Element Size An array's size is independent of the data type of its
elements. The size always represents the total number of
elements, not the number of bytes that they consume in
storage.
You can find out the data type of either an array or its elements in several ways.
You can call the System.Object.GetType method on the variable to receive a Type object for the run-time
type of the variable. The Type object holds extensive information in its properties and methods.
You can pass the variable to the TypeName function to receive a String containing the name of run-time
type.
You can pass the variable to the VarType function to receive a VariantType value representing the type
classification of the variable.
The following example calls the TypeName function to determine the type of the array and the type of the
elements in the array. The array type is Integer(,) and the elements in the array are of type Integer .
The declaration of the CustomerFile collection specifies that it can contain elements only of type Customer . It
also provides for an initial capacity of 200 elements. The procedure AddNewCustomer checks the new element for
validity and then adds it to the collection. The procedure PrintCustomers uses a For Each loop to traverse the
collection and display its elements.
Related Topics
TERM DEFINITION
How to: Initialize an Array Variable in Visual Basic Describes how to populate arrays with initial values.
How to: Sort An Array in Visual Basic Shows how to sort the elements of an array alphabetically.
How to: Assign One Array to Another Array Describes the rules and steps for assigning an array to
another array variable.
Troubleshooting Arrays Discusses some common problems that arise when working
with arrays.
See Also
Array
Dim Statement
ReDim Statement
Collection Initializers (Visual Basic)
7/29/2017 • 5 min to read • Edit Online
Collection initializers provide a shortened syntax that enables you to create a collection and populate it with an
initial set of values. Collection initializers are useful when you are creating a collection from a set of known values,
for example, a list of menu options or categories, an initial set of numeric values, a static list of strings such as day
or month names, or geographic locations such as a list of states that is used for validation.
For more information about collections, see Collections.
You identify a collection initializer by using the From keyword followed by braces ( {} ). This is similar to the array
literal syntax that is described in Arrays. The following examples show various ways to use collection initializers to
create collections.
NOTE
C# also provides collection initializers. C# collection initializers provide the same functionality as Visual Basic collection
initializers. For more information about C# collection initializers, see Object and Collection Initializers.
Syntax
A collection initializer consists of a list of comma-separated values that are enclosed in braces ( {} ), preceded by
the From keyword, as shown in the following code.
When you create a collection, such as a List<T> or a Dictionary<TKey,TValue>, you must supply the collection type
before the collection initializer, as shown in the following code.
The following code example shows equivalent code that does not use a collection initializer.
If the collection has an Add method that has parameters that match the constructor for the Customer object, you
could nest parameter values for the Add method within collection initializers, as discussed in the next section. If
the collection does not have such an Add method, you can create one as an extension method. For an example of
how to create an Add method as an extension method for a collection, see How to: Create an Add Extension
Method Used by a Collection Initializer. For an example of how to create a custom collection that can be used with
a collection initializer, see How to: Create a Collection Used by a Collection Initializer.
Only nested value lists from the first level of nesting are sent to the Add method for the collection type. Deeper
levels of nesting are treated as array literals and the nested value lists are not matched to the Add method of any
collection.
Related Topics
TITLE DESCRIPTION
How to: Create an Add Extension Method Used by a Shows how to create an extension method called Add that
Collection Initializer can be used to populate a collection with values from a
collection initializer.
How to: Create a Collection Used by a Collection Initializer Shows how to enable use of a collection initializer by including
an Add method in a collection class that implements
IEnumerable .
See Also
Collections
Arrays
Object Initializers: Named and Anonymous Types
New Operator
Auto-Implemented Properties
How to: Initialize an Array Variable in Visual Basic
Local Type Inference
Anonymous Types
Introduction to LINQ in Visual Basic
How to: Create a List of Items
Constants and Enumerations in Visual Basic
7/29/2017 • 1 min to read • Edit Online
Constants are a way to use meaningful names in place of a value that does not change. Constants store values that,
as the name implies, remain constant throughout the execution of an application. You can use constants to provide
meaningful names, instead of numbers, making your code more readable.
Enumerations provide a convenient way to work with sets of related constants, and to associate constant values
with names. For example, you can declare an enumeration for a set of integer constants associated with the days of
the week, and then use the names of the days rather than their integer values in your code.
In This Section
TERM DEFINITION
Constants Overview Topics in this section describe constants and their uses.
Enumerations Overview Topics in this section describe enumerations and their uses.
Related Sections
TERM DEFINITION
Option Explicit Statement Describes the Option Explicit statement, which is used at
module level to force explicit declaration of all variables in that
module.
Option Infer Statement Describes the Option Infer statement, which enables the
use of local type inference in declaring variables.
Option Strict Statement Describes the Option Strict statement, which restricts
implicit data type conversions to only widening conversions,
disallows late binding, and disallows implicit typing that results
in an Object type.
Control Flow in Visual Basic
7/29/2017 • 1 min to read • Edit Online
Left unregulated, a program proceeds through its statements from beginning to end. Some very simple programs
can be written with only this unidirectional flow. However, much of the power and utility of any programming
language comes from the ability to change execution order with control statements and loops.
Control structures allow you to regulate the flow of your program's execution. Using control structures, you can
write Visual Basic code that makes decisions or that repeats actions. Other control structures let you guarantee
disposal of a resource or run a series of statements on the same object reference.
In This Section
Decision Structures
Describes control structures used for branching.
Loop Structures
Discusses control structures used to repeat processes.
Other Control Structures
Describes control structures used for resource disposal and object access.
Nested Control Structures
Covers control structures inside other control structures.
Related Sections
Control Flow Summary
Provides links to language reference pages on this subject.
Data Types in Visual Basic
7/29/2017 • 1 min to read • Edit Online
The data type of a programming element refers to what kind of data it can hold and how it stores that data. Data
types apply to all values that can be stored in computer memory or participate in the evaluation of an expression.
Every variable, literal, constant, enumeration, property, procedure parameter, procedure argument, and procedure
return value has a data type.
See Also
Type Characters
Elementary Data Types
Composite Data Types
Generic Types in Visual Basic
Value Types and Reference Types
Type Conversions in Visual Basic
Structures
Tuples
Troubleshooting Data Types
Data Types
Efficient Use of Data Types
Declared Elements in Visual Basic
7/29/2017 • 1 min to read • Edit Online
A declared element is a programming element that is defined in a declaration statement. Declared elements
include variables, constants, enumerations, classes, structures, modules, interfaces, procedures, procedure
parameters, function returns, external procedure references, operators, properties, events, and delegates.
Declaration statements include the following:
Dim Statement
Const Statement
Enum Statement
Class Statement
Structure Statement
Module Statement
Interface Statement
Function Statement
Sub Statement
Declare Statement
Operator Statement
Property Statement
Event Statement
Delegate Statement
In This Section
Declared Element Names
Describes how to name elements and use alphabetic case.
Declared Element Characteristics
Covers characteristics, such as scope, possessed by declared elements.
References to Declared Elements
Describes how the compiler matches a reference to a declaration and how to qualify a name.
Related Sections
Program Structure and Code Conventions
Presents guidelines for making your code easier to read, understand, and maintain.
Statements
Describes statements that name and define procedures, variables, arrays, and constants.
Declaration Contexts and Default Access Levels
Lists the types of declared elements and shows for each one its declaration statement, in what context you can
declare it, and its default access level.
Delegates (Visual Basic)
7/29/2017 • 5 min to read • Edit Online
Delegates are objects that refer to methods. They are sometimes described as type-safe function pointers because
they are similar to function pointers used in other programming languages. But unlike function pointers, Visual
Basic delegates are a reference type based on the class System.Delegate. Delegates can reference both shared
methods — methods that can be called without a specific instance of a class — and instance methods.
You can use the shorthand way of creating delegates anywhere the compiler can determine the delegate's type by
the context.
This is useful when you want to route multiple events to the same handler.
The following example shows both AddressOf and lambda expressions used to specify the reference for a
delegate.
Module Module1
Sub Main()
' Create an instance of InOrderClass and assign values to the properties.
' InOrderClass method ShowInOrder displays the numbers in ascending
' or descending order, depending on the comparison method you specify.
Dim inOrder As New InOrderClass
inOrder.Num1 = 5
inOrder.Num2 = 4
' Use AddressOf to send a reference to the comparison function you want
' to use.
inOrder.ShowInOrder(AddressOf GreaterThan)
inOrder.ShowInOrder(AddressOf LessThan)
Class InOrderClass
' Define the delegate function for the comparisons.
Delegate Function CompareNumbers(ByVal num1 As Integer, ByVal num2 As Integer) As Boolean
' Display properties in ascending or descending order.
Sub ShowInOrder(ByVal compare As CompareNumbers)
If compare(_num1, _num2) Then
Console.WriteLine(_num1 & " " & _num2)
Else
Console.WriteLine(_num2 & " " & _num1)
End If
End Sub
The signature of the function must match that of the delegate type. For more information about lambda
expressions, see Lambda Expressions. For more examples of lambda expression and AddressOf assignments to
delegates, see Relaxed Delegate Conversion.
Related Topics
TITLE DESCRIPTION
How to: Invoke a Delegate Method Provides an example that shows how to associate a method
with a delegate and then invoke that method through the
delegate.
How to: Pass Procedures to Another Procedure in Visual Basic Demonstrates how to use delegates to pass one procedure to
another procedure.
Relaxed Delegate Conversion Describes how you can assign subs and functions to
delegates or handlers even when their signatures are not
identical
The Visual Basic compiler performs a process called binding when an object is assigned to an object variable. An
object is early bound when it is assigned to a variable declared to be of a specific object type. Early bound objects
allow the compiler to allocate memory and perform other optimizations before an application executes. For
example, the following code fragment declares a variable to be of type FileStream:
Because FileStream is a specific object type, the instance assigned to FS is early bound.
By contrast, an object is late bound when it is assigned to a variable declared to be of type Object . Objects of this
type can hold references to any object, but lack many of the advantages of early-bound objects. For example, the
following code fragment declares an object variable to hold an object returned by the CreateObject function:
' To use this example, you must have Microsoft Excel installed on your computer.
' Compile with Option Strict Off to allow late binding.
Sub TestLateBinding()
Dim xlApp As Object
Dim xlBook As Object
Dim xlSheet As Object
xlApp = CreateObject("Excel.Application")
' Late bind an instance of an Excel workbook.
xlBook = xlApp.Workbooks.Add
' Late bind an instance of an Excel worksheet.
xlSheet = xlBook.Worksheets(1)
xlSheet.Activate()
' Show the application.
xlSheet.Application.Visible = True
' Place some text in the second row of the sheet.
xlSheet.Cells(2, 2) = "This is column B row 2"
End Sub
NOTE
Late binding can only be used to access type members that are declared as Public . Accessing members declared as
Friend or Protected Friend results in a run-time error.
See Also
CreateObject
Object Lifetime: How Objects Are Created and Destroyed
Object Data Type
Error Types (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
In Visual Basic, errors (also called exceptions) fall into one of three categories: syntax errors, run-time errors, and
logic errors.
Syntax Errors
Syntax errors are those that appear while you write code. Visual Basic checks your code as you type it in the
Code Editor window and alerts you if you make a mistake, such as misspelling a word or using a language
element improperly. Syntax errors are the most common type of errors. You can fix them easily in the coding
environment as soon as they occur.
NOTE
The Option Explicit statement is one means of avoiding syntax errors. It forces you to declare, in advance, all the
variables to be used in the application. Therefore, when those variables are used in the code, any typographic errors are
caught immediately and can be fixed.
Run-Time Errors
Run-time errors are those that appear only after you compile and run your code. These involve code that may
appear to be correct in that it has no syntax errors, but that will not execute. For example, you might correctly
write a line of code to open a file. But if the file is corrupted, the application cannot carry out the Open function,
and it stops running. You can fix most run-time errors by rewriting the faulty code, and then recompiling and
rerunning it.
Logic Errors
Logic errors are those that appear once the application is in use. They are most often unwanted or unexpected
results in response to user actions. For example, a mistyped key or other outside influence might cause your
application to stop working within expected parameters, or altogether. Logic errors are generally the hardest
type to fix, since it is not always clear where they originate.
See Also
Try...Catch...Finally Statement
Debugger Basics
Events (Visual Basic)
7/29/2017 • 6 min to read • Edit Online
While you might visualize a Visual Studio project as a series of procedures that execute in a sequence, in reality,
most programs are event driven—meaning the flow of execution is determined by external occurrences called
events.
An event is a signal that informs an application that something important has occurred. For example, when a user
clicks a control on a form, the form can raise a Click event and call a procedure that handles the event. Events
also allow separate tasks to communicate. Say, for example, that your application performs a sort task separately
from the main application. If a user cancels the sort, your application can send a cancel event instructing the sort
process to stop.
Raising Events
An event is like a message announcing that something important has occurred. The act of broadcasting the
message is called raising the event. In Visual Basic, you raise events with the RaiseEvent statement, as in the
following example:
RaiseEvent AnEvent(EventNumber)
Events must be raised within the scope of the class, module, or structure where they are declared. For example, a
derived class cannot raise events inherited from a base class.
Event Senders
Any object capable of raising an event is an event sender, also known as an event source. Forms, controls, and
user-defined objects are examples of event senders.
Event Handlers
Event handlers are procedures that are called when a corresponding event occurs. You can use any valid
subroutine with a matching signature as an event handler. You cannot use a function as an event handler,
however, because it cannot return a value to the event source.
Visual Basic uses a standard naming convention for event handlers that combines the name of the event sender,
an underscore, and the name of the event. For example, the Click event of a button named button1 would be
named Sub button1_Click .
NOTE
We recommend that you use this naming convention when defining event handlers for your own events, but it is not
required; you can use any valid subroutine name.
Class EventClass
Public Event XEvent()
Public Event YEvent()
' RaiseEvents raises both events.
Sub RaiseEvents()
RaiseEvent XEvent()
RaiseEvent YEvent()
End Sub
End Class
The WithEvents statement and the Handles clause are often the best choice for event handlers because the
declarative syntax they use makes event handling easier to code, read and debug. However, be aware of the
following limitations on the use of WithEvents variables:
You cannot use a WithEvents variable as an object variable. That is, you cannot declare it as Object —you
must specify the class name when you declare the variable.
Because shared eventsare not tied to class instances, you cannot use WithEvents to declaratively handle
shared events. Similarly, you cannot use WithEvents or Handles to handle events from a Structure . In
both cases, you can use the AddHandler statement to handle those events.
You cannot create arrays of WithEvents variables.
WithEvents variables allow a single event handler to handle one or more kind of event, or one or more event
handlers to handle the same kind of event.
Although the Handles clause is the standard way of associating an event with an event handler, it is limited to
associating events with event handlers at compile time.
In some cases, such as with events associated with forms or controls, Visual Basic automatically stubs out an
empty event handler and associates it with an event. For example, when you double-click a command button on a
form in design mode, Visual Basic creates an empty event handler and a WithEvents variable for the command
button, as in the following code:
RemoveHandler , which disconnects an event from an event handler, uses the same syntax as AddHandler . For
example:
In the following example, an event handler is associated with an event, and the event is raised. The event handler
catches the event and displays a message.
Then the first event handler is removed and a different event handler is associated with the event. When the
event is raised again, a different message is displayed.
Finally, the second event handler is removed and the event is raised for a third time. Because there is no longer
an event handler associated with the event, no action is taken.
Module Module1
Sub Main()
Dim c1 As New Class1
' Associate an event handler with an event.
AddHandler c1.AnEvent, AddressOf EventHandler1
' Call a method to raise the event.
c1.CauseTheEvent()
' Stop handling the event.
RemoveHandler c1.AnEvent, AddressOf EventHandler1
' Now associate a different event handler with the event.
AddHandler c1.AnEvent, AddressOf EventHandler2
' Call a method to raise the event.
c1.CauseTheEvent()
' Stop handling the event.
RemoveHandler c1.AnEvent, AddressOf EventHandler2
' This event will not be handled.
c1.CauseTheEvent()
End Sub
Sub EventHandler1()
' Handle the event.
MsgBox("EventHandler1 caught event.")
End Sub
Sub EventHandler2()
' Handle the event.
MsgBox("EventHandler2 caught event.")
End Sub
End Module
Walkthrough: Declaring and Raising Events Provides a step-by-step description of how to declare and
raise events for a class.
How to: Declare Custom Events To Avoid Blocking Demonstrates how to define a custom event that allows its
event handlers to be called asynchronously.
How to: Declare Custom Events To Conserve Memory Demonstrates how to define a custom event that uses
memory only when the event is handled.
Troubleshooting Inherited Event Handlers in Visual Basic Lists common issues that arise with event handlers in
inherited components.
Creating Event Handlers in Windows Forms Describes how to work with events associated with Windows
Forms objects.
Interfaces define the properties, methods, and events that classes can implement. Interfaces allow you to define
features as small groups of closely related properties, methods, and events; this reduces compatibility problems
because you can develop enhanced implementations for your interfaces without jeopardizing existing code. You
can add new features at any time by developing additional interfaces and implementations.
There are several other reasons why you might want to use interfaces instead of class inheritance:
Interfaces are better suited to situations in which your applications require many possibly unrelated object
types to provide certain functionality.
Interfaces are more flexible than base classes because you can define a single implementation that can
implement multiple interfaces.
Interfaces are better in situations in which you do not have to inherit implementation from a base class.
Interfaces are useful when you cannot use class inheritance. For example, structures cannot inherit from
classes, but they can implement interfaces.
Declaring Interfaces
Interface definitions are enclosed within the Interface and End Interface statements. Following the Interface
statement, you can add an optional Inherits statement that lists one or more inherited interfaces. The Inherits
statements must precede all other statements in the declaration except comments. The remaining statements in
the interface definition should be Event , Sub , Function , Property , Interface , Class , Structure , and Enum
statements. Interfaces cannot contain any implementation code or statements associated with implementation
code, such as End Sub or End Property .
In a namespace, interface statements are Friend by default, but they can also be explicitly declared as Public or
Friend . Interfaces defined within classes, modules, interfaces, and structures are Public by default, but they can
also be explicitly declared as Public , Friend , Protected , or Private .
NOTE
The Shadows keyword can be applied to all interface members. The Overloads keyword can be applied to Sub ,
Function , and Property statements declared in an interface definition. In addition, Property statements can have the
Default , ReadOnly , or WriteOnly modifiers. None of the other modifiers— Public , Private , Friend , Protected
, Shared , Overrides , MustOverride , or Overridable —are allowed. For more information, see Declaration Contexts
and Default Access Levels.
For example, the following code defines an interface with one function, one property, and one event.
Interface IAsset
Event ComittedChange(ByVal Success As Boolean)
Property Division() As String
Function GetID() As Integer
End Interface
Implementing Interfaces
The Visual Basic reserved word Implements is used in two ways. The Implements statement signifies that a class
or structure implements an interface. The Implements keyword signifies that a class member or structure
member implements a specific interface member.
Implements Statement
If a class or structure implements one or more interfaces, it must include the Implements statement immediately
after the Class or Structure statement. The Implements statement requires a comma-separated list of
interfaces to be implemented by a class. The class or structure must implement all interface members using the
Implements keyword.
Implements Keyword
The Implements keyword requires a comma-separated list of interface members to be implemented. Generally,
only a single interface member is specified, but you can specify multiple members. The specification of an
interface member consists of the interface name, which must be specified in an implements statement within the
class; a period; and the name of the member function, property, or event to be implemented. The name of a
member that implements an interface member can use any legal identifier, and it is not limited to the
InterfaceName_MethodName convention used in earlier versions of Visual Basic.
For example, the following code shows how to declare a subroutine named Sub1 that implements a method of
an interface:
Class Class1
Implements interfaceclass.interface2
The parameter types and return types of the implementing member must match the interface property or
member declaration in the interface. The most common way to implement an element of an interface is with a
member that has the same name as the interface, as shown in the previous example.
To declare the implementation of an interface method, you can use any attributes that are legal on instance
method declarations, including Overloads , Overrides , Overridable , Public , Private , Protected , Friend ,
Protected Friend , MustOverride , Default , and Static . The Shared attribute is not legal since it defines a class
rather than an instance method.
Using Implements , you can also write a single method that implements multiple methods defined in an interface,
as in the following example:
Class Class2
Implements I1, I2
You can use a private member to implement an interface member. When a private member implements a
member of an interface, that member becomes available by way of the interface even though it is not available
directly on object variables for the class.
Interface Implementation Examples
Classes that implement an interface must implement all its properties, methods, and events.
The following example defines two interfaces. The second interface, Interface2 , inherits Interface1 and defines
an additional property and method.
Interface Interface1
Sub sub1(ByVal i As Integer)
End Interface
The next example implements Interface1 , the interface defined in the previous example:
The final example implements Interface2 , including a method inherited from Interface1 :
You can implement a readonly property with a readwrite property (that is, you do not have to declare it readonly
in the implementing class). Implementing an interface promises to implement at least the members that the
interface declares, but you can offer more functionality, such as allowing your property to be writable.
Related Topics
TITLE DESCRIPTION
Walkthrough: Creating and Implementing Interfaces Provides a detailed procedure that takes you through the
process of defining and implementing your own interface.
Interfaces describe the characteristics of properties, methods, and events, but leave the implementation details up
to structures or classes.
This walkthrough demonstrates how to declare and implement an interface.
NOTE
This walkthrough doesn't provide information about how to create a user interface.
NOTE
Your computer might show different names or locations for some of the Visual Studio user interface elements in the following
instructions. The Visual Studio edition that you have and the settings that you use determine these elements. For more
information, see Personalizing the IDE.
To define an interface
1. Open a new Visual Basic Windows Application project.
2. Add a new module to the project by clicking Add Module on the Project menu.
3. Name the new module Module1.vb and click Add. The code for the new module is displayed.
4. Define an interface named TestInterface within Module1 by typing Interface TestInterface between the
Module and End Module statements, and then pressing ENTER. The Code Editor indents the Interface
keyword and adds an End Interface statement to form a code block.
5. Define a property, method, and event for the interface by placing the following code between the Interface
and End Interface statements:
Implementation
You may notice that the syntax used to declare interface members is different from the syntax used to declare class
members. This difference reflects the fact that interfaces cannot contain implementation code.
To implement the interface
1. Add a class named ImplementationClass by adding the following statement to Module1 , after the
End Interface statement but before the End Module statement, and then pressing ENTER:
Class ImplementationClass
If you are working within the integrated development environment, the Code Editor supplies a matching
End Class statement when you press ENTER.
2. Add the following Implements statement to ImplementationClass , which names the interface the class
implements:
Implements TestInterface
When listed separately from other items at the top of a class or structure, the Implements statement
indicates that the class or structure implements an interface.
If you are working within the integrated development environment, the Code Editor implements the class
members required by TestInterface when you press ENTER, and you can skip the next step.
3. If you are not working within the integrated development environment, you must implement all the
members of the interface MyInterface . Add the following code to ImplementationClass to implement
Event1 , Method1 , and Prop1 :
The Implements statement names the interface and interface member being implemented.
4. Complete the definition of Prop1 by adding a private field to the class that stored the property value:
Return the value of the pval from the property get accessor.
Return pval
pval = value
By declaring testInstance as WithEvents , the Form1 class can handle its events.
3. Add the following event handler to the Form1 class to handle events raised by testInstance :
4. Add a subroutine named Test to the Form1 class to test the implementation class:
Sub Test()
' Create an instance of the class.
Dim T As New ImplementationClass
' Assign the class instance to the interface.
' Calls to the interface members are
' executed through the class instance.
testInstance = T
' Set a property.
testInstance.Prop1 = 9
' Read the property.
MsgBox("Prop1 was set to " & testInstance.Prop1)
' Test the method and raise an event.
testInstance.Method1(5)
End Sub
The Test procedure creates an instance of the class that implements MyInterface , assigns that instance to
the testInstance field, sets a property, and runs a method through the interface.
5. Add code to call the Test procedure from the Form1 Load procedure of your startup form:
6. Run the Test procedure by pressing F5. The message "Prop1 was set to 9" is displayed. After you click OK,
the message "The X parameter for Method1 is 5" is displayed. Click OK, and the message "The event handler
caught the event" is displayed.
See Also
Implements Statement
Interfaces
Interface Statement
Event Statement
LINQ in Visual Basic
7/29/2017 • 1 min to read • Edit Online
This section contains overviews, examples, and background information that will help you understand and use
Visual Basic and Language-Integrated Query (LINQ).
In This Section
Introduction to LINQ in Visual Basic
Provides an introduction to LINQ providers, operators, query structure, and language features.
How to: Query a Database
Provides an example of how to connect to a SQL Server database and execute a query by using LINQ.
How to: Call a Stored Procedure
Provides an example of how to connect to a SQL Server database and call a stored procedure by using LINQ.
How to: Modify Data in a Database
Provides an example of how to connect to a SQL Server database and retrieve and modify data by using LINQ.
How to: Combine Data with Joins
Provides examples of how to join data in a manner similar to database joins by using LINQ.
How to: Sort Query Results
Provides an example of how to order the results of a query by using LINQ.
How to: Filter Query Results
Provides an example of how to include search criteria in a query by using LINQ.
How to: Count, Sum, or Average Data
Provides examples of how to include aggregate functions to Count, Sum, or Average data returned from a query
by using LINQ.
How to: Find the Minimum or Maximum Value in a Query Result
Provides examples of how to include aggregate functions to determine the minimum and maximum values of data
returned from a query by using LINQ.
How to: Return a LINQ Query Result as a Specific Type
Provides an example of how to return the results of a LINQ query as a specific type instead of as an anonymous
type.
See Also
LINQ (Language-Integrated Query)
Overview of LINQ to XML in Visual Basic
LINQ to DataSet Overview
LINQ to SQL
Objects and classes in Visual Basic
7/29/2017 • 11 min to read • Edit Online
An object is a combination of code and data that can be treated as a unit. An object can be a piece of an
application, like a control or a form. An entire application can also be an object.
When you create an application in Visual Basic, you constantly work with objects. You can use objects provided
by Visual Basic, such as controls, forms, and data access objects. You can also use objects from other applications
within your Visual Basic application. You can even create your own objects and define additional properties and
methods for them. Objects act like prefabricated building blocks for programs — they let you write a piece of
code once and reuse it over and over.
This topic discusses objects in detail.
3. Add the New Operator keyword to initialize the variable to a new instance of the class.
4. You can now access the members of the class through the object variable.
nextCustomer.accountNumber = lastAccountNumber + 1
NOTE
Whenever possible, you should declare the variable to be of the class type you intend to assign to it. This is called early
binding. If you don't know the class type at compile time, you can invoke late binding by declaring the variable to be of
the Object Data Type. However, late binding can make performance slower and limit access to the run-time object's
members. For more information, see Object Variable Declaration.
Multiple instances
Objects newly created from a class are often identical to each other. Once they exist as individual objects,
however, their variables and properties can be changed independently of the other instances. For example, if you
add three check boxes to a form, each check box object is an instance of the CheckBox class. The individual
CheckBox objects share a common set of characteristics and capabilities (properties, variables, procedures, and
events) defined by the class. However, each has its own name, can be separately enabled and disabled, and can
be placed in a different location on the form.
Object members
An object is an element of an application, representing an instance of a class. Fields, properties, methods, and
events are the building blocks of objects and constitute their members.
Member Access
You access a member of an object by specifying, in order, the name of the object variable, a period ( . ), and the
name of the member. The following example sets the Text property of a Label object.
1. Make sure the object has been created from its class and assigned to an object variable.
2. In the statement that accesses the member, follow the object variable name with the member-access
operator ( . ) and then the member name.
secondForm.Show()
Follow the class name with the member-access operator ( . ) and then the member name. You should
always access a Shared member of the object directly through the class name.
If you have already created an object from the class, you can alternatively access a Shared member
through the object's variable.
Differences between classes and modules
The main difference between classes and modules is that classes can be instantiated as objects while standard
modules cannot. Because there is only one copy of a standard module's data, when one part of your program
changes a public variable in a standard module, any other part of the program gets the same value if it then
reads that variable. In contrast, object data exists separately for each instantiated object. Another difference is
that unlike standard modules, classes can implement interfaces.
NOTE
When the Shared modifier is applied to a class member, it is associated with the class itself instead of a particular
instance of the class. The member is accessed directly by using the class name, the same way module members are
accessed.
Classes and modules also use different scopes for their members. Members defined within a class are scoped
within a specific instance of the class and exist only for the lifetime of the object. To access class members from
outside a class, you must use fully qualified names in the format of Object.Member.
On the other hand, members declared within a module are publicly accessible by default, and can be accessed by
any code that can access the module. This means that variables in a standard module are effectively global
variables because they are visible from anywhere in your project, and they exist for the life of the program.
In the preceding example, the first Dim Statement declares an object variable of type TimeZone and assigns to it
a TimeZone object returned by the CurrentTimeZone property.
1. Use a Class Statement to define a class from which to create the object you need.
Be sure an End Class statement follows the last line of code in your class. By default, the integrated
development environment (IDE) automatically generates an End Class when you enter a Class
statement.
2. Follow the Class statement immediately with an Inherits Statement. Specify the class from which your
new class derives.
Inherits System.Windows.Forms.Button
Your new class inherits all the members defined by the base class.
3. Add the code for the additional members your derived class exposes. For example, you might add a
reverseColors method, and your derived class might look as follows:
If you create an object from the reversibleButton class, it can access all the members of the Button class,
as well as the reverseColors method and any other new members you define on reversibleButton .
Derived classes inherit members from the class they are based on, allowing you to add complexity as you
progress in a class hierarchy. For more information, see Inheritance Basics.
Compiling the code
Be sure the compiler can access the class from which you intend to derive your new class. This might mean fully
qualifying its name, as in the preceding example, or identifying its namespace in an Imports Statement (.NET
Namespace and Type). If the class is in a different project, you might need to add a reference to that project. For
more information, see Managing references in a project.
Containment relationship
Another way that objects can be related is a containment relationship. Container objects logically encapsulate
other objects. For example, the OperatingSystem object logically contains a Version object, which it returns
through its Version property. Note that the container object does not physically contain any other object.
Collections
One particular type of object containment is represented by collections. Collections are groups of similar objects
that can be enumerated. Visual Basic supports a specific syntax in the For Each...Next Statement that allows you
to iterate through the items of a collection. Additionally, collections often allow you to use an Item[String] to
retrieve elements by their index or by associating them with a unique string. Collections can be easier to use than
arrays because they allow you to add or remove items without using indexes. Because of their ease of use,
collections are often used to store forms and controls.
Related topics
Walkthrough: Defining Classes
Provides a step-by-step description of how to create a class.
Overloaded Properties and Methods
Overloaded Properties and Methods
Inheritance Basics
Covers inheritance modifiers, overriding methods and properties, MyClass, and MyBase.
Object Lifetime: How Objects Are Created and Destroyed
Discusses creating and disposing of class instances.
Anonymous Types
Describes how to create and use anonymous types, which allow you to create objects without writing a class
definition for the data type.
Object Initializers: Named and Anonymous Types
Discusses object initializers, which are used to create instances of named and anonymous types by using a single
expression.
How to: Infer Property Names and Types in Anonymous Type Declarations
Explains how to infer property names and types in anonymous type declarations. Provides examples of
successful and unsuccessful inference.
Operators and Expressions in Visual Basic
7/29/2017 • 1 min to read • Edit Online
An operator is a code element that performs an operation on one or more code elements that hold values. Value
elements include variables, constants, literals, properties, returns from Function and Operator procedures, and
expressions.
An expression is a series of value elements combined with operators, which yields a new value. The operators act
on the value elements by performing calculations, comparisons, or other operations.
Types of Operators
Visual Basic provides the following types of operators:
Arithmetic Operators perform familiar calculations on numeric values, including shifting their bit patterns.
Comparison Operators compare two expressions and return a Boolean value representing the result of
the comparison.
Concatenation Operators join multiple strings into a single string.
Logical and Bitwise Operators in Visual Basic combine Boolean or numeric values and return a result of
the same data type as the values.
The value elements that are combined with an operator are called operands of that operator. Operators
combined with value elements form expressions, except for the assignment operator, which forms a statement.
For more information, see Statements.
Evaluation of Expressions
The end result of an expression represents a value, which is typically of a familiar data type such as Boolean ,
String , or a numeric type.
15 * System.Math.Sqrt(9) + x
763 < 23
Several operators can perform actions in a single expression or statement, as the following example illustrates.
x = 45 + y * z ^ 2
In the preceding example, Visual Basic performs the operations in the expression on the right side of the
assignment operator ( = ), then assigns the resulting value to the variable x on the left. There is no practical limit
to the number of operators that can be combined into an expression, but an understanding of Operator
Precedence in Visual Basic is necessary to ensure that you get the results you expect.
For more information and examples, see Operator Overloading in Visual Basic 2005.
See Also
Operators
Efficient Combination of Operators
Statements
Procedures in Visual Basic
7/29/2017 • 3 min to read • Edit Online
A procedure is a block of Visual Basic statements enclosed by a declaration statement ( Function , Sub , Operator ,
Get , Set ) and a matching End declaration. All executable statements in Visual Basic must be within some
procedure.
Calling a Procedure
You invoke a procedure from some other place in the code. This is known as a procedure call. When the
procedure is finished running, it returns control to the code that invoked it, which is known as the calling code.
The calling code is a statement, or an expression within a statement, that specifies the procedure by name and
transfers control to it.
Types of Procedures
Visual Basic uses several types of procedures:
Sub Procedures perform actions but do not return a value to the calling code.
Event-handling procedures are Sub procedures that execute in response to an event raised by user action
or by an occurrence in a program.
Function Procedures return a value to the calling code. They can perform other actions before returning.
Some functions written in C# return a reference return value. Function callers can modify the return value,
and this modification is reflected in the state of the called object. Starting with Visual Basic 2017, Visual
Basic code can consume reference return values, although it cannot return a value by reference. For more
information, see Reference return values.
Property Procedures return and assign values of properties on objects or modules.
Operator Procedures define the behavior of a standard operator when one or both of the operands is a
newly-defined class or structure.
Generic Procedures in Visual Basic define one or more type parameters in addition to their normal
parameters, so the calling code can pass specific data types each time it makes a call.
Procedures are useful for performing repeated or shared tasks, such as frequently used calculations, text and
control manipulation, and database operations. You can call a procedure from many different places in your code,
so you can use procedures as building blocks for your application.
Structuring your code with procedures gives you the following benefits:
Procedures allow you to break your programs into discrete logical units. You can debug separate units
more easily than you can debug an entire program without procedures.
After you develop procedures for use in one program, you can use them in other programs, often with
little or no modification. This helps you avoid code duplication.
See Also
How to: Create a Procedure
Sub Procedures
Function Procedures
Property Procedures
Operator Procedures
Procedure Parameters and Arguments
Recursive Procedures
Procedure Overloading
Generic Procedures in Visual Basic
Objects and Classes
Statements in Visual Basic
7/29/2017 • 12 min to read • Edit Online
A statement in Visual Basic is a complete instruction. It can contain keywords, operators, variables, constants,
and expressions. Each statement belongs to one of the following categories:
Declaration Statements, which name a variable, constant, or procedure, and can also specify a data
type.
Executable Statements, which initiate actions. These statements can call a method or function, and they
can loop or branch through blocks of code. Executable statements include Assignment Statements,
which assign a value or expression to a variable or constant.
This topic describes each category. Also, this topic describes how to combine multiple statements on a single
line and how to continue a statement over multiple lines.
Declaration Statements
You use declaration statements to name and define procedures, variables, properties, arrays, and constants.
When you declare a programming element, you can also define its data type, access level, and scope. For more
information, see Declared Element Characteristics.
The following example contains three declarations.
The first declaration is the Sub statement. Together with its matching End Sub statement, it declares a
procedure named applyFormat . It also specifies that applyFormat is Public , which means that any code that
can refer to it can call it.
The second declaration is the Const statement, which declares the constant limit , specifying the Integer
data type and a value of 33.
The third declaration is the Dim statement, which declares the variable thisWidget . The data type is a specific
object, namely an object created from the Widget class. You can declare a variable to be of any elementary data
type or of any object type that is exposed in the application you are using.
Initial Values
When the code containing a declaration statement runs, Visual Basic reserves the memory required for the
declared element. If the element holds a value, Visual Basic initializes it to the default value for its data type. For
more information, see "Behavior" in Dim Statement.
You can assign an initial value to a variable as part of its declaration, as the following example illustrates.
Dim m As Integer = 45
' The preceding declaration creates m and assigns the value 45 to it.
If a variable is an object variable, you can explicitly create an instance of its class when you declare it by using
the New Operator keyword, as the following example illustrates.
Note that the initial value you specify in a declaration statement is not assigned to a variable until execution
reaches its declaration statement. Until that time, the variable contains the default value for its data type.
Executable Statements
An executable statement performs an action. It can call a procedure, branch to another place in the code, loop
through several statements, or evaluate an expression. An assignment statement is a special case of an
executable statement.
The following example uses an If...Then...Else control structure to run different blocks of code based on the
value of a variable. Within each block of code, a For...Next loop runs a specified number of times.
The If statement in the preceding example checks the value of the parameter clockwise . If the value is True ,
it calls the spinClockwise method of aWidget . If the value is False , it calls the spinCounterClockwise method
of aWidget . The If...Then...Else control structure ends with End If .
The For...Next loop within each block calls the appropriate method a number of times equal to the value of
the revolutions parameter.
Assignment Statements
Assignment statements carry out assignment operations, which consist of taking the value on the right side of
the assignment operator ( = ) and storing it in the element on the left, as in the following example.
v = 42
In the preceding example, the assignment statement stores the literal value 42 in the variable v .
Eligible Programming Elements
The programming element on the left side of the assignment operator must be able to accept and store a value.
This means it must be a variable or property that is not ReadOnly, or it must be an array element. In the context
of an assignment statement, such an element is sometimes called an lvalue, for "left value."
The value on the right side of the assignment operator is generated by an expression, which can consist of any
combination of literals, constants, variables, properties, array elements, other expressions, or function calls. The
following example illustrates this.
x = y + z + findResult(3)
The preceding example adds the value held in variable y to the value held in variable z , and then adds the
value returned by the call to function findResult . The total value of this expression is then stored in variable x .
Data Types in Assignment Statements
In addition to numeric values, the assignment operator can also assign String values, as the following example
illustrates.
Dim a, b As String
a = "String variable assignment"
b = "Con" & "cat" & "enation"
' The preceding statement assigns the value "Concatenation" to b.
You can also assign Boolean values, using either a Boolean literal or a Boolean expression, as the following
example illustrates.
Dim r, s, t As Boolean
r = True
s = 45 > 1003
t = 45 > 1003 Or 45 > 17
' The preceding statements assign False to s and True to t.
Similarly, you can assign appropriate values to programming elements of the Char , Date , or Object data
type. You can also assign an object instance to an element declared to be of the class from which that instance is
created.
Compound Assignment Statements
Compound assignment statements first perform an operation on an expression before assigning it to a
programming element. The following example illustrates one of these operators, += , which increments the
value of the variable on the left side of the operator by the value of the expression on the right.
n += 1
The preceding example adds 1 to the value of n , and then stores that new value in n . It is a shorthand
equivalent of the following statement:
n = n + 1
A variety of compound assignment operations can be performed using operators of this type. For a list of these
operators and more information about them, see Assignment Operators.
The concatenation assignment operator ( &= ) is useful for adding a string to the end of already existing strings,
as the following example illustrates.
Though occasionally convenient, this form of syntax makes your code hard to read and maintain. Thus, it is
recommended that you keep one statement to a line.
After a comma ( , ).
Public Function GetUsername(ByVal username As
String,
ByVal delimiter As
Char,
ByVal position As
Integer) As String
Return username.Split(delimiter)(position)
End Function
SYNTAX ELEMENT EXAMPLE
Security.Principal.WindowsIdentity.GetCurrent()
.Name,
CChar("\"),
1
)
ReadFile(inStream)
End If
' Allowed:
Dim aType = New With {.PropertyName =
"Value"}
' Allowed:
With log
.Source =
"Application"
End With
Adding Comments
Source code is not always self-explanatory, even to the programmer who wrote it. To help document their code,
therefore, most programmers make liberal use of embedded comments. Comments in code can explain a
procedure or a particular instruction to anyone reading or working with it later. Visual Basic ignores comments
during compilation, and they do not affect the compiled code.
Comment lines begin with an apostrophe ( ' ) or REM followed by a space. They can be added anywhere in
code, except within a string. To append a comment to a statement, insert an apostrophe or REM after the
statement, followed by the comment. Comments can also go on their own separate line. The following example
demonstrates these possibilities.
Related Sections
TERM DEFINITION
Operators and Expressions Shows how to combine elements with operators to yield
new values.
How to: Break and Combine Statements in Code Shows how to break a single statement into multiple lines
and how to place multiple statements on the same line.
This section describes the basic concepts behind using strings in Visual Basic.
In This Section
Introduction to Strings in Visual Basic
Lists topics that describe the basic concepts behind using strings in Visual Basic.
How to: Create Strings Using a StringBuilder in Visual Basic
Demonstrates how to efficiently create a long string from many smaller strings.
How to: Search Within a String
Demonstrates how to determine the index of the first occurrence of a substring.
Converting Between Strings and Other Data Types in Visual Basic
Lists topics that describe how to convert strings into other data types.
Validating Strings in Visual Basic
Lists topics that discuss how to validate strings.
Walkthrough: Encrypting and Decrypting Strings in Visual Basic
Demonstrates how to encrypt and decrypt strings by using the cryptographic service provider version of the Triple
Data Encryption Standard algorithm.
See Also
Visual Basic Language Features
Variables in Visual Basic
7/29/2017 • 1 min to read • Edit Online
You often have to store values when you perform calculations with Visual Basic. For example, you might want to
calculate several values, compare them, and perform different operations on them, depending on the result of the
comparison. You have to retain the values if you want to compare them.
Usage
Visual Basic, just like most programming languages, uses variables for storing values. A variable has a name (the
word that you use to refer to the value that the variable contains). A variable also has a data type (which
determines the kind of data that the variable can store). A variable can represent an array if it has to store an
indexed set of closely related data items.
Local type inference enables you to declare variables without explicitly stating a data type. Instead, the compiler
infers the type of the variable from the type of the initialization expression. For more information, see Local Type
Inference and Option Infer Statement.
Assigning Values
You use assignment statements to perform calculations and assign the result to a variable, as the following
example shows.
NOTE
The equal sign ( = ) in this example is an assignment operator, not an equality operator. The value is being assigned to the
variable applesSold .
For more information, see How to: Move Data Into and Out of a Variable.
See Also
Variable Declaration
Object Variables
Troubleshooting Variables
How to: Move Data Into and Out of a Variable
Differences Between Properties and Variables in Visual Basic
Local Type Inference
XML in Visual Basic
7/29/2017 • 1 min to read • Edit Online
Visual Basic provides integrated language support that enables it to interact with LINQ to XML.
In This Section
The topics in this section introduce using LINQ to XML with Visual Basic.
TOPIC DESCRIPTION
Overview of LINQ to XML in Visual Basic Describes how Visual Basic supports LINQ to XML.
Creating XML in Visual Basic Describes how to create XML literal objects by using LINQ to
XML.
Manipulating XML in Visual Basic Describes how to load and parse XML by using Visual Basic.
Accessing XML in Visual Basic Describes the XML axis properties and LINQ to XML methods
for accessing XML elements and attributes.
XML IntelliSense in Visual Basic Describes the IntelliSense capabilities provided with Visual
Basic.
See Also
System.Xml.Linq
XML Literals
XML Axis Properties
LINQ to XML
COM Interop (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
The Component Object Model (COM) allows an object to expose its functionality to other components and to host
applications. Most of today's software includes COM objects. Although .NET assemblies are the best choice for
new applications, you may at times need to employ COM objects. This section covers some of the issues
associated with creating and using COM objects with Visual Basic.
In This Section
Introduction to COM Interop
Provides an overview of COM interoperability.
How to: Reference COM Objects from Visual Basic
Covers how to add references to COM objects that have type libraries.
How to: Work with ActiveX Controls
Demonstrates how to use existing ActiveX controls to add features to the Visual Studio Toolbox.
Walkthrough: Calling Windows APIs
Steps you through the process of calling the APIs that are part of the Windows operating system.
How to: Call Windows APIs
Demonstrates how to define and call the MessageBox function in User32.dll.
How to: Call a Windows Function that Takes Unsigned Types
Demonstrates how to call a Windows function that has a parameter of an unsigned type.
Walkthrough: Creating COM Objects with Visual Basic
Steps you through the process of creating COM objects with and without the COM class template.
Troubleshooting Interoperability
Covers some of the problems you may encounter when using COM.
COM Interoperability in .NET Framework Applications
Provides an overview of how to use COM objects and .NET Framework objects in the same application.
Walkthrough: Implementing Inheritance with COM Objects
Describes using existing COM objects as the basis for new objects.
Related Sections
Interoperating with Unmanaged Code
Describes interoperability services provided by the common language runtime.
Exposing COM Components to the .NET Framework
Describes the process of calling COM types through COM interop.
Exposing .NET Framework Components to COM
Describes the preparation and use of managed types from COM.
Applying Interop Attributes
Covers attributes you can use when working with unmanaged code.
Introduction to COM Interop (Visual Basic)
7/29/2017 • 2 min to read • Edit Online
The Component Object Model (COM) lets an object expose its functionality to other components and to host
applications. While COM objects have been fundamental to Windows programming for many years, applications
designed for the common language runtime (CLR) offer many advantages.
.NET Framework applications will eventually replace those developed with COM. Until then, you may have to use or
create COM objects by using Visual Studio. Interoperability with COM, or COM interop, enables you to use existing
COM objects while transitioning to the .NET Framework at your own pace.
By using the .NET Framework to create COM components, you can use registration-free COM interop. This lets you
control which DLL version is enabled when more than one version is installed on a computer, and lets end users
use XCOPY or FTP to copy your application to an appropriate directory on their computer where it can be run. For
more information, see Registration-Free COM Interop.
Assemblies
An assembly is the primary building block of a .NET Framework application. It is a collection of functionality that is
built, versioned, and deployed as a single implementation unit containing one or more files. Each assembly
contains an assembly manifest.
Interoperability Marshaling
All .NET Framework applications share a set of common types that enable interoperability of objects, regardless of
the programming language that is used. The parameters and return values of COM objects sometimes use data
types that differ from those used in managed code. Interoperability marshaling is the process of packaging
parameters and return values into equivalent data types as they move to and from COM objects. For more
information, see Interop Marshaling.
See Also
COM Interop
Walkthrough: Implementing Inheritance with COM Objects
Interoperating with Unmanaged Code
Troubleshooting Interoperability
Assemblies and the Global Assembly Cache
Tlbimp.exe (Type Library Importer)
Tlbexp.exe (Type Library Exporter)
Interop Marshaling
Registration-Free COM Interop
How to: Reference COM Objects from Visual Basic
7/29/2017 • 2 min to read • Edit Online
In Visual Basic, adding references to COM objects that have type libraries requires the creation of an interop
assembly for the COM library. References to the members of the COM object are routed to the interop assembly
and then forwarded to the actual COM object. Responses from the COM object are routed to the interop assembly
and forwarded to your .NET Framework application.
You can reference a COM object without using an interop assembly by embedding the type information for the
COM object in a .NET assembly. To embed type information, set the Embed Interop Types property to True for the
reference to the COM object. If you are compiling by using the command-line compiler, use the /link option to
reference the COM library. For more information, see /link (Visual Basic).
Visual Basic automatically creates interop assemblies when you add a reference to a type library from the
integrated development environment (IDE). When working from the command line, you can use the Tlbimp utility
to manually create interop assemblies.
To add references to COM objects
1. On the Project menu, choose Add Reference and then click the COM tab in the dialog box.
2. Select the component you want to use from the list of COM objects.
3. To simplify access to the interop assembly, add an Imports statement to the top of the class or module in
which you will use the COM object. For example, the following code example imports the namespace
INKEDLib for objects referenced in the Microsoft InkEdit Control 1.0 library.
Imports INKEDLib
Class Sample
Private s As IInkCursor
End Class
You can use Tlbimp to create interop assemblies for type libraries, even for unregistered COM objects.
However, the COM objects referred to by interop assemblies must be properly registered on the computer
where they are to be used. You can register a COM object by using the Regsvr32 utility included with the
Windows operating system.
See Also
COM Interop
Tlbimp.exe (Type Library Importer)
Tlbexp.exe (Type Library Exporter)
Walkthrough: Implementing Inheritance with COM Objects
Troubleshooting Interoperability
Imports Statement (.NET Namespace and Type)
How to: Work with ActiveX Controls (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
ActiveX controls are COM components or objects you can insert into a Web page or other application to reuse
packaged functionality someone else has programmed. You can use ActiveX controls developed for Visual Basic 6.0
and earlier versions to add features to the Toolbox of Visual Studio.
To add ActiveX controls to the toolbox
1. On the Tools menu, click Choose Toolbox Items.
The Choose Toolbox dialog box appears.
2. Click the COM Components tab.
3. Select the check box next to the ActiveX control you want to use, and then click OK.
The new control appears with the other tools in the Toolbox.
NOTE
You can use the Aximp utility to manually create an interop assembly for ActiveX controls. For more information, see
Aximp.exe (Windows Forms ActiveX Control Importer).
See Also
COM Interop
How to: Add ActiveX Controls to Windows Forms
Aximp.exe (Windows Forms ActiveX Control Importer)
Considerations When Hosting an ActiveX Control on a Windows Form
Troubleshooting Interoperability
Walkthrough: Calling Windows APIs (Visual Basic)
7/29/2017 • 9 min to read • Edit Online
Windows APIs are dynamic-link libraries (DLLs) that are part of the Windows operating system. You use them to
perform tasks when it is difficult to write equivalent procedures of your own. For example, Windows provides a
function named FlashWindowEx that lets you make the title bar for an application alternate between light and dark
shades.
The advantage of using Windows APIs in your code is that they can save development time because they contain
dozens of useful functions that are already written and waiting to be used. The disadvantage is that Windows APIs
can be difficult to work with and unforgiving when things go wrong.
Windows APIs represent a special category of interoperability. Windows APIs do not use managed code, do not
have built-in type libraries, and use data types that are different than those used with Visual Studio. Because of
these differences, and because Windows APIs are not COM objects, interoperability with Windows APIs and the
.NET Framework is performed using platform invoke, or PInvoke. Platform invoke is a service that enables
managed code to call unmanaged functions implemented in DLLs. For more information, see Consuming
Unmanaged DLL Functions. You can use PInvoke in Visual Basic by using either the Declare statement or
applying the DllImport attribute to an empty procedure.
Windows API calls were an important part of Visual Basic programming in the past, but are seldom necessary with
Visual Basic .NET. Whenever possible, you should use managed code from the .NET Framework to perform tasks,
instead of Windows API calls. This walkthrough provides information for those situations in which using Windows
APIs is necessary.
NOTE
Your computer might show different names or locations for some of the Visual Studio user interface elements in the
following instructions. The Visual Studio edition that you have and the settings that you use determine these elements. For
more information, see Personalizing the IDE.
NOTE
For complete information about the Windows APIs, see the Win32 SDK documentation in the Platform SDK
Windows API. For more information about the constants that Windows APIs use, examine the header files such as
Windows.h included with the Platform SDK.
2. Open a new Windows Application project by clicking New on the File menu, and then clicking Project. The
New Project dialog box appears.
3. Select Windows Application from the list of Visual Basic project templates. The new project is displayed.
4. Add the following Declare function either to the class or module in which you want to use the DLL:
Declare Auto Function MBox Lib "user32.dll" Alias "MessageBox" (
ByVal hWnd As Integer,
ByVal txt As String,
ByVal caption As String,
ByVal Typ As Integer) As Integer
NOTE
Previous versions of Visual Basic allowed you to declare parameters As Any , meaning that data of any data type could be
used. Visual Basic requires that you use a specific data type for all Declare statements.
1. Consult the documentation for the Windows function you are calling. Determine the name of the constants
it uses and the name of the .h file that contains the numeric values for these constants.
2. Use a text editor, such as Notepad, to view the contents of the header (.h) file, and find the values associated
with the constants you are using. For example, the MessageBox API uses the constant MB_ICONQUESTION to
show a question mark in the message box. The definition for MB_ICONQUESTION is in WinUser.h and appears
as follows:
#define MB_ICONQUESTION 0x00000020L
3. Add equivalent Const statements to your class or module to make these constants available to your
application. For example:
To c a l l t h e DL L p ro c e d u re
1. Add a button named Button1 to the startup form for your project, and then double-click it to view its code.
The event handler for the button is displayed.
2. Add code to the Click event handler for the button you added, to call the procedure and provide the
appropriate arguments:
3. Run the project by pressing F5. The message box is displayed with both Yes and No response buttons. Click
either one.
Data Marshaling
Visual Basic automatically converts the data types of parameters and return values for Windows API calls, but you
can use the MarshalAs attribute to explicitly specify unmanaged data types that an API expects. For more
information about interop marshaling, see Interop Marshaling.
To u s e De c l a re a n d M a rs h a l A s i n a n A P I c a l l
1. Determine the name of the function you want to call, plus its arguments, data types, and return value.
2. To simplify access to the MarshalAs attribute, add an Imports statement to the top of the code for the class
or module, as in the following example:
Imports System.Runtime.InteropServices
3. Add a function prototype for the imported function to the class or module you are using, and apply the
MarshalAs attribute to the parameters or return value. In the following example, an API call that expects the
type void* is marshaled as AsAny :
Imports System.Runtime.InteropServices
6. Declare an empty function preceding the End Class statement for the form, and name the function
MoveFile .
7. Apply the Public and Shared modifiers to the function declaration and set parameters for MoveFile
based on the arguments the Windows API function uses:
Your function can have any valid procedure name; the DllImport attribute specifies the name in the DLL. It
also handles interoperability marshaling for the parameters and return values, so you can choose Visual
Studio data types that are similar to the data types the API uses.
8. Apply the DllImport attribute to the empty function. The first parameter is the name and location of the
DLL containing the function you are calling. You do not need to specify the path for files located in the
Windows system directories. The second parameter is a named argument that specifies the name of the
function in the Windows API. In this example, the DllImport attribute forces calls to MoveFile to be
forwarded to MoveFileW in KERNEL32.DLL. The MoveFileW method copies a file from the path src to the
path dst .
10. Create a file named Test.txt and place it in the C:\Tmp directory on your hard drive. Create the Tmp
directory if necessary.
11. Press F5 to start the application. The main form appears.
12. Click Button2. The message "The file was moved successfully" is displayed if the file can be moved.
See Also
DllImportAttribute
MarshalAsAttribute
Declare Statement
Auto
Alias
COM Interop
Creating Prototypes in Managed Code
Marshaling a Delegate as a Callback Method
How to: Call Windows APIs (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
This example defines and calls the MessageBox function in user32.dll and then passes a string to it.
Example
' Defines the MessageBox function.
Public Class Win32
Declare Auto Function MessageBox Lib "user32.dll" (
ByVal hWnd As Integer, ByVal txt As String,
ByVal caption As String, ByVal Type As Integer
) As Integer
End Class
Robust Programming
The following conditions may cause an exception:
The method is not static, is abstract, or has been previously defined. The parent type is an interface, or the
length of name or dllName is zero. (ArgumentException)
The name or dllName is Nothing . (ArgumentNullException)
The containing type has been previously created using CreateType . (InvalidOperationException)
See Also
A Closer Look at Platform Invoke
Platform Invoke Examples
Consuming Unmanaged DLL Functions
Defining a Method with Reflection Emit
Walkthrough: Calling Windows APIs
COM Interop
How to: Call a Windows Function that Takes
Unsigned Types (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
If you are consuming a class, module, or structure that has members of unsigned integer types, you can access
these members with Visual Basic.
To call a Windows function that takes an unsigned type
1. Use a Declare Statement to tell Visual Basic which library holds the function, what its name is in that library,
what its calling sequence is, and how to convert strings when calling it.
2. In the Declare statement, use UInteger , ULong , UShort , or Byte as appropriate for each parameter with
an unsigned type.
3. Consult the documentation for the Windows function you are calling to find the names and values of the
constants it uses. Many of these are defined in the WinUser.h file.
4. Declare the necessary constants in your code. Many Windows constants are 32-bit unsigned values, and
you should declare these As``UInteger .
5. Call the function in the normal way. The following example calls the Windows function MessageBox , which
takes an unsigned integer argument.
You can test the function messageThroughWindows with the following code.
Cau t i on
The UInteger , ULong , UShort , and SByte data types are not part of the Language Independence and
Language-Independent Components (CLS), so CLS-compliant code cannot consume a component that uses
them.
IMPORTANT
Making a call to unmanaged code, such as the Windows application programming interface (API), exposes your code
to potential security risks.
IMPORTANT
Calling the Windows API requires unmanaged code permission, which might affect its execution in partial-trust
situations. For more information, see SecurityPermission and Code Access Permissions.
See Also
Data Types
Integer Data Type
UInteger Data Type
Declare Statement
Walkthrough: Calling Windows APIs
Walkthrough: Creating COM Objects with Visual
Basic
7/29/2017 • 4 min to read • Edit Online
When creating new applications or components, it is best to create .NET Framework assemblies. However, Visual
Basic also makes it easy to expose a .NET Framework component to COM. This enables you to provide new
components for earlier application suites that require COM components. This walkthrough demonstrates how to
use Visual Basic to expose .NET Framework objects as COM objects, both with and without the COM class template.
The easiest way to expose COM objects is by using the COM class template. The COM class template creates a new
class, and then configures your project to generate the class and interoperability layer as a COM object and register
it with the operating system.
NOTE
Although you can also expose a class created in Visual Basic as a COM object for unmanaged code to use, it is not a true
COM object and cannot be used by Visual Basic. For more information, see COM Interoperability in .NET Framework
Applications.
NOTE
Your computer might show different names or locations for some of the Visual Studio user interface elements in the
following instructions. The Visual Studio edition that you have and the settings that you use determine these elements. For
more information, see Personalizing the IDE.
4. On the Tools menu, click Create Guid. In the Create GUID dialog box, click Registry Format and then click
Copy. Click Exit.
5. Replace the empty string for the ClassId with the GUID, removing the leading and trailing braces. For
example, if the GUID provided by Guidgen is "{2C8B0AEE-02C9-486e-B809-C780A11530FE}" then your code
should appear as follows.
6. Repeat the previous steps for the InterfaceId and EventsId constants, as in the following example.
NOTE
Make sure that the GUIDs are new and unique; otherwise, your COM component could conflict with other COM
components.
7. Add the ComClass attribute to ComClass1 , specifying the GUIDs for the Class ID, Interface ID, and Events ID
as in the following example:
8. COM classes must have a parameterless Public Sub New() constructor, or the class will not register
correctly. Add a parameterless constructor to the class:
9. Add properties, methods, and events to the class, ending it with an End Class statement. Select Build
Solution from the Build menu. Visual Basic builds the assembly and registers the COM object with the
operating system.
NOTE
The COM objects you generate with Visual Basic cannot be used by other Visual Basic applications because they are
not true COM objects. Attempts to add references to such COM objects will raise an error. For details, see COM
Interoperability in .NET Framework Applications.
See Also
ComClassAttribute
COM Interop
Walkthrough: Implementing Inheritance with COM Objects
#Region Directive
COM Interoperability in .NET Framework Applications
Troubleshooting Interoperability
Troubleshooting Interoperability (Visual Basic)
7/29/2017 • 9 min to read • Edit Online
When you interoperate between COM and the managed code of the .NET Framework, you may encounter one or
more of the following common issues.
Interop Marshaling
At times, you may have to use data types that are not part of the .NET Framework. Interop assemblies handle most
of the work for COM objects, but you may have to control the data types that are used when managed objects are
exposed to COM. For example, structures in class libraries must specify the BStr unmanaged type on strings sent
to COM objects created by Visual Basic 6.0 and earlier versions. In such cases, you can use the MarshalAsAttribute
attribute to cause managed types to be exposed as unmanaged types.
Overloaded Methods
Although you can create overloaded methods with Visual Basic, they are not supported by COM. When a class that
contains overloaded methods is exposed as a COM object, new method names are generated for the overloaded
methods.
For example, consider a class that has two overloads of the Synch method. When the class is exposed as a COM
object, the new generated method names could be Synch and Synch_2 .
The renaming can cause two problems for consumers of the COM object.
1. Clients might not expect the generated method names.
2. The generated method names in the class exposed as a COM object can change when new overloads are
added to the class or its base class. This can cause versioning problems.
To solve both problems, give each method a unique name, instead of using overloading, when you develop
objects that will be exposed as COM objects.
However, if you are using the COM class as the base for a derived class, you must use the interop class that
represents the COM class, as in the following code:
Class DerivedCommand
Inherits ADODB.CommandClass
End Class
NOTE
Interop assemblies implicitly implement interfaces that represent COM classes. You should not try to use the Implements
statement to implement these interfaces or an error will result.
Dim db As DAO.Database
' Open the database.
Set db = DBEngine.OpenDatabase("C:\nwind.mdb")
' Use the database object.
Visual Basic .NET requires that you always create instances of COM objects before you can use their methods. To
use these methods in Visual Basic, declare a variable of the desired class and use the new keyword to assign the
object to the object variable. The Shared keyword can be used when you want to make sure that only one
instance of the class is created.
Sub DAOOpenRecordset()
Dim db As DAO.Database
Dim rst As DAO.Recordset
Dim fld As DAO.Field
' Open the database.
db = DBEngine.OpenDatabase("C:\nwind.mdb")
ADODBConnect()
End Sub
' This is the event handler for the cn_ConnectComplete event raised
' by the ADODB.Connection object when a database is opened.
Dim x As Integer = 6
Dim y As Integer = 0
Try
x = CInt(x / y) ' Attempt to divide by zero.
' This procedure would fail silently without exception handling.
Catch ex As Exception
MsgBox("There was an error: " & ex.Message)
End Try
End Sub
This example raises an error as expected. However, if you try the same example without the
Try...Catch...Finally block, the error is ignored as if you used the OnError Resume Next statement. Without
error handling, the division by zero silently fails. Because such errors never raise unhandled exception errors, it is
important that you use some form of exception handling in event handlers that handle events from COM objects.
Understanding COM interop errors
Without error handling, interop calls often generate errors that provide little information. Whenever possible, use
structured error handling to provide more information about problems when they occur. This can be especially
helpful when you debug applications. For example:
Try
' Place call to COM object here.
Catch ex As Exception
' Display information about the failed call.
End Try
You can find information such as the error description, HRESULT, and the source of COM errors by examining the
contents of the exception object.
If you do not have access to the source code for the procedure being called, you can force the property to be
passed by value by adding an extra set of brackets around the calling procedure. For example, in a project that has
a reference to the Microsoft ActiveX Data Objects 2.8 Library COM object, you can use:
See Also
MarshalAsAttribute
COM Interop
Tlbimp.exe (Type Library Importer)
Tlbexp.exe (Type Library Exporter)
Walkthrough: Implementing Inheritance with COM Objects
Inherits Statement
Global Assembly Cache
COM Interoperability in .NET Framework
Applications (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
When you want to use COM objects and .NET Framework objects in the same application, you need to address the
differences in how the objects exist in memory. A .NET Framework object is located in managed memory—the
memory controlled by the common language runtime—and may be moved by the runtime as needed. A COM
object is located in unmanaged memory and is not expected to move to another memory location. Visual Studio
and the .NET Framework provide tools to control the interaction of these managed and unmanaged components.
For more information about managed code, see Common Language Runtime.
In addition to using COM objects in .NET applications, you may also want to use Visual Basic to develop objects
accessible from unmanaged code through COM.
The links on this page provide details on the interactions between COM and .NET Framework objects.
Related Sections
COM Interop
Provides links to topics covering COM interoperability in Visual Basic, including COM objects, ActiveX controls,
Win32 DLLs, managed objects, and inheritance of COM objects.
COM Interop Wrapper Error
Describes the consequences and options if the project system cannot create a COM interoperability wrapper for a
particular component.
Interoperating with Unmanaged Code
Briefly describes some of the interaction issues between managed and unmanaged code, and provides links for
further study.
COM Wrappers
Discusses runtime callable wrappers, which allow managed code to call COM methods, and COM callable
wrappers, which allow COM clients to call .NET object methods.
Advanced COM Interoperability
Provides links to topics covering COM interoperability with respect to wrappers, exceptions, inheritance,
threading, events, conversions, and marshaling.
Tlbimp.exe (Type Library Importer)
Discusses the tool you can use to convert the type definitions found within a COM type library into equivalent
definitions in a common language runtime assembly.
Walkthrough: Implementing Inheritance with COM
Objects (Visual Basic)
7/29/2017 • 5 min to read • Edit Online
You can derive Visual Basic classes from Public classes in COM objects, even those created in earlier versions of
Visual Basic. The properties and methods of classes inherited from COM objects can be overridden or overloaded
just as properties and methods of any other base class can be overridden or overloaded. Inheritance from COM
objects is useful when you have an existing class library that you do not want to recompile.
The following procedure shows how to use Visual Basic 6.0 to create a COM object that contains a class, and then
use it as a base class.
NOTE
Your computer might show different names or locations for some of the Visual Studio user interface elements in the
following instructions. The Visual Studio edition that you have and the settings that you use determine these elements. For
more information, see Personalizing the IDE.
Function AddNumbers(
ByVal SomeNumber As Integer,
ByVal AnotherNumber As Integer) As Integer
10. Create and register the COM object by clicking Make ComObject1.dll on the File menu.
NOTE
Although you can also expose a class created with Visual Basic as a COM object, it is not a true COM object and
cannot be used in this walkthrough. For details, see COM Interoperability in .NET Framework Applications.
Interop Assemblies
In the following procedure, you will create an interop assembly, which acts as a bridge between unmanaged code
(such as a COM object) and the managed code Visual Studio uses. The interop assembly that Visual Basic creates
handles many of the details of working with COM objects, such as interop marshaling, the process of packaging
parameters and return values into equivalent data types as they move to and from COM objects. The reference in
the Visual Basic application points to the interop assembly, not the actual COM object.
To use a COM object with Visual Basic 2005 and later versions
1. Open a new Visual Basic Windows Application project.
2. On the Project menu, click Add Reference.
The Add Reference dialog box is displayed.
3. On the COM tab, double-click ComObject1 in the Component Name list and click OK.
4. On the Project menu, click Add New Item.
The Add New Item dialog box is displayed.
5. In the Templates pane, click Class.
The default file name, Class1.vb , appears in the Name field. Change this field to MathClass.vb and click
Add. This creates a class named MathClass , and displays its code.
6. Add the following code to the top of MathClass to inherit from the COM class.
7. Overload the public method of the base class by adding the following code to MathClass :
' This method overloads the method AddNumbers from the base class.
Overloads Function AddNumbers(
ByVal SomeNumber As Integer,
ByVal AnotherNumber As Integer) As Integer
The new class inherits the properties of the base class in the COM object, overloads a method, and defines a new
method to extend the class.
To test the inherited class
1. Add a button to your startup form, and then double-click it to view its code.
2. In the button's Click event handler procedure, add the following code to create an instance of MathClass
and call the overloaded methods:
Next Steps
You may have noticed that the overloaded AddNumbers function appears to have the same data type as the
method inherited from the base class of the COM object. This is because the arguments and parameters of the
base class method are defined as 16-bit integers in Visual Basic 6.0, but they are exposed as 16-bit integers of
type Short in later versions of Visual Basic. The new function accepts 32-bit integers, and overloads the base
class function.
When working with COM objects, make sure that you verify the size and data types of parameters. For example,
when you are using a COM object that accepts a Visual Basic 6.0 collection object as an argument, you cannot
provide a collection from a later version of Visual Basic.
Properties and methods inherited from COM classes can be overridden, meaning that you can declare a local
property or method that replaces a property or method inherited from a base COM class. The rules for overriding
inherited COM properties are similar to the rules for overriding other properties and methods with the following
exceptions:
If you override any property or method inherited from a COM class, you must override all the other
inherited properties and methods.
Properties that use ByRef parameters cannot be overridden.
See Also
COM Interoperability in .NET Framework Applications
Inherits Statement
Short Data Type
Visual Basic Language Reference
7/29/2017 • 1 min to read • Edit Online
This section provides reference information for various aspects of the Visual Basic language.
In This Section
Typographic and Code Conventions
Summarizes the way that keywords, placeholders, and other elements of the language are formatted in the
Visual Basic documentation.
Visual Basic Runtime Library Members
Lists the classes and modules of the Microsoft.VisualBasic namespace, with links to their member functions,
methods, properties, constants, and enumerations.
Keywords
Lists all Visual Basic keywords and provides links to more information.
Attributes (Visual Basic)
Documents the attributes available in Visual Basic.
Constants and Enumerations
Documents the constants and enumerations available in Visual Basic.
Data Types
Documents the data types available in Visual Basic.
Directives
Documents the compiler directives available in Visual Basic.
Functions
Documents the run-time functions available in Visual Basic.
Modifiers
Lists the Visual Basic run-time modifiers and provides links to more information.
Modules
Documents the modules available in Visual Basic and their members.
Nothing
Describes the default value of any data type.
Objects
Documents the objects available in Visual Basic and their members.
Operators
Documents the operators available in Visual Basic.
Properties
Documents the properties available in Visual Basic.
Queries
Provides reference information about using Language-Integrated Query (LINQ) expressions in your code.
Statements
Documents the declaration and executable statements available in Visual Basic.
XML Comment Tags
Describes the documentation comments for which IntelliSense is provided in the Visual Basic Code Editor.
XML Axis Properties
Provides links to information about using XML axis properties to access XML directly in your code.
XML Literals
Provides links to information about using XML literals to incorporate XML directly in your code.
Error Messages
Provides a listing of Visual Basic compiler and run-time error messages and help on how to handle them.
Related Sections
Visual Basic
Provides comprehensive help on all areas of the Visual Basic language.
Visual Basic Command-Line Compiler
Describes how to use the command-line compiler as an alternative to compiling programs from within the
Visual Studio integrated development environment (IDE).
Typographic and Code Conventions (Visual Basic)
7/29/2017 • 2 min to read • Edit Online
Visual Basic documentation uses the following typographic and code conventions.
Typographic Conventions
EXAMPLE DESCRIPTION
Sub , If , ChDir , Print , True , Debug Language-specific keywords and runtime members have initial
uppercase letters and are formatted as shown in this example.
SmallProject, ButtonCollection Words and phrases you are instructed to type are formatted
as shown in this example.
Module Statement Links you can click to go to another Help page are formatted
as shown in this example.
object, variableName, argumentList Placeholders for information that you supply are formatted as
shown in this example.
{ Public | Friend | Private } In syntax, when you must make a choice between two or
more items, the items are enclosed in braces and separated by
vertical bars.
[ Protected | Friend ] In syntax, when you have the option of selecting between two
or more items, the items are enclosed in square brackets and
separated by vertical bars.
[{ ByVal | ByRef }] In syntax, when you can select no more than one item, but
you can also omit the items completely, the items are
enclosed in square brackets surrounded by braces and
separated by vertical bars.
memberName1, memberName2, memberName3 Multiple instances of the same placeholder are differentiated
by subscripts, as shown in the example.
memberNameN In code, ellipses signify code omitted for the sake of clarity.
ESC, ENTER Key names and key sequences on the keyboard appear in all
uppercase letters.
EXAMPLE DESCRIPTION
ALT+F1 When plus signs (+) appear between key names, you must
hold down one key while pressing the other. For example,
ALT+F1 means hold down the ALT key while pressing the F1
key.
Code Conventions
EXAMPLE DESCRIPTION
sampleString = "Hello, world!" Code samples appear in a fixed-pitch font and are formatted
as shown in this example.
The previous statement sets the value of sampleString to Code elements in explanatory text appear in a fixed-pitch font,
"Hello, world!" as shown in this example.
' This is a comment. Code comments are introduced by an apostrophe (') or the
REM keyword.
REM This is also a comment.
See Also
Visual Basic Language Reference
Keywords
Visual Basic Runtime Library Members
Visual Basic Naming Conventions
How to: Break and Combine Statements in Code
Comments in Code
Visual Basic Runtime Library Members
7/29/2017 • 1 min to read • Edit Online
The Microsoft.VisualBasic namespace contains the classes, modules, constants, and enumerations that
constitute the Visual Basic runtime library. These library members provide procedures, properties, and constant
values you can use in your code. Each module and class represents a particular category of functionality.
Microsoft.VisualBasic.Collection Class
Microsoft.VisualBasic.ComClassAttribute Class
Microsoft.VisualBasic.ControlChars Class
Tab VerticalTab
Microsoft.VisualBasic.Constants Class
vbYesNo vbYesNoCancel
Microsoft.VisualBasic.Conversion Module
Microsoft.VisualBasic.DateAndTime Module
WeekdayName Year
Microsoft.VisualBasic.ErrObject Class
Raise Raise
Microsoft.VisualBasic.FileSystem Module
Write WriteLine
Microsoft.VisualBasic.Financial Module
SYD
Microsoft.VisualBasic.Globals Module
Microsoft.VisualBasic.HideModuleNameAttribute Class
HideModuleNameAttribute
Microsoft.VisualBasic.Information Module
VbTypeName
Microsoft.VisualBasic.Interaction Module
Shell Switch
Microsoft.VisualBasic.MyGroupCollectionAttribute Class
Microsoft.VisualBasic.VBFixedArrayAttribute Class
Bounds Length
Microsoft.VisualBasic.VBFixedStringAttribute Class
Length
Microsoft.VisualBasic.VbMath Module
Randomize Rnd
See Also
Constants and Enumerations
Keywords
Keywords (Visual Basic)
7/29/2017 • 3 min to read • Edit Online
Reserved Keywords
The following keywords are reserved, which means that you cannot use them as names for programming
elements such as variables or procedures. You can bypass this restriction by enclosing the name in brackets (
[``] ). For more information, see "Escaped Names" in Declared Element Names.
NOTE
We do not recommend that you use escaped names, because it can make your code hard to read, and it can lead to
subtle errors that can be difficult to find.
Object Of On Operator
* *= / /=
\ \= ^ ^=
+ += - -=
NOTE
EndIf, GoSub , Variant , and Wend are retained as reserved keywords, although they are no longer used in
Visual Basic. The meaning of the Let keyword has changed. Let is now used in LINQ queries. For more
information, see Let Clause.
Unreserved Keywords
The following keywords are not reserved, which means you can use them as names for your programming
elements. However, doing this is not recommended, because it can make your code hard to read and can
lead to subtle errors that can be difficult to find.
#Region
Related Topics
TITLE DESCRIPTION
Arrays Summary Lists language elements that are used to create, define,
and use arrays.
Collection Object Summary Lists language elements that are used for collections.
Compiler Directive Summary (Visual Basic) Lists directives that control compiler behavior.
Control Flow Summary Lists statements that are used for looping and controlling
procedure flow.
Conversion Summary Lists functions that are used to convert numbers, dates,
times, and strings.
Data Types Summary Lists data types. Also lists functions that are used to
convert between data types and verify data types.
Dates and Times Summary Lists language elements that are used for dates and times.
Declarations and Constants Summary Lists statements that are used to declare variables,
constants, classes, modules, and other programming
elements. Also lists language elements that are used to
obtain object information, handle events, and implement
inheritance.
Directories and Files Summary Lists functions that are used to control the file system and
to process files.
Errors Summary Lists language elements that are used to catch and return
run-time error values.
Input and Output Summary Lists functions that are used to read from and write to
files, manage files, and print output.
Information and Interaction Summary Lists functions that are used to run other programs, obtain
command-line arguments, manipulate COM objects,
retrieve color information, and use control dialog boxes.
Math Summary Lists functions that are used to perform trigonometric and
other mathematical calculations.
Registry Summary Lists functions that are used to read, save, and delete
program settings.
TITLE DESCRIPTION
String Manipulation Summary Lists functions that are used to manipulate strings.
See Also
Visual Basic Runtime Library Members
Arrays Summary (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
Visual Basic language keywords and run-time library members are organized by purpose and use.
See Also
Keywords
Visual Basic Runtime Library Members
Collection Object Summary (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
Visual Basic language keywords and run-time library members are organized by purpose and use.
See Also
Keywords
Visual Basic Runtime Library Members
Control Flow Summary (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
Visual Basic language keywords and run-time library members are organized by purpose and use.
See Also
Keywords
Visual Basic Runtime Library Members
Conversion Summary (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
Visual Basic language keywords and run-time library members are organized by purpose and use.
Convert one data type to another. CBool, CByte, CDate, CDbl, CDec, CInt, CLng, CSng, CShort,
CStr, CType, Fix, Int
Convert date to day, month, weekday, or year. Day, Month, Weekday, Year
See Also
Keywords
Visual Basic Runtime Library Members
Data Types Summary (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
Visual Basic language keywords and run-time library members are organized by purpose and use.
Convert between data types CBool, CByte, CChar, CDate, CDbl, CDec, CInt, CLng, CObj,
CShort, CSng, CStr, Fix, Int
Set intrinsic data types Boolean, Byte, Char, Date, Decimal, Double, Integer, Long,
Object, Short, Single, String
See Also
Keywords
Visual Basic Runtime Library Members
Dates and Times Summary (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
Visual Basic language keywords and run-time library members are organized by purpose and use.
See Also
Keywords
Visual Basic Runtime Library Members
Declarations and Constants Summary (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
Visual Basic language keywords and run-time library members are organized by purpose and use.
Declare variables or constants. Const, Dim, Private, Protected, Public, Shadows, Shared, Static
Declare a class, delegate, enumeration, module, namespace, or Class, Delegate, Enum, Module, Namespace, Structure
structure.
Get information about an object. GetType, IsArray, IsDate, IsDBNull, IsError, IsNothing,
IsNumeric, IsReference, SystemTypeName, TypeName,
VarType, VbTypeName
See Also
Keywords
Visual Basic Runtime Library Members
Directories and Files Summary (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
Visual Basic language keywords and run-time library members are organized by purpose and use.
Using the My feature gives you greater productivity and performance in file I/O operations than using these
members. For more information, see FileSystem.
See Also
Keywords
Visual Basic Runtime Library Members
Reading from Files
Writing to Files
Creating, Deleting, and Moving Files and Directories
Parsing Text Files with the TextFieldParser Object
Errors Summary (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
Visual Basic language keywords and run-time library members are organized by purpose and use.
See Also
Keywords
Visual Basic Runtime Library Members
Financial Summary (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
Visual Basic language keywords and run-time library members are organized by purpose and use.
See Also
Keywords
Visual Basic Runtime Library Members
Information and Interaction Summary (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
Visual Basic language keywords and run-time library members are organized by purpose and use.
See Also
Keywords
Visual Basic Runtime Library Members
Input and Output Summary (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
Visual Basic language keywords and run-time library members are organized by purpose and use.
Get information about a file. EOF, FileAttr, FileDateTime, FileLen, FreeFile, GetAttr, Loc, LOF,
Seek
See Also
Keywords
Visual Basic Runtime Library Members
Math Summary (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
Visual Basic language keywords and run-time library members are organized by purpose and use.
See Also
Derived Math Functions
Keywords
Visual Basic Runtime Library Members
Derived Math Functions (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
The following table shows non-intrinsic math functions that can be derived from the intrinsic math functions of the
System.Math object. You can access the intrinsic math functions by adding Imports System.Math to your file or
project.
The My feature makes programming faster and easier by giving you intuitive access to commonly used methods,
properties, and events. This table lists the objects contained in My , and the actions that can be performed with
each.
ACTION OBJECT
Accessing application information and services. The My.Application object consists of the following classes:
Accessing the host computer and its resources, services, and My.Computer (Computer)
data.
Accessing XML Web services referenced by the current project. My.WebServices Object
See Also
Overview of the Visual Basic Application Model
Development with My
Operators Summary (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
Visual Basic language keywords and run-time library members are organized by purpose and use.
Arithmetic ^, –, *, /, \, Mod, +, =
Concatenation &, +
See Also
Keywords
Visual Basic Runtime Library Members
Registry Summary (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
Visual Studio language keywords and run-time library members are organized by purpose and use.
Using the My feature provides you with greater productivity and performance in registry operations than these
elements. For more information, see RegistryProxy.
See Also
Keywords
Visual Basic Runtime Library Members
Reading from and Writing to the Registry
String Manipulation Summary (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
Visual Basic language keywords and run-time library members are organized by purpose and use.
Work with ASCII and ANSI values. Asc, AscW, Chr, ChrW
See Also
Keywords
Visual Basic Runtime Library Members
Attributes (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
Visual Basic provides several attributes that allow objects interoperate with unmanaged code, and one attribute
that enables module members to be accessed without the module name. The following table lists the attributes
used by Visual Basic.
See Also
Attributes overview
Constants and Enumerations (Visual Basic)
7/29/2017 • 3 min to read • Edit Online
Visual Basic supplies a number of predefined constants and enumerations for developers. Constants store values
that remain constant throughout the execution of an application. Enumerations provide a convenient way to work
with sets of related constants, and to associate constant values with names.
Constants
Conditional Compilation Constants
The following table lists the predefined constants available for conditional compilation.
CONSTANT DESCRIPTION
TARGET A string representing the output type for the project or the
setting of the command-line /target option. The possible
values of TARGET are:
vbNullString Not the same as a zero-length string (""); used for calling
external procedures.
Enumerations
The following table lists and describes the enumerations provided by Visual Basic.
ENUMERATION DESCRIPTION
AppWinStyle Indicates the window style to use for the invoked program
when calling the Shell function.
BuiltInRole Indicates the type of role to check when calling the IsInRole
method.
FirstDayOfWeek Indicates the first day of the week to use when calling date-
related functions.
FirstWeekOfYear Indicates the first week of the year to use when calling date-
related functions.
UICancelOption Specifies what should be done if the user clicks Cancel during
an operation.
See Also
Visual Basic Language Reference
Visual Basic
Constants Overview
Enumerations Overview
Data Type Summary (Visual Basic)
7/29/2017 • 3 min to read • Edit Online
The following table shows the Visual Basic data types, their supporting common language runtime types, their
nominal storage allocation, and their value ranges.
4.94065645841246544E-
324 through
1.79769313486231570E+
308 † for positive values
Object Object (class) 4 bytes on 32-bit platform Any type can be stored in a
variable of type Object
8 bytes on 64-bit platform
1.401298E-45 through
3.4028235E+38 † for
positive values
User-Defined (structure) (inherits from ValueType) Depends on implementing Each member of the
platform structure has a range
determined by its data type
and independent of the
ranges of the other
members
†In scientific notation, "E" refers to a power of 10. So 3.56E+2 signifies 3.56 x 102 or 356, and 3.56E-2 signifies
3.56 / 102 or 0.0356.
NOTE
For strings containing text, use the StrConv function to convert from one text format to another.
In addition to specifying a data type in a declaration statement, you can force the data type of some
programming elements by using a type character. See Type Characters.
Memory Consumption
When you declare an elementary data type, it is not safe to assume that its memory consumption is the same
as its nominal storage allocation. This is due to the following considerations:
Storage Assignment. The common language runtime can assign storage based on the current
characteristics of the platform on which your application is executing. If memory is nearly full, it might
pack your declared elements as closely together as possible. In other cases it might align their memory
addresses to natural hardware boundaries to optimize performance.
Platform Width. Storage assignment on a 64-bit platform is different from assignment on a 32-bit
platform.
Composite Data Types
The same considerations apply to each member of a composite data type, such as a structure or an array. You
cannot rely on simply adding together the nominal storage allocations of the type's members. Furthermore,
there are other considerations, such as the following:
Overhead. Some composite types have additional memory requirements. For example, an array uses
extra memory for the array itself and also for each dimension. On a 32-bit platform, this overhead is
currently 12 bytes plus 8 bytes for each dimension. On a 64-bit platform this requirement is doubled.
Storage Layout. You cannot safely assume that the order of storage in memory is the same as your
order of declaration. You cannot even make assumptions about byte alignment, such as a 2-byte or 4-
byte boundary. If you are defining a class or structure and you need to control the storage layout of its
members, you can apply the StructLayoutAttribute attribute to the class or structure.
Object Overhead
An Object referring to any elementary or composite data type uses 4 bytes in addition to the data contained in
the data type.
See Also
StrConv
StructLayoutAttribute
Type Conversion Functions
Conversion Summary
Type Characters
Efficient Use of Data Types
Boolean Data Type (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
Holds values that can be only True or False . The keywords True and False correspond to the two states of
Boolean variables.
Remarks
Use the Boolean Data Type (Visual Basic) to contain two-state values such as true/false, yes/no, or on/off.
The default value of Boolean is False .
Boolean values are not stored as numbers, and the stored values are not intended to be equivalent to numbers.
You should never write code that relies on equivalent numeric values for True and False . Whenever possible,
you should restrict usage of Boolean variables to the logical values for which they are designed.
Type Conversions
When Visual Basic converts numeric data type values to Boolean , 0 becomes False and all other values
become True . When Visual Basic converts Boolean values to numeric types, False becomes 0 and True
becomes -1.
When you convert between Boolean values and numeric data types, keep in mind that the .NET Framework
conversion methods do not always produce the same results as the Visual Basic conversion keywords. This is
because the Visual Basic conversion retains behavior compatible with previous versions. For more information,
see "Boolean Type Does Not Convert to Numeric Type Accurately" in Troubleshooting Data Types.
Programming Tips
Negative Numbers. Boolean is not a numeric type and cannot represent a negative value. In any case,
you should not use Boolean to hold numeric values.
Type Characters. Boolean has no literal type character or identifier type character.
Framework Type. The corresponding type in the .NET Framework is the System.Boolean structure.
Example
In the following example, runningVB is a Boolean variable, which stores a simple yes/no setting.
See Also
System.Boolean
Data Types
Type Conversion Functions
Conversion Summary
Efficient Use of Data Types
Troubleshooting Data Types
CType Function
Byte data type (Visual Basic)
7/29/2017 • 2 min to read • Edit Online
Holds unsigned 8-bit (1-byte) integers that range in value from 0 through 255.
Remarks
Use the Byte data type to contain binary data.
The default value of Byte is 0.
Literal assignments
You can declare and initialize a Byte variable by assigning it a decimal literal, a hexadecimal literal, an octal literal,
or (starting with Visual Basic 2017) a binary literal. If the integral literal is outside the range of a Byte (that is, if it
is less than System.Byte.MinValue or greater than System.Byte.MaxValue), a compilation error occurs.
In the following example, integers equal to 201 that are represented as decimal, hexadecimal, and binary literals
are implicitly converted from Integer to byte values.
NOTE
You use the prefix &h or &H to denote a hexadecimal literal, the prefix &b or &B to denote a binary literal, and the
prefix &o or &O to denote an octal literal. Decimal literals have no prefix.
Starting with Visual Basic 2017, you can also use the underscore character, _ , as a digit separator to enhance
readability, as the following example shows.
Programming tips
Negative Numbers. Because Byte is an unsigned type, it cannot represent a negative number. If you use
the unary minus ( - ) operator on an expression that evaluates to type Byte , Visual Basic converts the
expression to Short first.
Format Conversions. When Visual Basic reads or writes files, or when it calls DLLs, methods, and
properties, it can automatically convert between data formats. Binary data stored in Byte variables and
arrays is preserved during such format conversions. You should not use a String variable for binary data,
because its contents can be corrupted during conversion between ANSI and Unicode formats.
Widening. The Byte data type widens to Short , UShort , Integer , UInteger , Long , ULong , Decimal ,
Single , or Double . This means you can convert Byte to any of these types without encountering a
System.OverflowException error.
Type Characters. Byte has no literal type character or identifier type character.
Framework Type. The corresponding type in the .NET Framework is the System.Byte structure.
Example
In the following example, b is a Byte variable. The statements demonstrate the range of the variable and the
application of bit-shift operators to it.
See Also
System.Byte
Data Types
Type Conversion Functions
Conversion Summary
Efficient Use of Data Types
Char Data Type (Visual Basic)
7/29/2017 • 2 min to read • Edit Online
Holds unsigned 16-bit (2-byte) code points ranging in value from 0 through 65535. Each code point, or character
code, represents a single Unicode character.
Remarks
Use the Char data type when you need to hold only a single character and do not need the overhead of String .
In some cases you can use Char() , an array of Char elements, to hold multiple characters.
The default value of Char is the character with a code point of 0.
Unicode Characters
The first 128 code points (0–127) of Unicode correspond to the letters and symbols on a standard U.S. keyboard.
These first 128 code points are the same as those the ASCII character set defines. The second 128 code points
(128–255) represent special characters, such as Latin-based alphabet letters, accents, currency symbols, and
fractions. Unicode uses the remaining code points (256-65535) for a wide variety of symbols, including worldwide
textual characters, diacritics, and mathematical and technical symbols.
You can use methods like IsDigit and IsPunctuation on a Char variable to determine its Unicode classification.
Type Conversions
Visual Basic does not convert directly between Char and the numeric types. You can use the Asc or AscW function
to convert a Char value to an Integer that represents its code point. You can use the Chr or ChrW function to
convert an Integer value to a Char that has that code point.
If the type checking switch (Option Strict Statement) is on, you must append the literal type character to a single-
character string literal to identify it as the Char data type. The following example illustrates this.
Option Strict On
Dim charVar As Char
' The following statement attempts to convert a String literal to Char.
' Because Option Strict is On, it generates a compiler error.
charVar = "Z"
' The following statement succeeds because it specifies a Char literal.
charVar = "Z"C
Programming Tips
Negative Numbers. Char is an unsigned type and cannot represent a negative value. In any case, you
should not use Char to hold numeric values.
Interop Considerations. If you interface with components not written for the .NET Framework, for
example Automation or COM objects, remember that character types have a different data width (8 bits) in
other environments. If you pass an 8-bit argument to such a component, declare it as Byte instead of
Char in your new Visual Basic code.
Widening. The Char data type widens to String . This means you can convert Char to String and will
not encounter a System.OverflowException error.
Type Characters. Appending the literal type character C to a single-character string literal forces it to the
Char data type. Char has no identifier type character.
Framework Type. The corresponding type in the .NET Framework is the System.Char structure.
See Also
System.Char
Asc
AscW
Chr
ChrW
Data Types
String Data Type
Type Conversion Functions
Conversion Summary
How to: Call a Windows Function that Takes Unsigned Types
Efficient Use of Data Types
Date Data Type (Visual Basic)
7/29/2017 • 3 min to read • Edit Online
Holds IEEE 64-bit (8-byte) values that represent dates ranging from January 1 of the year 0001 through December
31 of the year 9999, and times from 12:00:00 AM (midnight) through 11:59:59.9999999 PM. Each increment
represents 100 nanoseconds of elapsed time since the beginning of January 1 of the year 1 in the Gregorian
calendar. The maximum value represents 100 nanoseconds before the beginning of January 1 of the year 10000.
Remarks
Use the Date data type to contain date values, time values, or date and time values.
The default value of Date is 0:00:00 (midnight) on January 1, 0001.
You can get the current date and time from the DateAndTime class.
Format Requirements
You must enclose a Date literal within number signs ( # # ). You must specify the date value in the format
M/d/yyyy, for example #5/31/1993# , or yyyy-MM-dd, for example #1993-5-31# . You can use slashes when
specifying the year first. This requirement is independent of your locale and your computer's date and time format
settings.
The reason for this restriction is that the meaning of your code should never change depending on the locale in
which your application is running. Suppose you hard-code a Date literal of #3/4/1998# and intend it to mean
March 4, 1998. In a locale that uses mm/dd/yyyy, 3/4/1998 compiles as you intend. But suppose you deploy your
application in many countries. In a locale that uses dd/mm/yyyy, your hard-coded literal would compile to April 3,
1998. In a locale that uses yyyy/mm/dd, the literal would be invalid (April 1998, 0003) and cause a compiler error.
Workarounds
To convert a Date literal to the format of your locale, or to a custom format, supply the literal to the Format
function, specifying either a predefined or user-defined date format. The following example demonstrates this.
Alternatively, you can use one of the overloaded constructors of the DateTime structure to assemble a date and
time value. The following example creates a value to represent May 31, 1993 at 12:14 in the afternoon.
Hour Format
You can specify the time value in either 12-hour or 24-hour format, for example #1:15:30 PM# or #13:15:30# .
However, if you do not specify either the minutes or the seconds, you must specify AM or PM.
Type Conversions
If you convert a Date value to the String type, Visual Basic renders the date according to the short date format
specified by the run-time locale, and it renders the time according to the time format (either 12-hour or 24-hour)
specified by the run-time locale.
Programming Tips
Interop Considerations. If you are interfacing with components not written for the .NET Framework, for
example Automation or COM objects, keep in mind that date/time types in other environments are not
compatible with the Visual Basic Date type. If you are passing a date/time argument to such a component,
declare it as Double instead of Date in your new Visual Basic code, and use the conversion methods
System.DateTime.FromOADate and System.DateTime.ToOADate.
Type Characters. Date has no literal type character or identifier type character. However, the compiler
treats literals enclosed within number signs ( # # ) as Date .
Framework Type. The corresponding type in the .NET Framework is the System.DateTime structure.
Example
A variable or constant of the Date data type holds both the date and the time. The following example illustrates
this.
See Also
System.DateTime
Data Types
Standard Date and Time Format Strings
Custom Date and Time Format Strings
Type Conversion Functions
Conversion Summary
Efficient Use of Data Types
Decimal Data Type (Visual Basic)
7/29/2017 • 2 min to read • Edit Online
Holds signed 128-bit (16-byte) values representing 96-bit (12-byte) integer numbers scaled by a variable power
of 10. The scaling factor specifies the number of digits to the right of the decimal point; it ranges from 0 through
28. With a scale of 0 (no decimal places), the largest possible value is +/-
79,228,162,514,264,337,593,543,950,335 (+/-7.9228162514264337593543950335E+28). With 28 decimal
places, the largest value is +/-7.9228162514264337593543950335, and the smallest nonzero value is +/-
0.0000000000000000000000000001 (+/-1E-28).
Remarks
The Decimal data type provides the greatest number of significant digits for a number. It supports up to 29
significant digits and can represent values in excess of 7.9228 x 10^28. It is particularly suitable for calculations,
such as financial, that require a large number of digits but cannot tolerate rounding errors.
The default value of Decimal is 0.
Programming Tips
Precision. Decimal is not a floating-point data type. The Decimal structure holds a binary integer value,
together with a sign bit and an integer scaling factor that specifies what portion of the value is a decimal
fraction. Because of this, Decimal numbers have a more precise representation in memory than floating-
point types ( Single and Double ).
Performance. The Decimal data type is the slowest of all the numeric types. You should weigh the
importance of precision against performance before choosing a data type.
Widening. The Decimal data type widens to Single or Double . This means you can convert Decimal to
either of these types without encountering a System.OverflowException error.
Trailing Zeros. Visual Basic does not store trailing zeros in a Decimal literal. However, a Decimal variable
preserves any trailing zeros acquired computationally. The following example illustrates this.
Range
You might need to use the D type character to assign a large value to a Decimal variable or constant. This
requirement is because the compiler interprets a literal as Long unless a literal type character follows the literal,
as the following example shows.
The declaration for bigDec1 doesn't produce an overflow because the value that's assigned to it falls within the
range for Long . The Long value can be assigned to the Decimal variable.
The declaration for bigDec2 generates an overflow error because the value that's assigned to it is too large for
Long . Because the numeric literal can't first be interpreted as a Long , it can't be assigned to the Decimal
variable.
For bigDec3 , the literal type character D solves the problem by forcing the compiler to interpret the literal as a
Decimal instead of as a Long .
See Also
System.Decimal
System.Decimal.Decimal
System.Math.Round
Data Types
Single Data Type
Double Data Type
Type Conversion Functions
Conversion Summary
Efficient Use of Data Types
Double Data Type (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
Holds signed IEEE 64-bit (8-byte) double-precision floating-point numbers that range in value from -
1.79769313486231570E+308 through -4.94065645841246544E-324 for negative values and from
4.94065645841246544E-324 through 1.79769313486231570E+308 for positive values. Double-precision
numbers store an approximation of a real number.
Remarks
The Double data type provides the largest and smallest possible magnitudes for a number.
The default value of Double is 0.
Programming Tips
Precision. When you work with floating-point numbers, remember that they do not always have a
precise representation in memory. This could lead to unexpected results from certain operations, such as
value comparison and the Mod operator. For more information, see Troubleshooting Data Types.
Trailing Zeros. The floating-point data types do not have any internal representation of trailing zero
characters. For example, they do not distinguish between 4.2000 and 4.2. Consequently, trailing zero
characters do not appear when you display or print floating-point values.
Type Characters. Appending the literal type character R to a literal forces it to the Double data type. For
example, if an integer value is followed by R , the value is changed to a Double .
' Visual Basic expands the 4 in the statement Dim dub As Double = 4R to 4.0:
Dim dub As Double = 4.0R
Appending the identifier type character # to any identifier forces it to Double . In the following example,
the variable num is typed as a Double :
Dim num# = 3
Framework Type. The corresponding type in the .NET Framework is the System.Double structure.
See Also
System.Double
Data Types
Decimal Data Type
Single Data Type
Type Conversion Functions
Conversion Summary
Efficient Use of Data Types
Troubleshooting Data Types
Type Characters
Integer data type (Visual Basic)
7/29/2017 • 2 min to read • Edit Online
Holds signed 32-bit (4-byte) integers that range in value from -2,147,483,648 through 2,147,483,647.
Remarks
The Integer data type provides optimal performance on a 32-bit processor. The other integral types are slower
to load and store from and to memory.
The default value of Integer is 0.
Literal assignments
You can declare and initialize an Integer variable by assigning it a decimal literal, a hexadecimal literal, an octal
literal, or (starting with Visual Basic 2017) a binary literal. If the integer literal is outside the range of Integer
(that is, if it is less than System.Int32.MinValue or greater than System.Int32.MaxValue, a compilation error
occurs.
In the following example, integers equal to 16,342 that are represented as decimal, hexadecimal, and binary
literals are assigned to Integer values.
NOTE
You use the prefix &h or &H to denote a hexadecimal literal, the prefix &b or &B to denote a binary literal, and the
prefix &o or &O to denote an octal literal. Decimal literals have no prefix.
Starting with Visual Basic 2017, you can also use the underscore character, _ , as a digit separator to enhance
readability, as the following example shows.
Dim intValue1 As Integer = 90_946
Console.WriteLine(intValue1)
Numeric literals can also include the I type character to denote the Integer data type, as the following
example shows.
Programming tips
Interop Considerations. If you are interfacing with components not written for the .NET Framework,
such as Automation or COM objects, remember that Integer has a different data width (16 bits) in other
environments. If you are passing a 16-bit argument to such a component, declare it as Short instead of
Integer in your new Visual Basic code.
Widening. The Integer data type widens to Long , Decimal , Single , or Double . This means you can
convert Integer to any one of these types without encountering a System.OverflowException error.
Type Characters. Appending the literal type character I to a literal forces it to the Integer data type.
Appending the identifier type character % to any identifier forces it to Integer .
Framework Type. The corresponding type in the .NET Framework is the System.Int32 structure.
Range
If you try to set a variable of an integral type to a number outside the range for that type, an error occurs. If you
try to set it to a fraction, the number is rounded up or down to the nearest integer value. If the number is equally
close to two integer values, the value is rounded to the nearest even integer. This behavior minimizes rounding
errors that result from consistently rounding a midpoint value in a single direction. The following code shows
examples of rounding.
See also
System.Int32
Data Types
Long Data Type
Short Data Type
Type Conversion Functions
Conversion Summary
Efficient Use of Data Types
Long data type (Visual Basic)
7/29/2017 • 2 min to read • Edit Online
Holds signed 64-bit (8-byte) integers ranging in value from -9,223,372,036,854,775,808 through
9,223,372,036,854,775,807 (9.2...E+18).
Remarks
Use the Long data type to contain integer numbers that are too large to fit in the Integer data type.
The default value of Long is 0.
Literal assignments
You can declare and initialize a Long variable by assigning it a decimal literal, a hexadecimal literal, an octal
literal, or (starting with Visual Basic 2017) a binary literal. If the integer literal is outside the range of Long (that
is, if it is less than System.Int64.MinValue or greater than System.Int64.MaxValue, a compilation error occurs.
In the following example, integers equal to 4,294,967,296 that are represented as decimal, hexadecimal, and
binary literals are assigned to Long values.
NOTE
You use the prefix &h or &H to denote a hexadecimal literal, the prefix &b or &B to denote a binary literal, and the
prefix &o or &O to denote an octal literal. Decimal literals have no prefix.
Starting with Visual Basic 2017, you can also use the underscore character, _ , as a digit separator to enhance
readability, as the following example shows.
Dim longValue1 As Long = 4_294_967_296
Console.WriteLine(longValue1)
Numeric literals can also include the L type character to denote the Long data type, as the following example
shows.
Programming tips
Interop Considerations. If you are interfacing with components not written for the .NET Framework, for
example Automation or COM objects, remember that Long has a different data width (32 bits) in other
environments. If you are passing a 32-bit argument to such a component, declare it as Integer instead of
Long in your new Visual Basic code.
Widening. The Long data type widens to Decimal , Single , or Double . This means you can convert
Long to any one of these types without encountering a System.OverflowException error.
Type Characters. Appending the literal type character L to a literal forces it to the Long data type.
Appending the identifier type character & to any identifier forces it to Long .
Framework Type. The corresponding type in the .NET Framework is the System.Int64 structure.
See also
Int64 Data Types
Integer Data Type
Short Data Type
Type Conversion Functions
Conversion Summary
Efficient Use of Data Types
Object Data Type
7/29/2017 • 2 min to read • Edit Online
Holds addresses that refer to objects. You can assign any reference type (string, array, class, or interface) to an
Object variable. An Object variable can also refer to data of any value type (numeric, Boolean , Char , Date ,
structure, or enumeration).
Remarks
The Object data type can point to data of any data type, including any object instance your application
recognizes. Use Object when you do not know at compile time what data type the variable might point to.
The default value of Object is Nothing (a null reference).
Data Types
You can assign a variable, constant, or expression of any data type to an Object variable. To determine the data
type an Object variable currently refers to, you can use the GetTypeCode method of the System.Type class. The
following example illustrates this.
The Object data type is a reference type. However, Visual Basic treats an Object variable as a value type when it
refers to data of a value type.
Storage
Whatever data type it refers to, an Object variable does not contain the data value itself, but rather a pointer to
the value. It always uses four bytes in computer memory, but this does not include the storage for the data
representing the value of the variable. Because of the code that uses the pointer to locate the data, Object
variables holding value types are slightly slower to access than explicitly typed variables.
Programming Tips
Interop Considerations. If you are interfacing with components not written for the .NET Framework, for
example Automation or COM objects, keep in mind that pointer types in other environments are not
compatible with the Visual Basic Object type.
Performance. A variable you declare with the Object type is flexible enough to contain a reference to any
object. However, when you invoke a method or property on such a variable, you always incur late binding
(at run time). To force early binding (at compile time) and better performance, declare the variable with a
specific class name, or cast it to the specific data type.
When you declare an object variable, try to use a specific class type, for example OperatingSystem, instead
of the generalized Object type. You should also use the most specific class available, such as TextBox
instead of Control, so that you can access its properties and methods. You can usually use the Classes list
in the Object Browser to find available class names.
Widening. All data types and all reference types widen to the Object data type. This means you can
convert any type to Object without encountering a System.OverflowException error.
However, if you convert between value types and Object , Visual Basic performs operations called boxing
and unboxing, which make execution slower.
Type Characters. Object has no literal type character or identifier type character.
Framework Type. The corresponding type in the .NET Framework is the System.Object class.
Example
The following example illustrates an Object variable pointing to an object instance.
See Also
Object
Data Types
Type Conversion Functions
Conversion Summary
Efficient Use of Data Types
How to: Determine Whether Two Objects Are Related
How to: Determine Whether Two Objects Are Identical
SByte data type (Visual Basic)
7/29/2017 • 2 min to read • Edit Online
Holds signed 8-bit (1-byte) integers that range in value from -128 through 127.
Remarks
Use the SByte data type to contain integer values that do not require the full data width of Integer or even the
half data width of Short . In some cases, the common language runtime might be able to pack your SByte
variables closely together and save memory consumption.
The default value of SByte is 0.
Literal assignments
You can declare and initialize an SByte variable by assigning it a decimal literal, a hexadecimal literal, an octal
literal, or (starting with Visual Basic 2017) a binary literal.
In the following example, integers equal to -102 that are represented as decimal, hexadecimal, and binary literals
are assigned to SByte values. This example requires that you compile with the /removeintchecks compiler switch.
NOTE
You use the prefix &h or &H to denote a hexadecimal literal, the prefix &b or &B to denote a binary literal, and the
prefix &o or &O to denote an octal literal. Decimal literals have no prefix.
Starting with Visual Basic 2017, you can also use the underscore character, _ , as a digit separator to enhance
readability, as the following example shows.
If the integer literal is outside the range of SByte (that is, if it is less than System.SByte.MinValue or greater than
System.SByte.MaxValue, a compilation error occurs. When an integer literal has no suffix, an Integer is inferred. If
the integer literal is outside the range of the Integer type, a Long is inferred. This means that, in the previous
examples, the numeric literals 0x9A and 0b10011010 are interpreted as 32-bit signed integers with a value of 156,
which exceeds System.SByte.MaxValue. To successfully compile code like this that assigns a non-decimal integer
to an SByte , you can do either of the following:
Disable integer bounds checks by compiling with the /removeintchecks compiler switch.
Use a type character to explicitly define the literal value that you want to assign to the SByte . The
following example assigns a negative literal Short value to an SByte . Note that, for negative numbers, the
high-order bit of the high-order word of the numeric literal must be set. In the case of our example, this is
bit 15 of the literal Short value.
Programming tips
CLS Compliance. The SByte data type is not part of the Common Language Specification (CLS), so CLS-
compliant code cannot consume a component that uses it.
Widening. The SByte data type widens to Short , Integer , Long , Decimal , Single , and Double . This
means you can convert SByte to any of these types without encountering a System.OverflowException
error.
Type Characters. SByte has no literal type character or identifier type character.
Framework Type. The corresponding type in the .NET Framework is the System.SByte structure.
See also
System.SByte
Data Types
Type Conversion Functions
Conversion Summary
Short Data Type
Integer Data Type
Long Data Type
Efficient Use of Data Types
Short data type (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
Holds signed 16-bit (2-byte) integers that range in value from -32,768 through 32,767.
Remarks
Use the Short data type to contain integer values that do not require the full data width of Integer . In some
cases, the common language runtime can pack your Short variables closely together and save memory
consumption.
The default value of Short is 0.
Literal assignments
You can declare and initialize a Short variable by assigning it a decimal literal, a hexadecimal literal, an octal
literal, or (starting with Visual Basic 2017) a binary literal. If the integer literal is outside the range of Short (that
is, if it is less than System.Int16.MinValue or greater than System.Int16.MaxValue, a compilation error occurs.
In the following example, integers equal to 1,034 that are represented as decimal, hexadecimal, and binary literals
are implicitly converted from Integer to Short values.
NOTE
You use the prefix &h or &H to denote a hexadecimal literal, the prefix &b or &B to denote a binary literal, and the
prefix &o or &O to denote an octal literal. Decimal literals have no prefix.
Starting with Visual Basic 2017, you can also use the underscore character, _ , as a digit separator to enhance
readability, as the following example shows.
Programming tips
Widening. The Short data type widens to Integer , Long , Decimal , Single , or Double . This means you
can convert Short to any one of these types without encountering a System.OverflowException error.
Type Characters. Appending the literal type character S to a literal forces it to the Short data type.
Short has no identifier type character.
Framework Type. The corresponding type in the .NET Framework is the System.Int16 structure.
See also
System.Int16
Data Types
Type Conversion Functions
Conversion Summary
Integer Data Type
Long Data Type
Efficient Use of Data Types
Single Data Type (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
Holds signed IEEE 32-bit (4-byte) single-precision floating-point numbers ranging in value from -3.4028235E+38
through -1.401298E-45 for negative values and from 1.401298E-45 through 3.4028235E+38 for positive values.
Single-precision numbers store an approximation of a real number.
Remarks
Use the Single data type to contain floating-point values that do not require the full data width of Double . In
some cases the common language runtime might be able to pack your Single variables closely together and
save memory consumption.
The default value of Single is 0.
Programming Tips
Precision. When you work with floating-point numbers, keep in mind that they do not always have a
precise representation in memory. This could lead to unexpected results from certain operations, such as
value comparison and the Mod operator. For more information, see Troubleshooting Data Types.
Widening. The Single data type widens to Double . This means you can convert Single to Double
without encountering a System.OverflowException error.
Trailing Zeros. The floating-point data types do not have any internal representation of trailing 0
characters. For example, they do not distinguish between 4.2000 and 4.2. Consequently, trailing 0
characters do not appear when you display or print floating-point values.
Type Characters. Appending the literal type character F to a literal forces it to the Single data type.
Appending the identifier type character ! to any identifier forces it to Single .
Framework Type. The corresponding type in the .NET Framework is the System.Single structure.
See Also
System.Single
Data Types
Decimal Data Type
Double Data Type
Type Conversion Functions
Conversion Summary
Efficient Use of Data Types
Troubleshooting Data Types
String Data Type (Visual Basic)
7/29/2017 • 3 min to read • Edit Online
Holds sequences of unsigned 16-bit (2-byte) code points that range in value from 0 through 65535. Each code
point, or character code, represents a single Unicode character. A string can contain from 0 to approximately two
billion (2 ^ 31) Unicode characters.
Remarks
Use the String data type to hold multiple characters without the array management overhead of Char() , an
array of Char elements.
The default value of String is Nothing (a null reference). Note that this is not the same as the empty string
(value "" ).
Unicode Characters
The first 128 code points (0–127) of Unicode correspond to the letters and symbols on a standard U.S. keyboard.
These first 128 code points are the same as those the ASCII character set defines. The second 128 code points
(128–255) represent special characters, such as Latin-based alphabet letters, accents, currency symbols, and
fractions. Unicode uses the remaining code points (256-65535) for a wide variety of symbols. This includes
worldwide textual characters, diacritics, and mathematical and technical symbols.
You can use methods such as IsDigit and IsPunctuation on an individual character in a String variable to
determine its Unicode classification.
Format Requirements
You must enclose a String literal within quotation marks ( " " ). If you must include a quotation mark as one of
the characters in the string, you use two contiguous quotation marks ( "" ). The following example illustrates this.
Note that the contiguous quotation marks that represent a quotation mark in the string are independent of the
quotation marks that begin and end the String literal.
String Manipulations
Once you assign a string to a String variable, that string is immutable, which means you cannot change its
length or contents. When you alter a string in any way, Visual Basic creates a new string and abandons the
previous one. The String variable then points to the new string.
You can manipulate the contents of a String variable by using a variety of string functions. The following
example illustrates the Left function
Dim S As String = "Database"
' The following statement sets S to a new string containing "Data".
S = Microsoft.VisualBasic.Left(S, 4)
A string created by another component might be padded with leading or trailing spaces. If you receive such a
string, you can use the Trim, LTrim, and RTrim functions to remove these spaces.
For more information about string manipulations, see Strings.
Programming Tips
Negative Numbers. Remember that the characters held by String are unsigned and cannot represent
negative values. In any case, you should not use String to hold numeric values.
Interop Considerations. If you are interfacing with components not written for the .NET Framework, for
example Automation or COM objects, remember that string characters have a different data width (8 bits)
in other environments. If you are passing a string argument of 8-bit characters to such a component,
declare it as Byte() , an array of Byte elements, instead of String in your new Visual Basic code.
Type Characters. Appending the identifier type character $ to any identifier forces it to the String data
type. String has no literal type character. However, the compiler treats literals enclosed in quotation
marks ( " " ) as String .
Framework Type. The corresponding type in the .NET Framework is the System.String class.
See Also
System.String
Data Types
Char Data Type
Type Conversion Functions
Conversion Summary
How to: Call a Windows Function that Takes Unsigned Types
Efficient Use of Data Types
UInteger data type
7/29/2017 • 2 min to read • Edit Online
Holds unsigned 32-bit (4-byte) integers ranging in value from 0 through 4,294,967,295.
Remarks
The UInteger data type provides the largest unsigned value in the most efficient data width.
The default value of UInteger is 0.
Literal assignments
You can declare and initialize a UInteger variable by assigning it a decimal literal, a hexadecimal literal, an octal
literal, or (starting with Visual Basic 2017) a binary literal. If the integer literal is outside the range of UInteger
(that is, if it is less than System.UInt32.MinValue or greater than System.UInt32.MaxValue, a compilation error
occurs.
In the following example, integers equal to 3,000,000,000 that are represented as decimal, hexadecimal, and
binary literals are assigned to UInteger values.
NOTE
You use the prefix &h or &H to denote a hexadecimal literal, the prefix &b or &B to denote a binary literal, and the
prefix &o or &O to denote an octal literal. Decimal literals have no prefix.
Starting with Visual Basic 2017, you can also use the underscore character, _ , as a digit separator to enhance
readability, as the following example shows.
Dim uintValue1 As UInteger = 3_000_000_000ui
Console.WriteLine(uintValue1)
Numeric literals can also include the UI or ui type character to denote the UInteger data type, as the following
example shows.
Programming tips
The UInteger and Integer data types provide optimal performance on a 32-bit processor, because the smaller
integer types ( UShort , Short , Byte , and SByte ), even though they use fewer bits, take more time to load, store,
and fetch.
Negative Numbers. Because UInteger is an unsigned type, it cannot represent a negative number. If you
use the unary minus ( - ) operator on an expression that evaluates to type UInteger , Visual Basic converts
the expression to Long first.
CLS Compliance. The UInteger data type is not part of the Common Language Specification (CLS), so
CLS-compliant code cannot consume a component that uses it.
Interop Considerations. If you are interfacing with components not written for the .NET Framework, for
example Automation or COM objects, keep in mind that types such as uint can have a different data
width (16 bits) in other environments. If you are passing a 16-bit argument to such a component, declare it
as UShort instead of UInteger in your managed Visual Basic code.
Widening. The UInteger data type widens to Long , ULong , Decimal , Single , and Double . This means
you can convert UInteger to any of these types without encountering a System.OverflowException error.
Type Characters. Appending the literal type characters UI to a literal forces it to the UInteger data type.
UInteger has no identifier type character.
Framework Type. The corresponding type in the .NET Framework is the System.UInt32 structure.
See Also
UInt32
Data Types
Type Conversion Functions
Conversion Summary
How to: Call a Windows Function that Takes Unsigned Types
Efficient Use of Data Types
ULong data type (Visual Basic)
7/29/2017 • 2 min to read • Edit Online
Holds unsigned 64-bit (8-byte) integers ranging in value from 0 through 18,446,744,073,709,551,615 (more than
1.84 times 10 ^ 19).
Remarks
Use the ULong data type to contain binary data too large for UInteger , or the largest possible unsigned integer
values.
The default value of ULong is 0.
Literal assignments
You can declare and initialize a ULong variable by assigning it a decimal literal, a hexadecimal literal, an octal
literal, or (starting with Visual Basic 2017) a binary literal. If the integer literal is outside the range of ULong (that
is, if it is less than System.UInt64.MinValue or greater than System.UInt64.MaxValue, a compilation error occurs.
In the following example, integers equal to 7,934,076,125 that are represented as decimal, hexadecimal, and
binary literals are assigned to ULong values.
NOTE
You use the prefix &h or &H to denote a hexadecimal literal, the prefix &b or &B to denote a binary literal, and the
prefix &o or &O to denote an octal literal. Decimal literals have no prefix.
Starting with Visual Basic 2017, you can also use the underscore character, _ , as a digit separator to enhance
readability, as the following example shows.
Dim longValue1 As Long = 4_294_967_296
Console.WriteLine(longValue1)
Numeric literals can also include the UL or ul type character to denote the ULong data type, as the following
example shows.
Programming tips
Negative Numbers. Because ULong is an unsigned type, it cannot represent a negative number. If you
use the unary minus ( - ) operator on an expression that evaluates to type ULong , Visual Basic converts the
expression to Decimal first.
CLS Compliance. The ULong data type is not part of the Common Language Specification (CLS), so CLS-
compliant code cannot consume a component that uses it.
Interop Considerations. If you are interfacing with components not written for the .NET Framework, for
example Automation or COM objects, keep in mind that types such as ulong can have a different data
width (32 bits) in other environments. If you are passing a 32-bit argument to such a component, declare it
as UInteger instead of ULong in your managed Visual Basic code.
Furthermore, Automation does not support 64-bit integers on Windows 95, Windows 98, Windows ME, or
Windows 2000. You cannot pass a Visual Basic ULong argument to an Automation component on these
platforms.
Widening. The ULong data type widens to Decimal , Single , and Double . This means you can convert
ULong to any of these types without encountering a System.OverflowException error.
Type Characters. Appending the literal type characters UL to a literal forces it to the ULong data type.
ULong has no identifier type character.
Framework Type. The corresponding type in the .NET Framework is the System.UInt64 structure.
See also
UInt64
Data Types
Type Conversion Functions
Conversion Summary
How to: Call a Windows Function that Takes Unsigned Types
Efficient Use of Data Types
User-Defined Data Type
7/29/2017 • 2 min to read • Edit Online
Holds data in a format you define. The Structure statement defines the format.
Previous versions of Visual Basic support the user-defined type (UDT). The current version expands the UDT to a
structure. A structure is a concatenation of one or more members of various data types. Visual Basic treats a
structure as a single unit, although you can also access its members individually.
Remarks
Define and use a structure data type when you need to combine various data types into a single unit, or when none
of the elementary data types serve your needs.
The default value of a structure data type consists of the combination of the default values of each of its members.
Declaration Format
A structure declaration starts with the Structure Statement and ends with the End``Structure statement. The
Structure statement supplies the name of the structure, which is also the identifier of the data type the structure is
defining. Other parts of the code can use this identifier to declare variables, parameters, and function return values
to be of this structure's data type.
The declarations between the Structure and End``Structure statements define the members of the structure.
Programming Tips
Memory Consumption. As with all composite data types, you cannot safely calculate the total memory
consumption of a structure by adding together the nominal storage allocations of its members. Furthermore,
you cannot safely assume that the order of storage in memory is the same as your order of declaration. If
you need to control the storage layout of a structure, you can apply the StructLayoutAttribute attribute to the
Structure statement.
Interop Considerations. If you are interfacing with components not written for the .NET Framework, for
example Automation or COM objects, keep in mind that user-defined types in other environments are not
compatible with Visual Basic structure types.
Widening. There is no automatic conversion to or from any structure data type. You can define conversion
operators on your structure using the Operator Statement, and you can declare each conversion operator to
be Widening or Narrowing .
Type Characters. Structure data types have no literal type character or identifier type character.
Framework Type. There is no corresponding type in the .NET Framework. All structures inherit from the
.NET Framework class System.ValueType, but no individual structure corresponds to System.ValueType.
Example
The following paradigm shows the outline of the declaration of a structure.
See Also
ValueType
StructLayoutAttribute
Data Types
Type Conversion Functions
Conversion Summary
Structure Statement
Widening
Narrowing
Structures
Efficient Use of Data Types
UShort data type (Visual Basic)
7/29/2017 • 2 min to read • Edit Online
Holds unsigned 16-bit (2-byte) integers ranging in value from 0 through 65,535.
Remarks
Use the UShort data type to contain binary data too large for Byte .
The default value of UShort is 0.
Literal assignments
You can declare and initialize a UShort variable by assigning it a decimal literal, a hexadecimal literal, an octal
literal, or (starting with Visual Basic 2017) a binary literal. If the integer literal is outside the range of UShort (that
is, if it is less than System.UInt16.MinValue or greater than System.UInt16.MaxValue, a compilation error occurs.
In the following example, integers equal to 65,034 that are represented as decimal, hexadecimal, and binary
literals are assigned to UShort values.
NOTE
You use the prefix &h or &H to denote a hexadecimal literal, the prefix &b or &B to denote a binary literal, and the
prefix &o or &O to denote an octal literal. Decimal literals have no prefix.
Starting with Visual Basic 2017, you can also use the underscore character, _ , as a digit separator to enhance
readability, as the following example shows.
Numeric literals can also include the US or us type character to denote the UShort data type, as the following
example shows.
Dim number = &H035826us
Programming tips
Negative Numbers. Because UShort is an unsigned type, it cannot represent a negative number. If you
use the unary minus ( - ) operator on an expression that evaluates to type UShort , Visual Basic converts
the expression to Integer first.
CLS Compliance. The UShort data type is not part of the Common Language Specification (CLS), so CLS-
compliant code cannot consume a component that uses it.
Widening. The UShort data type widens to Integer , UInteger , Long , ULong , Decimal , Single , and
Double . This means you can convert UShort to any of these types without encountering a
System.OverflowException error.
Type Characters. Appending the literal type characters US to a literal forces it to the UShort data type.
UShort has no identifier type character.
Framework Type. The corresponding type in the .NET Framework is the System.UInt16 structure.
See Also
UInt16
Data Types
Type Conversion Functions
Conversion Summary
How to: Call a Windows Function that Takes Unsigned Types
Efficient Use of Data Types
Directives (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
The topics in this section document the Visual Basic source code compiler directives.
In This Section
#Const Directive -- Define a compiler constant
#ExternalSource Directive -- Indicate a mapping between source lines and text external to the source
#If...Then...#Else Directives -- Compile selected blocks of code
#Region Directive -- Collapse and hide sections of code in the Visual Studio editor
#Disable, #Enable -- Disable and enable specific warnings for regions of code.
#Disable Warning BC42356 ' suppress warning about no awaits in this method
Async Function TestAsync() As Task
Console.WriteLine("testing")
End Function
#Enable Warning BC42356
You can disable and enable a comma-separated list of warning codes too.
Related Sections
Visual Basic Language Reference
Visual Basic
#Const Directive
7/29/2017 • 1 min to read • Edit Online
Syntax
#Const constname = expression
Parts
constname
Required. Name of the constant being defined.
expression
Required. Literal, other conditional compiler constant, or any combination that includes any or all arithmetic or
logical operators except Is .
Remarks
Conditional compiler constants are always private to the file in which they appear. You cannot create public
compiler constants using the #Const directive; you can create them only in the user interface or with the /define
compiler option.
You can use only conditional compiler constants and literals in expression . Using a standard constant defined
with Const causes an error. Conversely, you can use constants defined with the #Const keyword only for
conditional compilation. Constants can also be undefined, in which case they have a value of Nothing .
Example
This example uses the #Const directive.
See Also
/define (Visual Basic)
#If...Then...#Else Directives
Const Statement
Conditional Compilation
If...Then...Else Statement
#ExternalSource Directive
7/29/2017 • 1 min to read • Edit Online
Indicates a mapping between specific lines of source code and text external to the source.
Syntax
#ExternalSource( StringLiteral , IntLiteral )
[ LogicalLine+ ]
#End ExternalSource
Parts
StringLiteral
The path to the external source.
IntLiteral
The line number of the first line of the external source.
LogicalLine
The line where the error occurs in the external source.
#End ExternalSource
Terminates the #ExternalSource block.
Remarks
This directive is used only by the compiler and the debugger.
A source file may include external source directives, which indicate a mapping between specific lines of code in the
source file and text external to the source, such as an .aspx file. If errors are encountered in the designated source
code during compilation, they are identified as coming from the external source.
External source directives have no effect on compilation and cannot be nested. They are intended for internal use
by the application only.
See Also
Conditional Compilation
#If...Then...#Else Directives
7/29/2017 • 1 min to read • Edit Online
Syntax
#If expression Then
statements
[ #ElseIf expression Then
[ statements ]
...
#ElseIf expression Then
[ statements ] ]
[ #Else
[ statements ] ]
#End If
Parts
expression
Required for #If and #ElseIf statements, optional elsewhere. Any expression, consisting exclusively of one or
more conditional compiler constants, literals, and operators, that evaluates to True or False .
statements
Required for #If statement block, optional elsewhere. Visual Basic program lines or compiler directives that are
compiled if the associated expression evaluates to True .
#End If
Terminates the #If statement block.
Remarks
On the surface, the behavior of the #If...Then...#Else directives appears the same as that of the
If...Then...Else statements. However, the #If...Then...#Else directives evaluate what is compiled by the
compiler, whereas the If...Then...Else statements evaluate conditions at run time.
Conditional compilation is typically used to compile the same program for different platforms. It is also used to
prevent debugging code from appearing in an executable file. Code excluded during conditional compilation is
completely omitted from the final executable file, so it has no effect on size or performance.
Regardless of the outcome of any evaluation, all expressions are evaluated using Option Compare Binary . The
Option Compare statement does not affect expressions in #If and #ElseIf statements.
NOTE
No single-line form of the #If , #Else , #ElseIf , and #End If directives exists. No other code can appear on the
same line as any of the directives.
Example
This example uses the #If...Then...#Else construct to determine whether to compile certain statements.
#Const CustomerNumber = 36
#If CustomerNumber = 35 Then
' Insert code to be compiled for customer # 35.
#ElseIf CustomerNumber = 36 Then
' Insert code to be compiled for customer # 36.
#Else
' Insert code to be compiled for all other customers.
#End If
See Also
#Const Directive
If...Then...Else Statement
Conditional Compilation
#Region Directive
7/29/2017 • 1 min to read • Edit Online
Syntax
#Region "identifier_string"
#End Region
Parts
TERM DEFINITION
Remarks
Use the #Region directive to specify a block of code to expand or collapse when using the outlining feature of the
Visual Studio Code Editor. You can place, or nest, regions within other regions to group similar regions together.
Example
This example uses the #Region directive.
#Region "MathFunctions"
' Insert code for the Math functions here.
#End Region
See Also
#If...Then...#Else Directives
Outlining
How to: Collapse and Hide Sections of Code
Functions (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
The topics in this section contain tables of the Visual Basic run-time member functions.
NOTE
You can also create functions and call them. For more information, see Function Statement and How to: Create a Procedure
that Returns a Value.
In This Section
Conversion Functions
Math Functions
String Functions
Type Conversion Functions
CType Function
Related Sections
Visual Basic Language Reference
Visual Basic
Conversion functions (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
Asc
AscW
CBool Function
CByte Function
CChar Function
CDate Function
CDbl Function
CDec Function
Chr
ChrW
CInt Function
CLng Function
CObj Function
CSByte Function
CShort Function
CSng Function
CStr Function
CType Function
CUInt Function
CULng Function
CUShort Function
Format
Hex
Oct
Str
Val
See also
Type Conversion Functions
Converting Data Types
Math Functions (Visual Basic)
7/29/2017 • 3 min to read • Edit Online
The methods of the System.Math class provide trigonometric, logarithmic, and other common mathematical
functions.
Remarks
The following table lists methods of the System.Math class. You can use these in a Visual Basic program.
Ceiling Returns the smallest integral value that's greater than or equal
to the specified Decimal or Double .
Floor Returns the largest integer that's less than or equal to the
specified Decimal or Double number.
To use these functions without qualification, import the System.Math namespace into your project by adding the
following code to the top of your source file:
Imports System.Math
Example
This example uses the Abs method of the Math class to compute the absolute value of a number.
Example
This example uses the Atan method of the Math class to calculate the value of pi.
Example
This example uses the Cos method of the Math class to return the cosine of an angle.
Public Function Sec(ByVal angle As Double) As Double
' Calculate the secant of angle, in radians.
Return 1.0 / Math.Cos(angle)
End Function
Example
This example uses the Exp method of the Math class to return e raised to a power.
Example
This example uses the Log method of the Math class to return the natural logarithm of a number.
Example
This example uses the Round method of the Math class to round a number to the nearest integer.
' Returns 3.
Dim MyVar2 As Double = Math.Round(2.8)
Example
This example uses the Sign method of the Math class to determine the sign of a number.
' Returns 1.
Dim MySign1 As Integer = Math.Sign(12)
' Returns -1.
Dim MySign2 As Integer = Math.Sign(-2.4)
' Returns 0.
Dim MySign3 As Integer = Math.Sign(0)
Example
This example uses the Sin method of the Math class to return the sine of an angle.
Example
This example uses the Sqrt method of the Math class to calculate the square root of a number.
' Returns 2.
Dim MySqr1 As Double = Math.Sqrt(4)
' Returns 4.79583152331272.
Dim MySqr2 As Double = Math.Sqrt(23)
' Returns 0.
Dim MySqr3 As Double = Math.Sqrt(0)
' Returns NaN (not a number).
Dim MySqr4 As Double = Math.Sqrt(-4)
Example
This example uses the Tan method of the Math class to return the tangent of an angle.
Requirements
Class: Math
Namespace: System
Assembly: mscorlib (in mscorlib.dll)
See Also
Rnd
Randomize
NaN
Derived Math Functions
Arithmetic Operators
String Functions (Visual Basic)
7/29/2017 • 5 min to read • Edit Online
The following table lists the functions that Visual Basic provides to search and manipulate strings.
Chr, ChrW Returns the character associated with the specified character
code.
You can use the Option Compare statement to set whether strings are compared using a case-insensitive text sort
order determined by your system's locale ( Text ) or by the internal binary representations of the characters (
Binary ). The default text comparison method is Binary .
Example
This example uses the UCase function to return an uppercase version of a string.
Example
This example uses the LTrim function to strip leading spaces and the RTrim function to strip trailing spaces from a
string variable. It uses the Trim function to strip both types of spaces.
Example
This example uses the Mid function to return a specified number of characters from a string.
Example
This example uses Len to return the number of characters in a string.
Example
This example uses the InStr function to return the position of the first occurrence of one string within another.
' String to search in.
Dim SearchString As String = "XXpXXpXXPXXP"
' Search for "P".
Dim SearchChar As String = "P"
' Returns 0.
TestPos = InStr(1, SearchString, "W")
Example
This example shows various uses of the Format function to format values using both String formats and user-
defined formats. For the date separator ( / ), time separator ( : ), and the AM/PM indicators ( t and tt ), the
actual formatted output displayed by your system depends on the locale settings the code is using. When times
and dates are displayed in the development environment, the short time format and short date format of the code
locale are used.
NOTE
For locales that use a 24-hour clock, the AM/PM indicators ( t and tt ) display nothing.
These functions are compiled inline, meaning the conversion code is part of the code that
evaluates the expression. Sometimes there is no call to a procedure to accomplish the
conversion, which improves performance. Each function coerces an expression to a specific
data type.
Syntax
CBool(expression)
CByte(expression)
CChar(expression)
CDate(expression)
CDbl(expression)
CDec(expression)
CInt(expression)
CLng(expression)
CObj(expression)
CSByte(expression)
CShort(expression)
CSng(expression)
CStr(expression)
CUInt(expression)
CULng(expression)
CUShort(expression)
Part
expression
Required. Any expression of the source data type.
1 Fractional parts can be subject to a special type of rounding called banker's rounding. See
Remarks
As a rule, you should use the Visual Basic type conversion functions in preference to the .NET
Framework methods such as ToString() , either on the Convert class or on an individual type
structure or class. The Visual Basic functions are designed for optimal interaction with Visual
Basic code, and they also make your source code shorter and easier to read. In addition, the
.NET Framework conversion methods do not always produce the same results as the Visual
Basic functions, for example when converting Boolean to Integer . For more information, see
Troubleshooting Data Types.
Behavior
Coercion. In general, you can use the data type conversion functions to coerce the
result of an operation to a particular data type rather than the default data type. For
example, use CDec to force decimal arithmetic in cases where single-precision, double-
precision, or integer arithmetic would normally take place.
Failed Conversions. If the expression passed to the function is outside the range of
the data type to which it is to be converted, an OverflowException occurs.
Fractional Parts. When you convert a nonintegral value to an integral type, the integer
conversion functions ( CByte , CInt , CLng , CSByte , CShort , CUInt , CULng , and
CUShort ) remove the fractional part and round the value to the closest integer.
If the fractional part is exactly 0.5, the integer conversion functions round it to the
nearest even integer. For example, 0.5 rounds to 0, and 1.5 and 2.5 both round to 2. This
is sometimes called banker's rounding, and its purpose is to compensate for a bias that
could accumulate when adding many such numbers together.
CInt and CLng differ from the Int and Fix functions, which truncate, rather than round,
the fractional part of a number. Also, Fix and Int always return a value of the same
data type as you pass in.
Date/Time Conversions. Use the IsDate function to determine if a value can be
converted to a date and time. CDate recognizes date literals and time literals but not
numeric values. To convert a Visual Basic 6.0 Date value to a Date value in Visual
Basic 2005 or later versions, you can use the System.DateTime.FromOADate method.
Neutral Date/Time Values. The Date Data Type always contains both date and time
information. For purposes of type conversion, Visual Basic considers 1/1/0001 (January
1 of the year 1) to be a neutral value for the date, and 00:00:00 (midnight) to be a
neutral value for the time. If you convert a Date value to a string, CStr does not
include neutral values in the resulting string. For example, if you convert
#January 1, 0001 9:30:00# to a string, the result is "9:30:00 AM"; the date information
is suppressed. However, the date information is still present in the original Date value
and can be recovered with functions such as DatePart function.
Culture Sensitivity. The type conversion functions involving strings perform
conversions based on the current culture settings for the application. For example,
CDate recognizes date formats according to the locale setting of your system. You
must provide the day, month, and year in the correct order for your locale, or the date
might not be interpreted correctly. A long date format is not recognized if it contains a
day-of-the-week string, such as "Wednesday".
If you need to convert to or from a string representation of a value in a format other
than the one specified by your locale, you cannot use the Visual Basic type conversion
functions. To do this, use the ToString(IFormatProvider) and
Parse(String, IFormatProvider) methods of that value's type. For example, use
System.Double.Parse when converting a string to a Double , and use
System.Double.ToString when converting a value of type Double to a string.
CType Function
The CType Function takes a second argument, typename , and coerces expression to typename
, where typename can be any data type, structure, class, or interface to which there exists a
valid conversion.
For a comparison of CType with the other type conversion keywords, see DirectCast Operator
and TryCast Operator.
CBool Example
The following example uses the CBool function to convert expressions to Boolean values. If
an expression evaluates to a nonzero value, CBool returns True ; otherwise, it returns False .
Dim a, b, c As Integer
Dim check As Boolean
a = 5
b = 5
' The following line of code sets check to True.
check = CBool(a = b)
c = 0
' The following line of code sets check to False.
check = CBool(c)
CByte Example
The following example uses the CByte function to convert an expression to a Byte .
The input argument to CChar must be of data type Char or String . You cannot use CChar
to convert a number to a character, because CChar cannot accept a numeric data type. The
following example obtains a number representing a code point (character code) and converts
it to the corresponding character. It uses the InputBox function to obtain the string of digits,
CInt to convert the string to type Integer , and ChrW to convert the number to type Char .
CDate Example
The following example uses the CDate function to convert strings to Date values. In general,
hard-coding dates and times as strings (as shown in this example) is not recommended. Use
date literals and time literals, such as #Feb 12, 1969# and #4:45:23 PM#, instead.
CDbl Example
Dim aDec As Decimal
Dim aDbl As Double
' The following line of code uses the literal type character D to make aDec a Decimal.
aDec = 234.456784D
' The following line of code sets aDbl to 1.9225456288E+1.
aDbl = CDbl(aDec * 8.2D * 0.01D)
CDec Example
The following example uses the CDec function to convert a numeric value to Decimal .
Dim aDouble As Double
Dim aDecimal As Decimal
aDouble = 10000000.0587
' The following line of code sets aDecimal to 10000000.0587.
aDecimal = CDec(aDouble)
CInt Example
The following example uses the CInt function to convert a value to Integer .
CLng Example
The following example uses the CLng function to convert values to Long .
CObj Example
The following example uses the CObj function to convert a numeric value to Object . The
Object variable itself contains only a four-byte pointer, which points to the Double value
assigned to it.
CSByte Example
The following example uses the CSByte function to convert a numeric value to SByte .
CShort Example
The following example uses the CShort function to convert a numeric value to Short .
CSng Example
The following example uses the CSng function to convert values to Single .
CStr Example
The following example uses the CStr function to convert a numeric value to String .
The following example uses the CStr function to convert Date values to String values.
CStr always renders a Date value in the standard short format for the current locale, for
example, "6/15/2003 4:35:47 PM". However, CStr suppresses the neutral values of 1/1/0001
for the date and 00:00:00 for the time.
For more detail on the values returned by CStr , see Return Values for the CStr Function.
CUInt Example
The following example uses the CUInt function to convert a numeric value to UInteger .
CULng Example
The following example uses the CULng function to convert a numeric value to ULong .
CUShort Example
The following example uses the CUShort function to convert a numeric value to UShort .
See Also
Asc
AscW
Chr
ChrW
Int
Fix
Format
Hex
Oct
Str
Val
Conversion Functions
Type Conversions in Visual Basic
Return Values for the CStr Function (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
The following table describes the return values for CStr for different data types of expression .
Date Data Type A string containing a Date value (date and time) in the short
date format of your system.
NOTE
The CStr function performs its conversion based on the current culture settings for the application. To get the string
representation of a number in a particular culture, use the number's ToString(IFormatProvider) method. For example,
use System.Double.ToString when converting a value of type Double to a String .
See Also
DatePart
Type Conversion Functions
Boolean Data Type
Date Data Type
CType Function (Visual Basic)
7/29/2017 • 2 min to read • Edit Online
Returns the result of explicitly converting an expression to a specified data type, object, structure, class, or
interface.
Syntax
CType(expression, typename)
Parts
expression
Any valid expression. If the value of expression is outside the range allowed by typename , Visual Basic throws an
exception.
typename
Any expression that is legal within an As clause in a Dim statement, that is, the name of any data type, object,
structure, class, or interface.
Remarks
TIP
You can also use the following functions to perform a type conversion:
Type conversion functions such as CByte , CDbl , and CInt that perform a conversion to a specific data type. For
more information, see Type Conversion Functions.
DirectCast Operator or TryCast Operator. These operators require that one type inherit from or implement the
other type. They can provide somewhat better performance than CType when converting to and from the
Object data type.
CType is compiled inline, which means that the conversion code is part of the code that evaluates the expression.
In some cases, the code runs faster because no procedures are called to perform the conversion.
If no conversion is defined from expression to typename (for example, from Integer to Date ), Visual Basic
displays a compile-time error message.
If a conversion fails at run time, the appropriate exception is thrown. If a narrowing conversion fails, an
OverflowException is the most common result. If the conversion is undefined, an InvalidCastException in thrown.
For example, this can happen if expression is of type Object and its run-time type has no conversion to
typename .
If the data type of expression or typename is a class or structure you've defined, you can define CType on that
class or structure as a conversion operator. This makes CType act as an overloaded operator. If you do this, you
can control the behavior of conversions to and from your class or structure, including the exceptions that can be
thrown.
Overloading
The CType operator can also be overloaded on a class or structure defined outside your code. If your code
converts to or from such a class or structure, be sure you understand the behavior of its CType operator. For
more information, see Operator Procedures.
Example
The following example uses the CType function to convert an expression to the Single data type.
See Also
OverflowException
InvalidCastException
Type Conversion Functions
Conversion Functions
Operator Statement
How to: Define a Conversion Operator
Type Conversion in the .NET Framework
Modifiers (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
In This Section
Ansi
Assembly
Async
Auto
ByRef
ByVal
Default
Friend
In
Iterator
Key
Module <keyword>
MustInherit
MustOverride
Narrowing
NotInheritable
NotOverridable
Optional
Out
Overloads
Overridable
Overrides
ParamArray
Partial
Private
Protected
Public
ReadOnly
Shadows
Shared
Static
Unicode
Widening
WithEvents
WriteOnly
Related Sections
Visual Basic Language Reference
Visual Basic
Ansi (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
Specifies that Visual Basic should marshal all strings to American National Standards Institute (ANSI) values
regardless of the name of the external procedure being declared.
When you call a procedure defined outside your project, the Visual Basic compiler does not have access to the
information it needs to call the procedure correctly. This information includes where the procedure is located, how
it is identified, its calling sequence and return type, and the string character set it uses. The Declare Statement
creates a reference to an external procedure and supplies this necessary information.
The charsetmodifier part in the Declare statement supplies the character set information for marshaling strings
during a call to the external procedure. It also affects how Visual Basic searches the external file for the external
procedure name. The Ansi modifier specifies that Visual Basic should marshal all strings to ANSI values and
should look up the procedure without modifying its name during the search.
If no character set modifier is specified, Ansi is the default.
Remarks
The Ansi modifier can be used in this context:
Declare Statement
See Also
Auto
Unicode
Keywords
Assembly (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
Specifies that an attribute at the beginning of a source file applies to the entire assembly.
Remarks
Many attributes pertain to an individual programming element, such as a class or property. You apply such an
attribute by attaching the attribute block, within angle brackets ( < > ), directly to the declaration statement.
If an attribute pertains not only to the following element but to the entire assembly, you place the attribute block at
the beginning of the source file and identify the attribute with the Assembly keyword. If it applies to the current
assembly module, you use the Module keyword.
You can also apply an attribute to an assembly in the AssemblyInfo.vb file, in which case you do not have to use an
attribute block in your main source-code file.
See Also
Module <keyword>
Attributes overview
Async (Visual Basic)
7/29/2017 • 3 min to read • Edit Online
The Async modifier indicates that the method or lambda expression that it modifies is asynchronous. Such
methods are referred to as async methods.
An async method provides a convenient way to do potentially long-running work without blocking the caller's
thread. The caller of an async method can resume its work without waiting for the async method to finish.
NOTE
The Async and Await keywords were introduced in Visual Studio 2012. For an introduction to async programming, see
Asynchronous Programming with Async and Await.
The following example shows the structure of an async method. By convention, async method names end in
"Async."
' . . .
' The return statement completes the task. Any method that is
' awaiting ExampleMethodAsync can now get the integer result.
Return exampleInt
End Function
Typically, a method modified by the Async keyword contains at least one Await expression or statement. The
method runs synchronously until it reaches the first Await , at which point it suspends until the awaited task
completes. In the meantime, control is returned to the caller of the method. If the method doesn’t contain an
Await expression or statement, the method isn’t suspended and executes as a synchronous method does. A
compiler warning alerts you to any async methods that don't contain Await because that situation might
indicate an error. For more information, see the compiler error.
The Async keyword is an unreserved keyword. It is a keyword when it modifies a method or a lambda
expression. In all other contexts, it is interpreted as an identifier.
Return Types
An async method is either a Sub procedure, or a Function procedure that has a return type of Task or
Task<TResult>. The method cannot declare any ByRef parameters.
You specify Task(Of TResult) for the return type of an async method if the Return statement of the method has
an operand of type TResult. You use Task if no meaningful value is returned when the method is completed.
That is, a call to the method returns a Task , but when the Task is completed, any Await statement that's
awaiting the Task doesn’t produce a result value.
Async subroutines are used primarily to define event handlers where a Sub procedure is required. The caller of
an async subroutine can't await it and can't catch exceptions that the method throws.
For more information and examples, see Async Return Types.
Example
The following examples show an async event handler, an async lambda expression, and an async method. For a
full example that uses these elements, see Walkthrough: Accessing the Web by Using Async and Await. You can
download the walkthrough code from Developer Code Samples.
' Send the request to the Internet resource and wait for
' the response.
Using response As WebResponse = Await webReq.GetResponseAsync()
' Get the data stream that is associated with the specified URL.
Using responseStream As Stream = response.GetResponseStream()
' Read the bytes in responseStream and copy them to content.
' CopyToAsync returns a Task, not a Task<T>.
Await responseStream.CopyToAsync(content)
End Using
End Using
See Also
AsyncStateMachineAttribute
Await Operator
Asynchronous Programming with Async and Await
Walkthrough: Accessing the Web by Using Async and Await
Auto (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
Specifies that Visual Basic should marshal strings according to .NET Framework rules based on the external name
of the external procedure being declared.
When you call a procedure defined outside your project, the Visual Basic compiler does not have access to the
information it must have to call the procedure correctly. This information includes where the procedure is located,
how it is identified, its calling sequence and return type, and the string character set it uses. The Declare Statement
creates a reference to an external procedure and supplies this necessary information.
The charsetmodifier part in the Declare statement supplies the character set information for marshaling strings
during a call to the external procedure. It also affects how Visual Basic searches the external file for the external
procedure name. The Auto modifier specifies that Visual Basic should marshal strings according to .NET
Framework rules, and that it should determine the base character set of the run-time platform and possibly
modify the external procedure name if the initial search fails. For more information, see "Character Sets" in
Declare Statement.
If no character set modifier is specified, Ansi is the default.
Remarks
The Auto modifier can be used in this context:
Declare Statement
See Also
Ansi
Unicode
Keywords
ByRef (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
Specifies that an argument is passed in such a way that the called procedure can change the value of a variable
underlying the argument in the calling code.
Remarks
The ByRef modifier can be used in these contexts:
Declare Statement
Function Statement
Sub Statement
See Also
Keywords
Passing Arguments by Value and by Reference
ByVal (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
Specifies that an argument is passed in such a way that the called procedure or property cannot change the value
of a variable underlying the argument in the calling code.
Remarks
The ByVal modifier can be used in these contexts:
Declare Statement
Function Statement
Operator Statement
Property Statement
Sub Statement
Example
The following example demonstrates the use of the ByVal parameter passing mechanism with a reference type
argument. In the example, the argument is c1 , an instance of class Class1 . ByVal prevents the code in the
procedures from changing the underlying value of the reference argument, c1 , but does not protect the
accessible fields and properties of c1 .
Module Module1
Sub Main()
' Declare an instance of the class and assign a value to its field.
Dim c1 As Class1 = New Class1()
c1.Field = 5
Console.WriteLine(c1.Field)
' Output: 5
' ByVal does not prevent changing the value of a field or property.
ChangeFieldValue(c1)
Console.WriteLine(c1.Field)
' Output: 500
Console.ReadKey()
End Sub
End Module
See Also
Keywords
Passing Arguments by Value and by Reference
Default (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
Remarks
A class, structure, or interface can designate at most one of its properties as the default property, provided that
property takes at least one parameter. If code makes a reference to a class or structure without specifying a
member, Visual Basic resolves that reference to the default property.
Default properties can result in a small reduction in source code-characters, but they can make your code more
difficult to read. If the calling code is not familiar with your class or structure, when it makes a reference to the
class or structure name it cannot be certain whether that reference accesses the class or structure itself, or a
default property. This can lead to compiler errors or subtle run-time logic errors.
You can somewhat reduce the chance of default property errors by always using the Option Strict Statement to
set compiler type checking to On .
If you are planning to use a predefined class or structure in your code, you must determine whether it has a
default property, and if so, what its name is.
Because of these disadvantages, you should consider not defining default properties. For code readability, you
should also consider always referring to all properties explicitly, even default properties.
The Default modifier can be used in this context:
Property Statement
See Also
How to: Declare and Call a Default Property in Visual Basic
Keywords
Friend (Visual Basic)
7/29/2017 • 2 min to read • Edit Online
Specifies that one or more declared programming elements are accessible only from within the assembly that
contains their declaration.
Remarks
In many cases, you want programming elements such as classes and structures to be used by the entire
assembly, not only by the component that declares them. However, you might not want them to be accessible
by code outside the assembly (for example, if the application is proprietary). If you want to limit access to an
element in this way, you can declare it by using the Friend modifier.
Code in other classes, structures, and modules that are compiled to the same assembly can access all the
Friend elements in that assembly.
Friend access is often the preferred level for an application's programming elements, and Friend is the
default access level of an interface, a module, a class, or a structure.
You can use Friend only at the module, interface, or namespace level. Therefore, the declaration context for a
Friend element must be a source file, a namespace, an interface, a module, a class, or a structure; it can't be a
procedure.
You can use the Friend modifier in conjunction with the Protected modifier in the same declaration. This
combination confers both Friend access and protected access on the declared elements, so they are accessible
from anywhere in the same assembly, from their own class, and from derived classes. You can specify
Protected Friend only on members of classes.
For a comparison of Friend and the other access modifiers, see Access levels in Visual Basic.
NOTE
You can specify that another assembly is a friend assembly, which allows it to access all types and members that are
marked as Friend . For more information, see Friend Assemblies.
Example
The following class uses the Friend modifier to allow other programming elements within the same assembly
to access certain members.
Class CustomerInfo
End Sub
' Require that a customer identifier be specified for the public constructor.
Public Sub New(ByVal customerID As Integer)
p_CustomerID = customerID
End Sub
Usage
You can use the Friend modifier in these contexts:
Class Statement
Const Statement
Declare Statement
Delegate Statement
Dim Statement
Enum Statement
Event Statement
Function Statement
Interface Statement
Module Statement
Property Statement
Structure Statement
Sub Statement
See Also
InternalsVisibleToAttribute
Public
Protected
Private
Access levels in Visual Basic
Procedures
Structures
Objects and Classes
In (Generic Modifier) (Visual Basic)
8/11/2017 • 2 min to read • Edit Online
For generic type parameters, the In keyword specifies that the type parameter is contravariant.
Remarks
Contravariance enables you to use a less derived type than that specified by the generic parameter. This allows for
implicit conversion of classes that implement variant interfaces and implicit conversion of delegate types.
For more information, see Covariance and Contravariance.
Rules
You can use the In keyword in generic interfaces and delegates.
A type parameter can be declared contravariant in a generic interface or delegate if it is used only as a type of
method arguments and not used as a method return type. ByRef parameters cannot be covariant or
contravariant.
Covariance and contravariance are supported for reference types and not supported for value types.
In Visual Basic, you cannot declare events in contravariant interfaces without specifying the delegate type. Also,
contravariant interfaces cannot have nested classes, enums, or structures, but they can have nested interfaces.
Behavior
An interface that has a contravariant type parameter allows its methods to accept arguments of less derived types
than those specified by the interface type parameter. For example, because in .NET Framework 4, in the
IComparer<T> interface, type T is contravariant, you can assign an object of the IComparer(Of Person) type to an
object of the IComparer(Of Employee) type without using any special conversion methods if Person inherits
Employee .
A contravariant delegate can be assigned another delegate of the same type, but with a less derived generic type
parameter.
Example
The following example shows how to declare, extend, and implement a contravariant generic interface. It also
shows how you can use implicit conversion for classes that implement this interface.
' Contravariant interface.
Interface IContravariant(Of In A)
End Interface
Sub Main()
Dim iobj As IContravariant(Of Object) = New Sample(Of Object)()
Dim istr As IContravariant(Of String) = New Sample(Of String)()
Example
The following example shows how to declare, instantiate, and invoke a contravariant generic delegate. It also
shows how you can implicitly convert a delegate type.
See Also
Variance in Generic Interfaces
Out
Iterator (Visual Basic)
7/29/2017 • 2 min to read • Edit Online
Remarks
An iterator performs a custom iteration over a collection. An iterator uses the Yield statement to return each
element in the collection one at a time. When a Yield statement is reached, the current location in code is
retained. Execution is restarted from that location the next time that the iterator function is called.
An iterator can be implemented as a function or as a Get accessor of a property definition. The Iterator
modifier appears in the declaration of the iterator function or Get accessor.
You call an iterator from client code by using a For Each...Next Statement.
The return type of an iterator function or Get accessor can be IEnumerable, IEnumerable<T>, IEnumerator, or
IEnumerator<T>.
An iterator cannot have any ByRef parameters.
An iterator cannot occur in an event, instance constructor, static constructor, or static destructor.
An iterator can be an anonymous function. For more information, see Iterators.
For more information about iterators, see Iterators.
Usage
The Iterator modifier can be used in these contexts:
Function Statement
Property Statement
Example
The following example demonstrates an iterator function. The iterator function has a Yield statement that is
inside a For…Next loop. Each iteration of the For Each statement body in Main creates a call to the Power iterator
function. Each call to the iterator function proceeds to the next execution of the Yield statement, which occurs
during the next iteration of the For…Next loop.
Sub Main()
For Each number In Power(2, 8)
Console.Write(number & " ")
Next
' Output: 2 4 8 16 32 64 128 256
Console.ReadKey()
End Sub
Dim result = 1
Example
The following example demonstrates a Get accessor that is an iterator. The Iterator modifier is in the property
declaration.
Sub Main()
Dim theGalaxies As New Galaxies
For Each theGalaxy In theGalaxies.NextGalaxy
With theGalaxy
Console.WriteLine(.Name & " " & .MegaLightYears)
End With
Next
Console.ReadKey()
End Sub
See Also
IteratorStateMachineAttribute
Iterators
Yield Statement
Key (Visual Basic)
7/29/2017 • 3 min to read • Edit Online
The Key keyword enables you to specify behavior for properties of anonymous types. Only properties you
designate as key properties participate in tests of equality between anonymous type instances, or calculation of
hash code values. The values of key properties cannot be changed.
You designate a property of an anonymous type as a key property by placing the keyword Key in front of its
declaration in the initialization list. In the following example, Airline and FlightNo are key properties, but Gate
is not.
When a new anonymous type is created, it inherits directly from Object. The compiler overrides three inherited
members: Equals, GetHashCode, and ToString. The override code that is produced for Equals and GetHashCode is
based on key properties. If there are no key properties in the type, GetHashCode and Equals are not overridden.
Equality
Two anonymous type instances are equal if they are instances of the same type and if the values of their key
properties are equal. In the following examples, flight2 is equal to flight1 from the previous example because
they are instances of the same anonymous type and they have matching values for their key properties. However,
flight3 is not equal to flight1 because it has a different value for a key property, FlightNo . Instance flight4 is
not the same type as flight1 because they designate different properties as key properties.
If two instances are declared with only non-key properties, identical in name, type, order, and value, the two
instances are not equal. An instance without key properties is equal only to itself.
For more information about the conditions under which two anonymous type instances are instances of the same
anonymous type, see Anonymous Types.
Console.WriteLine(flight1.GetHashCode = flight2.GetHashCode)
Instances of an anonymous type that have different values for one or more key properties have different hash code
values. The following statement returns False .
Console.WriteLine(flight1.GetHashCode = flight3.GetHashCode)
Instances of anonymous types that designate different properties as key properties are not instances of the same
type. They have different hash code values even when the names and values of all properties are the same. The
following statement returns False .
Console.WriteLine(flight1.GetHashCode = flight4.GetHashCode)
Read-Only Values
The values of key properties cannot be changed. For example, in flight1 in the earlier examples, the Airline and
FlightNo fields are read-only, but Gate can be changed.
' The following statement will not compile, because FlightNo is a key
' property and cannot be changed.
' flight1.FlightNo = 1234
'
' Gate is not a key property. Its value can be changed.
flight1.Gate = "C5"
See Also
Anonymous Type Definition
How to: Infer Property Names and Types in Anonymous Type Declarations
Anonymous Types
Module <keyword> (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
Specifies that an attribute at the beginning of a source file applies to the current assembly module.
Remarks
Many attributes pertain to an individual programming element, such as a class or property. You apply such an
attribute by attaching the attribute block, within angle brackets ( < > ), directly to the declaration statement.
If an attribute pertains not only to the following element but to the current assembly module, you place the
attribute block at the beginning of the source file and identify the attribute with the Module keyword. If it applies
to the entire assembly, you use the Assembly keyword.
The Module modifier is not the same as the Module Statement.
See Also
Assembly
Module Statement
Attributes overview
MustInherit (Visual Basic)
7/29/2017 • 2 min to read • Edit Online
Specifies that a class can be used only as a base class and that you cannot create an object directly from it.
Remarks
The purpose of a base class (also known as an abstract class) is to define functionality that is common to all the
classes derived from it. This saves the derived classes from having to redefine the common elements. In some
cases, this common functionality is not complete enough to make a usable object, and each derived class defines
the missing functionality. In such a case, you want the consuming code to create objects only from the derived
classes. You use MustInherit on the base class to enforce this.
Another use of a MustInherit class is to restrict a variable to a set of related classes. You can define a base class
and derive all these related classes from it. The base class does not need to provide any functionality common to
all the derived classes, but it can serve as a filter for assigning values to variables. If your consuming code declares
a variable as the base class, Visual Basic allows you to assign only an object from one of the derived classes to
that variable.
The .NET Framework defines several MustInherit classes, among them Array, Enum, and ValueType. ValueType is
an example of a base class that restricts a variable. All value types derive from ValueType. If you declare a variable
as ValueType, you can assign only value types to that variable.
Rules
Declaration Context. You can use MustInherit only in a Class statement.
Combined Modifiers. You cannot specify MustInherit together with NotInheritable in the same
declaration.
Example
The following example illustrates both forced inheritance and forced overriding. The base class shape defines a
variable acrossLine . The classes circle and square derive from shape . They inherit the definition of
acrossLine , but they must define the function area because that calculation is different for each kind of shape.
Public MustInherit Class shape
Public acrossLine As Double
Public MustOverride Function area() As Double
End Class
Public Class circle : Inherits shape
Public Overrides Function area() As Double
Return Math.PI * acrossLine
End Function
End Class
Public Class square : Inherits shape
Public Overrides Function area() As Double
Return acrossLine * acrossLine
End Function
End Class
Public Class consumeShapes
Public Sub makeShapes()
Dim shape1, shape2 As shape
shape1 = New circle
shape2 = New square
End Sub
End Class
You can declare shape1 and shape2 to be of type shape . However, you cannot create an object from shape
because it lacks the functionality of the function area and is marked MustInherit .
Because they are declared as shape , the variables shape1 and shape2 are restricted to objects from the derived
classes circle and square . Visual Basic does not allow you to assign any other object to these variables, which
gives you a high level of type safety.
Usage
The MustInherit modifier can be used in this context:
Class Statement
See Also
Inherits Statement
NotInheritable
Keywords
Inheritance Basics
MustOverride (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
Specifies that a property or procedure is not implemented in this class and must be overridden in a derived class
before it can be used.
Remarks
You can use MustOverride only in a property or procedure declaration statement. The property or procedure that
specifies MustOverride must be a member of a class, and the class must be marked MustInherit.
Rules
Incomplete Declaration. When you specify MustOverride , you do not supply any additional lines of code
for the property or procedure, not even the End Function , End Property , or End Sub statement.
Combined Modifiers. You cannot specify MustOverride together with NotOverridable , Overridable , or
Shared in the same declaration.
Shadowing and Overriding. Both shadowing and overriding redefine an inherited element, but there are
significant differences between the two approaches. For more information, see Shadowing in Visual Basic.
Alternate Terms. An element that cannot be used except in an override is sometimes called a pure virtual
element.
The MustOverride modifier can be used in these contexts:
Function Statement
Property Statement
Sub Statement
See Also
NotOverridable
Overridable
Overrides
MustInherit
Keywords
Shadowing in Visual Basic
Narrowing (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
Indicates that a conversion operator ( CType ) converts a class or structure to a type that might not be able to hold
some of the possible values of the original class or structure.
See Also
Operator Statement
Widening
Widening and Narrowing Conversions
How to: Define an Operator
CType Function
Option Strict Statement
NotInheritable (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
Remarks
Alternate Terms. A class that cannot be inherited is sometimes called a sealed class.
The NotInheritable modifier can be used in this context:
Class Statement
See Also
Inherits Statement
MustInherit
Keywords
NotOverridable (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
Remarks
The NotOverridable modifier prevents a property or method from being overridden in a derived class. The
Overridable modifier allows a property or method in a class to be overridden in a derived class. For more
information, see Inheritance Basics.
If the Overridable or NotOverridable modifier is not specified, the default setting depends on whether the
property or method overrides a base class property or method. If the property or method overrides a base class
property or method, the default setting is Overridable ; otherwise, it is NotOverridable .
An element that cannot be overridden is sometimes called a sealed element.
You can use NotOverridableonly in a property or procedure declaration statement. You can specify
NotOverridable only on a property or procedure that overrides another property or procedure, that is, only in
combination with Overrides .
Combined Modifiers
You cannot specify Overridable or NotOverridable for a Private method.
You cannot specify NotOverridable together with MustOverride , Overridable , or Shared in the same
declaration.
Usage
The NotOverridable modifier can be used in these contexts:
Function Statement
Property Statement
Sub Statement
See Also
Modifiers
Inheritance Basics
MustOverride
Overridable
Overrides
Keywords
Shadowing in Visual Basic
Optional (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
Specifies that a procedure argument can be omitted when the procedure is called.
Remarks
For each optional parameter, you must specify a constant expression as the default value of that parameter. If the
expression evaluates to Nothing, the default value of the value data type is used as the default value of the
parameter.
If the parameter list contains an optional parameter, every parameter that follows it must also be optional.
The Optional modifier can be used in these contexts:
Declare Statement
Function Statement
Property Statement
Sub Statement
NOTE
When calling a procedure with or without optional parameters, you can pass arguments by position or by name. For more
information, see Passing Arguments by Position and by Name.
NOTE
You can also define a procedure with optional parameters by using overloading. If you have one optional parameter, you can
define two overloaded versions of the procedure, one that accepts the parameter and one that doesn’t. For more
information, see Procedure Overloading.
Example
The following example defines a procedure that has an optional parameter.
Public Function FindMatches(ByRef values As List(Of String),
ByVal searchString As String,
Optional ByVal matchCase As Boolean = False) As List(Of String)
If matchCase Then
results = From v In values
Where v.Contains(searchString)
Else
results = From v In values
Where UCase(v).Contains(UCase(searchString))
End If
Return results.ToList()
End Function
Example
The following example demonstrates how to call a procedure with arguments passed by position and with
arguments passed by name. The procedure has two optional parameters.
' Omit one optional argument by holding its place with a comma.
studentInfo("Mary", , #9/21/1981#)
See Also
Parameter List
Optional Parameters
Keywords
Out (Generic Modifier) (Visual Basic)
8/11/2017 • 2 min to read • Edit Online
For generic type parameters, the Out keyword specifies that the type is covariant.
Remarks
Covariance enables you to use a more derived type than that specified by the generic parameter. This allows for
implicit conversion of classes that implement variant interfaces and implicit conversion of delegate types.
For more information, see Covariance and Contravariance.
Rules
You can use the Out keyword in generic interfaces and delegates.
In a generic interface, a type parameter can be declared covariant if it satisfies the following conditions:
The type parameter is used only as a return type of interface methods and not used as a type of method
arguments.
NOTE
There is one exception to this rule. If in a covariant interface you have a contravariant generic delegate as a method
parameter, you can use the covariant type as a generic type parameter for this delegate. For more information
about covariant and contravariant generic delegates, see Variance in Delegates and Using Variance for Func and
Action Generic Delegates.
The type parameter is not used as a generic constraint for the interface methods.
In a generic delegate, a type parameter can be declared covariant if it is used only as a method return type and not
used for method arguments.
Covariance and contravariance are supported for reference types, but they are not supported for value types.
In Visual Basic, you cannot declare events in covariant interfaces without specifying the delegate type. Also,
covariant interfaces cannot have nested classes, enums, or structures, but they can have nested interfaces.
Behavior
An interface that has a covariant type parameter enables its methods to return more derived types than those
specified by the type parameter. For example, because in .NET Framework 4, in IEnumerable<T>, type T is
covariant, you can assign an object of the IEnumerabe(Of String) type to an object of the IEnumerable(Of Object)
type without using any special conversion methods.
A covariant delegate can be assigned another delegate of the same type, but with a more derived generic type
parameter.
Example
The following example shows how to declare, extend, and implement a covariant generic interface. It also shows
how to use implicit conversion for classes that implement a covariant interface.
' Covariant interface.
Interface ICovariant(Of Out R)
End Interface
Sub Main()
Dim iobj As ICovariant(Of Object) = New Sample(Of Object)()
Dim istr As ICovariant(Of String) = New Sample(Of String)()
Example
The following example shows how to declare, instantiate, and invoke a covariant generic delegate. It also shows
how you can use implicit conversion for delegate types.
See Also
Variance in Generic Interfaces
In
Overloads (Visual Basic)
7/29/2017 • 2 min to read • Edit Online
Specifies that a property or procedure redeclares one or more existing properties or procedures with the same
name.
Remarks
Overloading is the practice of supplying more than one definition for a given property or procedure name in the
same scope. Redeclaring a property or procedure with a different signature is sometimes called hiding by
signature.
Rules
Declaration Context. You can use Overloads only in a property or procedure declaration statement.
Combined Modifiers. You cannot specify Overloads together with Shadows in the same procedure
declaration.
Required Differences. The signature in this declaration must be different from the signature of every
property or procedure that it overloads. The signature comprises the property or procedure name together
with the following:
the number of parameters
the order of the parameters
the data types of the parameters
the number of type parameters (for a generic procedure)
the return type (only for a conversion operator procedure)
All overloads must have the same name, but each must differ from all the others in one or more of the
preceding respects. This allows the compiler to distinguish which version to use when code calls the
property or procedure.
Disallowed Differences. Changing one or more of the following is not valid for overloading a property
or procedure, because they are not part of the signature:
whether or not it returns a value (for a procedure)
the data type of the return value (except for a conversion operator)
the names of the parameters or type parameters
the constraints on the type parameters (for a generic procedure)
parameter modifier keywords (such as ByRef or Optional )
property or procedure modifier keywords (such as Public or Shared )
Optional Modifier. You do not have to use the Overloads modifier when you are defining multiple
overloaded properties or procedures in the same class. However, if you use Overloads in one of the
declarations, you must use it in all of them.
Shadowing and Overloading. Overloads can also be used to shadow an existing member, or set of
overloaded members, in a base class. When you use Overloads in this way, you declare the property or
method with the same name and the same parameter list as the base class member, and you do not supply
the Shadows keyword.
If you use Overrides , the compiler implicitly adds Overloads so that your library APIs work with C# more easily.
The Overloads modifier can be used in these contexts:
Function Statement
Operator Statement
Property Statement
Sub Statement
See Also
Shadows
Procedure Overloading
Generic Types in Visual Basic
Operator Procedures
How to: Define a Conversion Operator
Overridable (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
Specifies that a property or procedure can be overridden by an identically named property or procedure in a
derived class.
Remarks
The Overridable modifier allows a property or method in a class to be overridden in a derived class. The
NotOverridable modifier prevents a property or method from being overridden in a derived class. For more
information, see Inheritance Basics.
If the Overridable or NotOverridable modifier is not specified, the default setting depends on whether the
property or method overrides a base class property or method. If the property or method overrides a base class
property or method, the default setting is Overridable ; otherwise, it is NotOverridable .
You can shadow or override to redefine an inherited element, but there are significant differences between the
two approaches. For more information, see Shadowing in Visual Basic.
An element that can be overridden is sometimes referred to as a virtual element. If it can be overridden, but does
not have to be, it is sometimes also called a concrete element.
You can use Overridable only in a property or procedure declaration statement.
Combined Modifiers
You cannot specify Overridable or NotOverridable for a Private method.
You cannot specify Overridable together with MustOverride , NotOverridable , or Shared in the same
declaration.
Because an overriding element is implicitly overridable, you cannot combine Overridable with Overrides .
Usage
The Overridable modifier can be used in these contexts:
Function Statement
Property Statement
Sub Statement
See Also
Modifiers
Inheritance Basics
MustOverride
NotOverridable
Overrides
Keywords
Shadowing in Visual Basic
Overrides (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
Specifies that a property or procedure overrides an identically named property or procedure inherited from a
base class.
Remarks
Rules
Declaration Context. You can use Overrides only in a property or procedure declaration statement.
Combined Modifiers. You cannot specify Overrides together with Shadows or Shared in the same
declaration. Because an overriding element is implicitly overridable, you cannot combine Overridable
with Overrides .
Matching Signatures. The signature of this declaration must exactly match the signature of the property
or procedure that it overrides. This means the parameter lists must have the same number of parameters,
in the same order, with the same data types.
In addition to the signature, the overriding declaration must also exactly match the following:
The access level
The return type, if any
Generic Signatures. For a generic procedure, the signature includes the number of type parameters.
Therefore, the overriding declaration must match the base class version in that respect as well.
Additional Matching. In addition to matching the signature of the base class version, this declaration
must also match it in the following respects:
Access-level modifier (such as Public)
Passing mechanism of each parameter (ByVal or ByRef)
Constraint lists on each type parameter of a generic procedure
Shadowing and Overriding. Both shadowing and overriding redefine an inherited element, but there
are significant differences between the two approaches. For more information, see Shadowing in Visual
Basic.
If you use Overrides , the compiler implicitly adds Overloads so that your library APIs work with C# more easily.
The Overrides modifier can be used in these contexts:
Function Statement
Property Statement
Sub Statement
See Also
MustOverride
NotOverridable
Overridable
Keywords
Shadowing in Visual Basic
Generic Types in Visual Basic
Type List
ParamArray (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
Specifies that a procedure parameter takes an optional array of elements of the specified type. ParamArray can be
used only on the last parameter of a parameter list.
Remarks
ParamArray allows you to pass an arbitrary number of arguments to the procedure. A ParamArray parameter is
always declared using ByVal.
You can supply one or more arguments to a ParamArray parameter by passing an array of the appropriate data
type, a comma-separated list of values, or nothing at all. For details, see "Calling a ParamArray" in Parameter
Arrays.
IMPORTANT
Whenever you deal with an array which can be indefinitely large, there is a risk of overrunning some internal capacity of your
application. If you accept a parameter array from the calling code, you should test its length and take appropriate steps if it is
too large for your application.
See Also
Keywords
Parameter Arrays
Partial (Visual Basic)
7/29/2017 • 3 min to read • Edit Online
NOTE
Visual Basic supports partial methods, which are typically implemented in partial classes. For more information, see Partial
Methods and Sub Statement.
Syntax
[ <attrlist> ] [ accessmodifier ] [ Shadows ] [ MustInherit | NotInheritable ] _
Partial { Class | Structure | Interface | Module } name [ (Of typelist) ]
[ Inherits classname ]
[ Implements interfacenames ]
[ variabledeclarations ]
[ proceduredeclarations ]
{ End Class | End Structure }
Parts
TERM DEFINITION
attrlist Optional. List of attributes that apply to this type. You must
enclose the Attribute List in angle brackets ( < > ).
accessmodifier Optional. Specifies what code can access this type. See Access
levels in Visual Basic.
name Required. Name of this type. Must match the name defined in
all other partial declarations of the same type.
End Class or End Structure Ends this partial Class or Structure definition.
Remarks
Visual Basic uses partial-class definitions to separate generated code from user-authored code in separate source
files. For example, the Windows Form Designer defines partial classes for controls such as Form. You should not
modify the generated code in these controls.
All the rules for class, structure, interface, and module creation, such as those for modifier usage and inheritance,
apply when creating a partial type.
Best Practices
Under normal circumstances, you should not split the development of a single type across two or more
declarations. Therefore, in most cases you do not need the Partial keyword.
For readability, every partial declaration of a type should include the Partial keyword. The compiler allows
at most one partial declaration to omit the keyword; if two or more omit it the compiler signals an error.
Behavior
Union of Declarations. The compiler treats the type as the union of all its partial declarations. Every
modifier from every partial definition applies to the entire type, and every member from every partial
definition is available to the entire type.
Type Promotion Not Allowed For Partial Types in Modules. If a partial definition is inside a module,
type promotion of that type is automatically defeated. In such a case, a set of partial definitions can cause
unexpected results and even compiler errors. For more information, see Type Promotion.
The compiler merges partial definitions only when their fully qualified paths are identical.
The Partial keyword can be used in these contexts:
Class Statement
Structure Statement
Example
The following example splits the definition of class sampleClass into two declarations, each of which defines a
different Sub procedure.
The two partial definitions in the preceding example could be in the same source file or in two different source
files.
See Also
Class Statement
Structure Statement
Type Promotion
Shadows
Generic Types in Visual Basic
Partial Methods
Private (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
Specifies that one or more declared programming elements are accessible only from within their declaration
context, including from within any contained types.
Remarks
If a programming element represents proprietary functionality, or contains confidential data, you usually want
to limit access to it as strictly as possible. You achieve the maximum limitation by allowing only the module,
class, or structure that defines it to access it. To limit access to an element in this way, you can declare it with
Private .
Rules
Declaration Context. You can use Private only at module level. This means the declaration context for a
Private element must be a module, class, or structure, and cannot be a source file, namespace, interface,
or procedure.
Behavior
Access Level. All code within a declaration context can access its Private elements. This includes code
within a contained type, such as a nested class or an assignment expression in an enumeration. No
code outside of the declaration context can access its Private elements.
Access Modifiers. The keywords that specify access level are called access modifiers. For a comparison
of the access modifiers, see Access levels in Visual Basic.
The Private modifier can be used in these contexts:
Class Statement
Const Statement
Declare Statement
Delegate Statement
Dim Statement
Enum Statement
Event Statement
Function Statement
Interface Statement
Property Statement
Structure Statement
Sub Statement
See Also
Public
Protected
Friend
Access levels in Visual Basic
Procedures
Structures
Objects and Classes
Protected (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
Specifies that one or more declared programming elements are accessible only from within their own class or
from a derived class.
Remarks
Sometimes a programming element declared in a class contains sensitive data or restricted code, and you want
to limit access to the element. However, if the class is inheritable and you expect a hierarchy of derived classes,
it might be necessary for these derived classes to access the data or code. In such a case, you want the element
to be accessible both from the base class and from all derived classes. To limit access to an element in this
manner, you can declare it with Protected .
Rules
Declaration Context. You can use Protected only at class level. This means the declaration context for
a Protected element must be a class, and cannot be a source file, namespace, interface, module,
structure, or procedure.
Combined Modifiers. You can use the Protected modifier together with the Friend modifier in the
same declaration. This combination makes the declared elements accessible from anywhere in the same
assembly, from their own class, and from derived classes. You can specify Protected Friend only on
members of classes.
Behavior
Access Level. All code in a class can access its elements. Code in any class that derives from a base class
can access all the Protected elements of the base class. This is true for all generations of derivation. This
means that a class can access Protected elements of the base class of the base class, and so on.
Protected access is not a superset or subset of friend access.
Access Modifiers. The keywords that specify access level are called access modifiers. For a comparison
of the access modifiers, see Access levels in Visual Basic.
The Protected modifier can be used in these contexts:
Class Statement
Const Statement
Declare Statement
Delegate Statement
Dim Statement
Enum Statement
Event Statement
Function Statement
Interface Statement
Property Statement
Structure Statement
Sub Statement
See Also
Public
Friend
Private
Access levels in Visual Basic
Procedures
Structures
Objects and Classes
Public (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
Specifies that one or more declared programming elements have no access restrictions.
Remarks
If you are publishing a component or set of components, such as a class library, you usually want the
programming elements to be accessible by any code that interoperates with your assembly. To confer such
unlimited access on an element, you can declare it with Public .
Public access is the normal level for a programming element when you do not need to limit access to it. Note
that the access level of an element declared within an interface, module, class, or structure defaults to Public
if you do not declare it otherwise.
Rules
Declaration Context. You can use Public only at module, interface, or namespace level. This means the
declaration context for a Public element must be a source file, namespace, interface, module, class, or
structure, and cannot be a procedure.
Behavior
Access Level. All code that can access a module, class, or structure can access its Public elements.
Default Access. Local variables inside a procedure default to public access, and you cannot use any
access modifiers on them.
Access Modifiers. The keywords that specify access level are called access modifiers. For a comparison
of the access modifiers, see Access levels in Visual Basic.
The Public modifier can be used in these contexts:
Class Statement
Const Statement
Declare Statement
Delegate Statement
Dim Statement
Enum Statement
Event Statement
Function Statement
Interface Statement
Module Statement
Operator Statement
Property Statement
Structure Statement
Sub Statement
See Also
Protected
Friend
Private
Access levels in Visual Basic
Procedures
Structures
Objects and Classes
ReadOnly (Visual Basic)
7/29/2017 • 2 min to read • Edit Online
Remarks
Rules
Declaration Context. You can use ReadOnly only at module level. This means the declaration context for
a ReadOnly element must be a class, structure, or module, and cannot be a source file, namespace, or
procedure.
Combined Modifiers. You cannot specify ReadOnly together with Static in the same declaration.
Assigning a Value. Code consuming a ReadOnly property cannot set its value. But code that has access
to the underlying storage can assign or change the value at any time.
You can assign a value to a ReadOnly variable only in its declaration or in the constructor of a class or
structure in which it is defined.
IMPORTANT
If the data type of the variable is a reference type, such as an array or a class instance, its members can be changed even if
the variable itself is ReadOnly . The following example illustrates this.
Sub changeArrayElement()
characterArray(1) = "M"c
End Sub
When initialized, the array pointed to by characterArray() holds "x", "y", and "z". Because the variable
characterArray is ReadOnly , you cannot change its value once it is initialized; that is, you cannot assign a new
array to it. However, you can change the values of one or more of the array members. Following a call to the
procedure changeArrayElement , the array pointed to by characterArray() holds "x", "M", and "z".
Note that this is similar to declaring a procedure parameter to be ByVal, which prevents the procedure from
changing the calling argument itself but allows it to change its members.
Example
The following example defines a ReadOnly property for the date on which an employee was hired. The class
stores the property value internally as a Private variable, and only code inside the class can change that value.
However, the property is Public , and any code that can access the class can read the property.
Class employee
' Only code inside class employee can change the value of hireDateValue.
Private hireDateValue As Date
' Any code that can access class employee can read property dateHired.
Public ReadOnly Property dateHired() As Date
Get
Return hireDateValue
End Get
End Property
End Class
See Also
WriteOnly
Keywords
Shadows (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
Specifies that a declared programming element redeclares and hides an identically named element, or set of
overloaded elements, in a base class.
Remarks
The main purpose of shadowing (which is also known as hiding by name) is to preserve the definition of your
class members. The base class might undergo a change that creates an element with the same name as one
you have already defined. If this happens, the Shadows modifier forces references through your class to be
resolved to the member you defined, instead of to the new base class element.
Both shadowing and overriding redefine an inherited element, but there are significant differences between the
two approaches. For more information, see Shadowing in Visual Basic.
Rules
Declaration Context. You can use Shadows only at class level. This means the declaration context for a
Shadows element must be a class, and cannot be a source file, namespace, interface, module, structure,
or procedure.
You can declare only one shadowing element in a single declaration statement.
Combined Modifiers. You cannot specify Shadows together with Overloads , Overrides , or Static in
the same declaration.
Element Types. You can shadow any kind of declared element with any other kind. If you shadow a
property or procedure with another property or procedure, the parameters and the return type do not
have to match those in the base class property or procedure.
Accessing. The shadowed element in the base class is normally unavailable from within the derived
class that shadows it. However, the following considerations apply.
If the shadowing element is not accessible from the code referring to it, the reference is resolved
to the shadowed element. For example, if a Private element shadows a base class element, code
that does not have permission to access the Private element accesses the base class element
instead.
If you shadow an element, you can still access the shadowed element through an object declared
with the type of the base class. You can also access it through MyBase .
The Shadows modifier can be used in these contexts:
Class Statement
Const Statement
Declare Statement
Delegate Statement
Dim Statement
Enum Statement
Event Statement
Function Statement
Interface Statement
Property Statement
Structure Statement
Sub Statement
See Also
Shared
Static
Private
Me, My, MyBase, and MyClass
Inheritance Basics
MustOverride
NotOverridable
Overloads
Overridable
Overrides
Shadowing in Visual Basic
Shared (Visual Basic)
7/29/2017 • 3 min to read • Edit Online
Specifies that one or more declared programming elements are associated with a class or structure at large,
and not with a specific instance of the class or structure.
Remarks
When to Use Shared
Sharing a member of a class or structure makes it available to every instance, rather than nonshared, where
each instance keeps its own copy. This is useful, for example, if the value of a variable applies to the entire
application. If you declare that variable to be Shared , then all instances access the same storage location, and if
one instance changes the variable's value, all instances access the updated value.
Sharing does not alter the access level of a member. For example, a class member can be shared and private
(accessible only from within the class), or nonshared and public. For more information, see Access levels in
Visual Basic.
Rules
Declaration Context. You can use Shared only at module level. This means the declaration context for
a Shared element must be a class or structure, and cannot be a source file, namespace, or procedure.
Combined Modifiers. You cannot specify Shared together with Overrides, Overridable,
NotOverridable, MustOverride, or Static in the same declaration.
Accessing. You access a shared element by qualifying it with its class or structure name, not with the
variable name of a specific instance of its class or structure. You do not even have to create an instance
of a class or structure to access its shared members.
The following example calls the shared procedure IsNaN exposed by the Double structure.
If Double.IsNaN(result) Then MsgBox("Result is mathematically undefined.")
Implicit Sharing. You cannot use the Shared modifier in a Const Statement, but constants are implicitly
shared. Similarly, you cannot declare a member of a module or an interface to be Shared , but they are
implicitly shared.
Behavior
Storage. A shared variable or event is stored in memory only once, no matter how many or few
instances you create of its class or structure. Similarly, a shared procedure or property holds only one set
of local variables.
Accessing through an Instance Variable. It is possible to access a shared element by qualifying it with
the name of a variable that contains a specific instance of its class or structure. Although this usually
works as expected, the compiler generates a warning message and makes the access through the class
or structure name instead of the variable.
Accessing through an Instance Expression. If you access a shared element through an expression
that returns an instance of its class or structure, the compiler makes the access through the class or
structure name instead of evaluating the expression. This produces unexpected results if you intended
the expression to perform other actions as well as returning the instance. The following example
illustrates this.
Sub main()
shareTotal.total = 10
' The preceding line is the preferred way to access total.
Dim instanceVar As New shareTotal
instanceVar.total += 100
' The preceding line generates a compiler warning message and
' accesses total through class shareTotal instead of through
' the variable instanceVar. This works as expected and adds
' 100 to total.
returnClass().total += 1000
' The preceding line generates a compiler warning message and
' accesses total through class shareTotal instead of calling
' returnClass(). This adds 1000 to total but does not work as
' expected, because the MsgBox in returnClass() does not run.
MsgBox("Value of total is " & CStr(shareTotal.total))
End Sub
Public Function returnClass() As shareTotal
MsgBox("Function returnClass() called")
Return New shareTotal
End Function
Public Class shareTotal
Public Shared total As Integer
End Class
In the preceding example, the compiler generates a warning message both times the code accesses the
shared variable total through an instance. In each case it makes the access directly through the class
shareTotal and does not make use of any instance. In the case of the intended call to the procedure
returnClass , this means it does not even generate a call to returnClass , so the additional action of
displaying "Function returnClass() called" is not performed.
The Shared modifier can be used in these contexts:
Dim Statement
Event Statement
Function Statement
Operator Statement
Property Statement
Sub Statement
See Also
Shadows
Static
Lifetime in Visual Basic
Procedures
Structures
Objects and Classes
Static (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
Specifies that one or more declared local variables are to continue to exist and retain their latest values after
termination of the procedure in which they are declared.
Remarks
Normally, a local variable in a procedure ceases to exist as soon as the procedure stops. A static variable continues
to exist and retains its most recent value. The next time your code calls the procedure, the variable is not
reinitialized, and it still holds the latest value that you assigned to it. A static variable continues to exist for the
lifetime of the class or module that it is defined in.
Rules
Declaration Context. You can use Static only on local variables. This means the declaration context for
a Static variable must be a procedure or a block in a procedure, and it cannot be a source file,
namespace, class, structure, or module.
You cannot use Static inside a structure procedure.
The data types of Static local variables cannot be inferred. For more information, see Local Type
Inference.
Combined Modifiers. You cannot specify Static together with ReadOnly , Shadows , or Shared in the
same declaration.
Behavior
When you declare a static variable in a Shared procedure, only one copy of the static variable is available for the
whole application. You call a Shared procedure by using the class name, not a variable that points to an instance
of the class.
When you declare a static variable in a procedure that isn't Shared , only one copy of the variable is available for
each instance of the class. You call a non-shared procedure by using a variable that points to a specific instance of
the class.
Example
The following example demonstrates the use of Static .
The Static variable totalSales is initialized to 0 only one time. Each time that you enter updateSales ,
totalSales still has the most recent value that you calculated for it.
The Static modifier can be used in this context:
Dim Statement
See Also
Shadows
Shared
Lifetime in Visual Basic
Variable Declaration
Structures
Local Type Inference
Objects and Classes
Unicode (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
Specifies that Visual Basic should marshal all strings to Unicode values regardless of the name of the external
procedure being declared.
When you call a procedure defined outside your project, the Visual Basic compiler does not have access to the
information it must have in order to call the procedure correctly. This information includes where the procedure is
located, how it is identified, its calling sequence and return type, and the string character set it uses. The Declare
Statement creates a reference to an external procedure and supplies this necessary information.
The charsetmodifier part in the Declare statement supplies the character set information to marshal strings
during a call to the external procedure. It also affects how Visual Basic searches the external file for the external
procedure name. The Unicode modifier specifies that Visual Basic should marshal all strings to Unicode values
and should look up the procedure without modifying its name during the search.
If no character set modifier is specified, Ansi is the default.
Remarks
The Unicode modifier can be used in this context:
Declare Statement
See Also
Ansi
Auto
Keywords
Widening (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
Indicates that a conversion operator ( CType ) converts a class or structure to a type that can hold all possible
values of the original class or structure.
See Also
Operator Statement
Narrowing
Widening and Narrowing Conversions
How to: Define an Operator
CType Function
Option Strict Statement
How to: Define a Conversion Operator
WithEvents (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
Specifies that one or more declared member variables refer to an instance of a class that can raise events.
Remarks
When a variable is defined using WithEvents , you can declaratively specify that a method handles the variable's
events using the Handles keyword.
You can use WithEvents only at class or module level. This means the declaration context for a WithEvents
variable must be a class or module and cannot be a source file, namespace, structure, or procedure.
You cannot use WithEvents on a structure member.
You can declare only individual variables—not arrays—with WithEvents .
Rules
Element Types. You must declare WithEvents variables to be object variables so that they can accept class
instances. However, you cannot declare them as Object . You must declare them as the specific class that can
raise the events.
The WithEvents modifier can be used in this context: Dim Statement
See Also
Handles
Keywords
Events
WriteOnly (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
Remarks
Rules
Declaration Context. You can use WriteOnly only at module level. This means the declaration context for a
WriteOnly property must be a class, structure, or module, and cannot be a source file, namespace, or procedure.
IMPORTANT
When you define and use a WriteOnly property, consider the following additional protective measures:
Overriding. If the property is a member of a class, allow it to default to NotOverridable, and do not declare
it Overridable or MustOverride . This prevents a derived class from making undesired access through an
override.
Access Level. If you hold the property's sensitive data in one or more variables, declare them Private so
that no other code can access them.
Encryption. Store all sensitive data in encrypted form rather than in plain text. If malicious code somehow
gains access to that area of memory, it is more difficult to make use of the data. Encryption is also useful if it
is necessary to serialize the sensitive data.
Resetting. When the class, structure, or module defining the property is being terminated, reset the
sensitive data to default values or to other meaningless values. This gives extra protection when that area of
memory is freed for general access.
Persistence. Do not persist any sensitive data, for example on disk, if you can avoid it. Also, do not write
any sensitive data to the Clipboard.
The WriteOnly modifier can be used in this context:
Property Statement
See Also
ReadOnly
Private
Keywords
Modules (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
Visual Basic provides several modules that enable you to simplify common tasks in your code, including
manipulating strings, performing mathematical calculations, getting system information, performing file and
directory operations, and so on. The following table lists the modules provided by Visual Basic.
DateAndTime Contains members that get the current date or time, perform
date calculations, return a date or time, set the date or time,
or time the duration of a process.
See Also
Visual Basic Language Reference
Visual Basic
Nothing (Visual Basic)
7/29/2017 • 3 min to read • Edit Online
Represents the default value of any data type. For reference types, the default value is the null reference. For
value types, the default value depends on whether the value type is nullable.
NOTE
For non-nullable value types, Nothing in Visual Basic differs from null in C#. In Visual Basic, if you set a variable of a
non-nullable value type to Nothing , the variable is set to the default value for its declared type. In C#, if you assign a
variable of a non-nullable value type to null , a compile-time error occurs.
Remarks
Nothing represents the default value of a data type. The default value depends on whether the variable is of a
value type or of a reference type.
A variable of a value type directly contains its value. Value types include all numeric data types, Boolean , Char ,
Date , all structures, and all enumerations. A variable of a reference type stores a reference to an instance of the
object in memory. Reference types include classes, arrays, delegates, and strings. For more information, see
Value Types and Reference Types.
If a variable is of a value type, the behavior of Nothing depends on whether the variable is of a nullable data
type. To represent a nullable value type, add a ? modifier to the type name. Assigning Nothing to a nullable
variable sets the value to null . For more information and examples, see Nullable Value Types.
If a variable is of a value type that is not nullable, assigning Nothing to it sets it to the default value for its
declared type. If that type contains variable members, they are all set to their default values. The following
example illustrates this for scalar types.
Module Module1
Sub Main()
Dim ts As TestStruct
Dim i As Integer
Dim b As Boolean
Console.ReadKey()
End Sub
If a variable is of a reference type, assigning Nothing to the variable sets it to a null reference of the variable's
type. A variable that is set to a null reference is not associated with any object. The following example
demonstrates this.
Module Module1
Sub Main()
End Sub
Class TestClass
Public Field1 As Integer
' . . .
End Class
End Module
When checking whether a reference (or nullable value type) variable is null , do not use = Nothing or
<> Nothing . Always use Is Nothing or IsNot Nothing .
For strings in Visual Basic, the empty string equals Nothing . Therefore, "" = Nothing is true.
The following example shows comparisons that use the Is and IsNot operators.
Module Module1
Sub Main()
n = 4
Console.WriteLine(n Is Nothing)
' Output: False
n = Nothing
Console.WriteLine(n IsNot Nothing)
' Output: False
Console.ReadKey()
End Sub
Class TestClass
Public Field1 As Integer
Private field2 As Boolean
End Class
End Module
If you declare a variable without using an As clause and set it to Nothing , the variable has a type of Object .
An example of this is Dim something = Nothing . A compile-time error occurs in this case when Option Strict is
on and Option Infer is off.
When you assign Nothing to an object variable, it no longer refers to any object instance. If the variable had
previously referred to an instance, setting it to Nothing does not terminate the instance itself. The instance is
terminated, and the memory and system resources associated with it are released, only after the garbage
collector (GC) detects that there are no active references remaining.
Nothing differs from the DBNull object, which represents an uninitialized variant or a nonexistent database
column.
See Also
Dim Statement
Object Lifetime: How Objects Are Created and Destroyed
Lifetime in Visual Basic
Is Operator
IsNot Operator
Nullable Value Types
Objects (Visual Basic)
7/29/2017 • 2 min to read • Edit Online
This topic provides links to other topics that document the Visual Basic run-time objects and contain tables of their
member procedures, properties, and events.
The My.Application object consists of the following classes: Provides data that is associated only with the current
application or DLL. No system-level information can be altered
ApplicationBase provides members that are available in all with My.Application .
projects.
Some members are available only for Windows Forms or
WindowsFormsApplicationBase provides members available in console applications.
Windows Forms applications.
My.Computer.Clock (Clock) Provides properties for accessing the current local time and
Universal Coordinated Time (equivalent to Greenwich Mean
Time) from the system clock.
My.Computer.FileSystem (FileSystem) Provides properties and methods for working with drives, files,
and directories.
My.Computer.Keyboard (Keyboard) Provides properties for accessing the current state of the
keyboard, such as what keys are currently pressed, and
provides a method to send keystrokes to the active window.
My.Computer.Mouse (Mouse) Provides properties for getting information about the format
and configuration of the mouse that is installed on the local
computer.
My.Log (AspLog) Provides a property and methods for writing event and
exception information to the application's log listeners for
Web applications.
My.Request Object Gets the HttpRequest object for the requested page. The
My.Request object contains information about the current
HTTP request.
My.Response Object Gets the HttpResponse object that is associated with the
Page. This object allows you to send HTTP response data to a
client and contains information about that response.
See Also
Visual Basic Language Reference
Visual Basic
My.Application Object
7/29/2017 • 1 min to read • Edit Online
Remarks
For information about the methods and properties of the My.Application object, see the following resources:
ApplicationBase for members that are available in all projects.
WindowsFormsApplicationBase for members that are available in Windows Forms applications.
ConsoleApplicationBase for members that are available in console applications.
Requirements
Namespace: Microsoft.VisualBasic.ApplicationServices
Class: WindowsFormsApplicationBase (the base class ConsoleApplicationBase provides members available in
console applications, and its base class ApplicationBase provides the members that are available in all projects)
Assembly: Visual Basic Runtime Library (in Microsoft.VisualBasic.dll)
See Also
My.Application.Info Object
My.Application.Log Object
My.Application.Info Object
7/29/2017 • 1 min to read • Edit Online
Provides properties for getting the information about the application, such as the version number, description,
loaded assemblies, and so on.
Remarks
For information about the methods and properties of the My.Application.Info object, see AssemblyInfo.
NOTE
You can use properties of the System.Diagnostics.FileVersionInfo class to obtain information about a file on disk.
Requirements
Namespace: Microsoft.VisualBasic.ApplicationServices
Class: AssemblyInfo
Assembly: Visual Basic Runtime Library (in Microsoft.VisualBasic.dll)
See Also
My.Application Object
My.Application.Log Object
7/29/2017 • 1 min to read • Edit Online
Provides a property and methods to write event and exception information to the application's log listeners.
Remarks
For information about the methods and properties of the My.Application.Log object, see Log.
For more information, see Logging Information from the Application.
NOTE
You can also use classes in the .NET Framework to log information from your application. For more information, see Tracing
and Instrumenting Applications.
Requirements
Namespace: Microsoft.VisualBasic.Logging
Class: Log
Assembly: Visual Basic Runtime Library (in Microsoft.VisualBasic.dll)
See Also
My.Application Object
My.Computer Object
7/29/2017 • 1 min to read • Edit Online
Provides properties for manipulating computer components such as audio, the clock, the keyboard, the file
system, and so on.
Remarks
For information about the methods and properties of the My.Computer object, see Computer. The base class
ServerComputer provides the members that are available in all projects.
Requirements
Namespace: Microsoft.VisualBasic.Devices
Class: Computer (the base class ServerComputer provides the members that are available in all projects).
Assembly: Visual Basic Runtime Library (in Microsoft.VisualBasic.dll)
See Also
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.Computer.Audio Object
7/29/2017 • 1 min to read • Edit Online
Remarks
For information about the methods and properties of the My.Computer.Audio object, see Audio.
For more information, see Playing Sounds.
Requirements
Namespace: Microsoft.VisualBasic.Devices
Class: Audio
Assembly: Visual Basic Runtime Library (in Microsoft.VisualBasic.dll)
See Also
My.Computer Object
My.Computer.Clipboard Object
7/29/2017 • 1 min to read • Edit Online
Remarks
For information about the methods and properties of the My.Computer.Clipboard object, see ClipboardProxy.
For more information, see Storing Data to and Reading from the Clipboard.
NOTE
You can also use methods of the System.Windows.Forms.Clipboard class to manipulate the Clipboard.
Requirements
Namespace: Microsoft.VisualBasic.MyServices
Class: ClipboardProxy (provides access to Clipboard)
Assembly: Visual Basic Runtime Library (in Microsoft.VisualBasic.dll)
See Also
Clipboard
My.Computer Object
My.Computer.Clock Object
7/29/2017 • 1 min to read • Edit Online
Provides properties for accessing the current local time and Universal Coordinated Time (equivalent to Greenwich
Mean Time) from the system clock.
Remarks
For information about the methods and properties of the My.Computer.Clock object, see Clock.
Requirements
Namespace: Microsoft.VisualBasic.Devices
Class: Clock
Assembly: Visual Basic Runtime Library (in Microsoft.VisualBasic.dll)
See Also
My.Computer Object
My.Computer.FileSystem Object
7/29/2017 • 1 min to read • Edit Online
Provides properties and methods for working with drives, files, and directories.
Remarks
For information about the methods and properties of the My.Computer.FileSystem object, see FileSystem.
For more information, see File Access with Visual Basic.
NOTE
You can also use classes in the System.IO namespace to work with drives, files, and directories.
Requirements
Namespace: Microsoft.VisualBasic.MyServices
Class: FileSystemProxy (provides access to FileSystem)
Assembly: Visual Basic Runtime Library (in Microsoft.VisualBasic.dll)
See Also
My.Computer.FileSystem.SpecialDirectories Object
My.Computer Object
My.Computer.FileSystem.SpecialDirectories Object
7/29/2017 • 1 min to read • Edit Online
Remarks
For information about the methods and properties of the My.Computer.FileSystem.SpecialDirectories object, see
SpecialDirectories.
For more information, see How to: Retrieve the Contents of the My Documents Directory.
Requirements
Namespace: Microsoft.VisualBasic.MyServices
Class: SpecialDirectoriesProxy (provides access to SpecialDirectories)
Assembly: Visual Basic Runtime Library (in Microsoft.VisualBasic.dll)
See Also
My.Computer.FileSystem Object
My.Computer Object
My.Computer.Info Object
7/29/2017 • 1 min to read • Edit Online
Provides properties for getting information about the computer's memory, loaded assemblies, name, and operating
system.
Remarks
For information about the properties of the My.Computer.Info object, see ComputerInfo.
Requirements
Namespace: Microsoft.VisualBasic.Devices
Class: ComputerInfo
Assembly: Visual Basic Runtime Library (in Microsoft.VisualBasic.dll)
See Also
My.Computer Object
My.Computer.Keyboard Object
7/29/2017 • 1 min to read • Edit Online
Provides properties for accessing the current state of the keyboard, such as what keys are currently pressed, and
provides a method to send keystrokes to the active window.
Remarks
For information about the methods and properties of the My.Computer.Keyword object, see Keyboard.
For more information, see Accessing the Keyboard.
Requirements
Namespace: Microsoft.VisualBasic.Devices
Class: Keyboard
Assembly: Visual Basic Runtime Library (in Microsoft.VisualBasic.dll)
See Also
My.Computer Object
My.Computer.Mouse Object
7/29/2017 • 1 min to read • Edit Online
Provides properties for getting information about the format and configuration of the mouse installed on the local
computer.
Remarks
For information about the methods and properties of the My.Computer.Mouse object, see Mouse.
For more information, see Accessing the Mouse.
Requirements
Namespace: Microsoft.VisualBasic.Devices
Class: Mouse
Assembly: Visual Basic Runtime Library (in Microsoft.VisualBasic.dll)
See Also
My.Computer Object
My.Computer.Network Object
7/29/2017 • 1 min to read • Edit Online
Provides a property, event, and methods for interacting with the network to which the computer is connected.
Remarks
For information about the methods and properties of the My.Computer.Network object, see Network.
For more information, see Performing Network Operations.
Requirements
Namespace: Microsoft.VisualBasic.Devices
Class: Network
Assembly: Visual Basic Runtime Library (in Microsoft.VisualBasic.dll)
See Also
My.Computer Object
My.Computer.Ports Object
7/29/2017 • 1 min to read • Edit Online
Provides a property and a method for accessing the computer's serial ports.
Remarks
For information about the methods and properties of the My.Computer.Ports object, see Ports.
For more information, see Accessing the Computer's Ports.
NOTE
You can also use properties and methods of the System.IO.Ports.SerialPort class to access the computer's serial ports.
Requirements
Namespace: Microsoft.VisualBasic.Devices
Class: Ports
Assembly: Visual Basic Runtime Library (in Microsoft.VisualBasic.dll)
See Also
My.Computer Object
My.Computer.Registry Object
7/29/2017 • 1 min to read • Edit Online
Remarks
For information about the methods and properties of the My.Computer.Registry object, see RegistryProxy.
For more information, see Reading from and Writing to the Registry.
NOTE
You can also manipulate the registry by using methods of the Microsoft.Win32.Registry class.
Requirements
Namespace: Microsoft.VisualBasic.MyServices
Class: RegistryProxy (provides access to Registry)
Assembly: Visual Basic Runtime Library (in Microsoft.VisualBasic.dll)
See Also
My.Computer Object
My.Forms Object
7/29/2017 • 3 min to read • Edit Online
Provides properties for accessing an instance of each Windows form declared in the current project.
Remarks
The My.Forms object provides an instance of each form in the current project. The name of the property is the
same as the name of the form that the property accesses. For information about adding forms to a project, see
How to: Add Windows Forms to a Project.
You can access the forms provided by the My.Forms object by using the name of the form, without qualification.
Because the property name is the same as the form's type name, this allows you to access a form as if it had a
default instance. For example, My.Forms.Form1.Show is equivalent to Form1.Show .
The My.Forms object exposes only the forms associated with the current project. It does not provide access to
forms declared in referenced DLLs. To access a form that a DLL provides, you must use the qualified name of the
form, written as DllName.FormName.
You can use the OpenForms property to get a collection of all the application's open forms.
The object and its properties are available only for Windows applications.
Properties
Each property of the My.Forms object provides access to an instance of a form in the current project. The name of
the property is the same as the name of the form that the property accesses, and the property type is the same as
the form's type.
NOTE
If there is a name collision, the property name to access a form is RootNamespaceNamespace\FormName. For example,
consider two forms named Form1. If one of these forms is in the root namespace WindowsApplication1 and in the
namespace Namespace1 , you would access that form through My.Forms.WindowsApplication1_Namespace1_Form1 .
The My.Forms object provides access to the instance of the application's main form that was created on startup.
For all other forms, the My.Forms object creates a new instance of the form when it is accessed and stores it.
Subsequent attempts to access that property return that instance of the form.
You can dispose of a form by assigning Nothing to the property for that form. The property setter calls the Close
method of the form, and then assigns Nothing to the stored value. If you assign any value other than Nothing to
the property, the setter throws an ArgumentException exception.
You can test whether a property of the My.Forms object stores an instance of the form by using the Is or
IsNot operator. You can use those operators to check if the value of the property is Nothing .
NOTE
Typically, the Is or IsNot operator has to read the value of the property to perform the comparison. However, if the
property currently stores Nothing , the property creates a new instance of the form and then returns that instance.
However, the Visual Basic compiler treats the properties of the My.Forms object differently and allows the Is or IsNot
operator to check the status of the property without altering its value.
Example
This example changes the title of the default SidebarMenu form.
For this example to work, your project must have a form named SidebarMenu . For more information, see How to:
Add Windows Forms to a Project.
This code will work only in a Windows Application project.
Requirements
Availability by Project Type
PROJECT TYPE AVAILABLE
Class Library No
Console Application No
Windows Service No
Web Site No
See Also
OpenForms
Form
Close
Objects
How to: Add Windows Forms to a Project
Is Operator
IsNot Operator
Accessing Application Forms
My.Log Object
7/29/2017 • 1 min to read • Edit Online
Provides a property and methods for writing event and exception information to the application's log listeners.
Remarks
For information about the methods and properties of the My.Log object, see AspLog.
The My.Log object is available for ASP.NET applications only. For client applications, use My.Application.Log Object.
Requirements
Namespace: Microsoft.VisualBasic.Logging
Class: AspLog
Assembly: Visual Basic Runtime Library (in Microsoft.VisualBasic.dll)
My.Request Object
7/29/2017 • 1 min to read • Edit Online
Remarks
The My.Request object contains information about the current HTTP request.
The My.Request object is available only for ASP.NET applications.
Example
The following example gets the header collection from the My.Request object and uses the My.Response object to
write it to the ASP.NET page.
<script runat="server">
Public Sub ShowHeaders()
' Load the header collection from the Request object.
Dim coll As System.Collections.Specialized.NameValueCollection
coll = My.Request.Headers
See Also
HttpRequest
My.Response Object
My.Response Object
7/29/2017 • 1 min to read • Edit Online
Gets the HttpResponse object associated with the Page. This object allows you to send HTTP response data to a
client and contains information about that response.
Remarks
The My.Response object contains the current HttpResponse object associated with the page.
The My.Response object is only available for ASP.NET applications.
Example
The following example gets the header collection from the My.Request object and uses the My.Response object to
write it to the ASP.NET page.
<script runat="server">
Public Sub ShowHeaders()
' Load the header collection from the Request object.
Dim coll As System.Collections.Specialized.NameValueCollection
coll = My.Request.Headers
See Also
HttpResponse
My.Request Object
My.Resources Object
7/29/2017 • 3 min to read • Edit Online
Remarks
The My.Resources object provides access to the application's resources and lets you dynamically retrieve
resources for your application. For more information, see Managing Application Resources (.NET).
The My.Resources object exposes only global resources. It does not provide access to resource files associated with
forms. You must access the form resources from the form. For more information, see Walkthrough: Localizing
Windows Forms.
You can access the application's culture-specific resource files from the My.Resources object. By default, the
My.Resources object looks up resources from the resource file that matches the culture in the UICulture property.
However, you can override this behavior and specify a particular culture to use for the resources. For more
information, see Resources in Desktop Apps.
Properties
The properties of the My.Resources object provide read-only access to your application's resources. To add or
remove resources, use the Project Designer. For more information, see How to: Add or Remove Resources. You
can access resources added through the Project Designer by using My.Resources.``resourceName .
You can also add or remove resource files by selecting your project in Solution Explorer and clicking Add New
Item or Add Existing Item from the Project menu. You can access resources added in this manner by using
My.Resources.``resourceFileName . resourceName .
Each resource has a name, category, and value, and these resource settings determine how the property to access
the resource appears in the My.Resources object. For resources added in the Project Designer:
The name determines the name of the property,
The resource data is the value of the property,
The category determines the type of the property:
Strings String
Images Bitmap
Icons Icon
Audio UnmanagedMemoryStream
Classes
The My.Resources object exposes each resource file as a class with shared properties. The class name is the same
as the name of the resource file. As described in the previous section, the resources in a resource file are exposed
as properties in the class.
Example
This example sets the title of a form to the string resource named Form1Title in the application resource file. For
the example to work, the application must have a string named Form1Title in its resource file. For more
information, see How to: Add or Remove Resources.
Sub SetFormTitle()
Me.Text = My.Resources.Form1Title
End Sub
Example
This example sets the icon of the form to the icon named Form1Icon that is stored in the application's resource file.
For the example to work, the application must have an icon named Form1Icon in its resource file.
Sub SetFormIcon()
Me.Icon = My.Resources.Form1Icon
End Sub
Example
This example sets the background image of a form to the image resource named Form1Background , which is in the
application resource file. For this example to work, the application must have an image resource named
Form1Background in its resource file.
Sub SetFormBackgroundImage()
Me.BackgroundImage = My.Resources.Form1Background
End Sub
Example
This example plays the sound that is stored as an audio resource named Form1Greeting in the application's
resource file. For the example to work, the application must have an audio resource named Form1Greeting in its
resource file. The My.Computer.Audio.Play method is available only for Windows Forms applications.
Sub PlayFormGreeting()
My.Computer.Audio.Play(My.Resources.Form1Greeting,
AudioPlayMode.Background)
End Sub
Example
This example retrieves the French-culture version of a string resource of the application. The resource is named
Message . To change the culture that the My.Resources object uses, the example uses ChangeUICulture.
For this example to work, the application must have a string named Message in its resource file, and the
application should have the French-culture version of that resource file, Resources.fr-FR.resx. For more
information, see How to: Add or Remove Resources. If the application does not have the French-culture version of
the resource file, the My.Resource object retrieves the resource from the default-culture resource file.
Sub ShowLocalizedMessage()
Dim culture As String = My.Application.UICulture.Name
My.Application.ChangeUICulture("fr-FR")
MsgBox(My.Resources.Message)
My.Application.ChangeUICulture(culture)
End Sub
See Also
How to: Add or Remove Resources
Managing Application Resources (.NET)
Resources in Desktop Apps
Walkthrough: Localizing Windows Forms
My.Settings Object
7/29/2017 • 1 min to read • Edit Online
Remarks
The My.Settings object provides access to the application's settings and allows you to dynamically store and
retrieve property settings and other information for your application. For more information, see Managing
Application Settings (.NET).
Properties
The properties of the My.Settings object provide access to your application's settings. To add or remove settings,
use the Settings Designer.
Each setting has a Name, Type, Scope, and Value, and these settings determine how the property to access each
setting appears in the My.Settings object:
Name determines the name of the property.
Type determines the type of the property.
Scope indicates if the property is read-only. If the value is Application, the property is read-only; if the
value is User, the property is read-write.
Value is the default value of the property.
Methods
METHOD DESCRIPTION
Reload Reloads the user settings from the last saved values.
The My.Settings object also provides advanced properties and methods, inherited from the
ApplicationSettingsBase class.
Tasks
The following table lists examples of tasks involving the My.Settings object.
TO SEE
Read an application setting How to: Read Application Settings in Visual Basic
Change a user setting How to: Change User Settings in Visual Basic
Persist user settings How to: Persist User Settings in Visual Basic
TO SEE
Create a property grid for user settings How to: Create Property Grids for User Settings in Visual Basic
Example
This example displays the value of the Nickname setting.
Sub ShowNickname()
MsgBox("Nickname is " & My.Settings.Nickname)
End Sub
For this example to work, your application must have a Nickname setting, of type String .
See Also
ApplicationSettingsBase
How to: Read Application Settings in Visual Basic
How to: Change User Settings in Visual Basic
How to: Persist User Settings in Visual Basic
How to: Create Property Grids for User Settings in Visual Basic
Managing Application Settings (.NET)
My.User Object
7/29/2017 • 1 min to read • Edit Online
Remarks
For information about the methods and properties of the My.User object, see
Microsoft.VisualBasic.ApplicationServices.User.
For more information, see Accessing User Data.
Requirements
Assembly: Visual Basic Runtime Library (in Microsoft.VisualBasic.dll)
See Also
IPrincipal
CurrentPrincipal
User
Current
My.WebServices Object
7/29/2017 • 2 min to read • Edit Online
Provides properties for creating and accessing a single instance of each XML Web service referenced by the
current project.
Remarks
The My.WebServices object provides an instance of each Web service referenced by the current project. Each
instance is instantiated on demand. You can access these Web services through the properties of the
My.WebServices object. The name of the property is the same as the name of the Web service that the property
accesses. Any class that inherits from SoapHttpClientProtocol is a Web service. For information about adding
Web services to a project, see Accessing Application Web Services.
The My.WebServices object exposes only the Web services associated with the current project. It does not provide
access to Web services declared in referenced DLLs. To access a Web service that a DLL provides, you must use
the qualified name of the Web service, in the form DllName.WebServiceName. For more information, see
Accessing Application Web Services.
The object and its properties are not available for Web applications.
Properties
Each property of the My.WebServices object provides access to an instance of a Web service referenced by the
current project. The name of the property is the same as the name of the Web service that the property accesses,
and the property type is the same as the Web service's type.
NOTE
If there is a name collision, the property name for accessing a Web service is RootNamespaceNamespace\ServiceName.
For example, consider two Web services named Service1 . If one of these services is in the root namespace
WindowsApplication1 and in the namespace Namespace1 , you would access that service by using
My.WebServices.WindowsApplication1_Namespace1_Service1 .
When you first access one of the My.WebServices object's properties, it creates a new instance of the Web service
and stores it. Subsequent accesses of that property return that instance of the Web service.
You can dispose of a Web service by assigning Nothing to the property for that Web service. The property setter
assigns Nothing to the stored value. If you assign any value other than Nothing to the property, the setter
throws an ArgumentException exception.
You can test whether a property of the My.WebServices object stores an instance of the Web service by using the
Is or IsNot operator. You can use those operators to check if the value of the property is Nothing .
NOTE
Typically, the Is or IsNot operator has to read the value of the property to perform the comparison. However, if the
property currently stores Nothing , the property creates a new instance of the Web service and then returns that
instance. However, the Visual Basic compiler treats the properties of the My.WebServices object specially, and allows the
Is or IsNot operator to check the status of the property without altering its value.
Example
This example calls the FahrenheitToCelsius method of the TemperatureConverter XML Web service, and returns
the result.
Function ConvertFromFahrenheitToCelsius(
ByVal dFahrenheit As Double) As Double
Return My.WebServices.TemperatureConverter.FahrenheitToCelsius(dFahrenheit)
End Function
For this example to work, your project must reference a Web service named Converter , and that Web service
must expose the ConvertTemperature method. For more information, see Accessing Application Web Services.
This code does not work in a Web application project.
Requirements
Availability by Project Type
PROJECT TYPE AVAILABLE
Web Site No
See Also
SoapHttpClientProtocol
ArgumentException
Accessing Application Web Services
TextFieldParser Object
7/29/2017 • 1 min to read • Edit Online
Syntax
Public Class TextFieldParser
Remarks
For information about the methods and properties of the TextFieldParser object, see TextFieldParser.
For more information, see Reading from Files.
Requirements
Namespace: Microsoft.VisualBasic.FileIO
Class: TextFieldParser
Assembly: Visual Basic Runtime Library (in Microsoft.VisualBasic.dll)
Operators (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
In This Section
Operator Precedence in Visual Basic
Operators Listed by Functionality
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
Related Sections
Visual Basic Language Reference
Visual Basic
Operator Precedence in Visual Basic
7/29/2017 • 3 min to read • Edit Online
When several operations occur in an expression, each part is evaluated and resolved in a predetermined order
called operator precedence.
Precedence Rules
When expressions contain operators from more than one category, they are evaluated according to the
following rules:
The arithmetic and concatenation operators have the order of precedence described in the following
section, and all have greater precedence than the comparison, logical, and bitwise operators.
All comparison operators have equal precedence, and all have greater precedence than the logical and
bitwise operators, but lower precedence than the arithmetic and concatenation operators.
The logical and bitwise operators have the order of precedence described in the following section, and
all have lower precedence than the arithmetic, concatenation, and comparison operators.
Operators with equal precedence are evaluated left to right in the order in which they appear in the
expression.
Precedence Order
Operators are evaluated in the following order of precedence:
Await Operator
Await
Arithmetic and Concatenation Operators
Exponentiation ( ^ )
Unary identity and negation ( + , – )
Multiplication and floating-point division ( * , / )
Integer division ( \ )
Modulus arithmetic ( Mod )
Addition and subtraction ( + , – )
String concatenation ( & )
Arithmetic bit shift ( << , >> )
Comparison Operators
All comparison operators ( = , <> , < , <= , > , >= , Is , IsNot , Like , TypeOf ... Is )
Logical and Bitwise Operators
Negation ( Not )
Conjunction ( And , AndAlso )
Inclusive disjunction ( Or , OrElse )
Exclusive disjunction ( Xor )
Comments
The = operator is only the equality comparison operator, not the assignment operator.
The string concatenation operator ( & ) is not an arithmetic operator, but in precedence it is grouped with the
arithmetic operators.
The Is and IsNot operators are object reference comparison operators. They do not compare the values of
two objects; they check only to determine whether two object variables refer to the same object instance.
Associativity
When operators of equal precedence appear together in an expression, for example multiplication and
division, the compiler evaluates each operation as it encounters it from left to right. The following example
illustrates this.
Dim n1 As Integer = 96 / 8 / 4
Dim n2 As Integer = (96 / 8) / 4
Dim n3 As Integer = 96 / (8 / 4)
The first expression evaluates the division 96 / 8 (which results in 12) and then the division 12 / 4, which
results in three. Because the compiler evaluates the operations for n1 from left to right, the evaluation is the
same when that order is explicitly indicated for n2 . Both n1 and n2 have a result of three. By contrast, n3
has a result of 48, because the parentheses force the compiler to evaluate 8 / 4 first.
Because of this behavior, operators are said to be left associative in Visual Basic.
Dim a, b, c, d, e, f, g As Double
a = 8.0
b = 3.0
c = 4.0
d = 2.0
e = 1.0
f = a - b + c / d * e
' The preceding line sets f to 7.0. Because of natural operator
' precedence and associativity, it is exactly equivalent to the
' following line.
f = (a - b) + ((c / d) * e)
' The following line overrides the natural operator precedence
' and left associativity.
g = (a - (b + c)) / (d * e)
' The preceding line sets g to 0.5.
See Also
= Operator
Is Operator
IsNot Operator
Like Operator
TypeOf Operator
Await Operator
Operators Listed by Functionality
Operators and Expressions
Operators Listed by Functionality (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
See one of the categories listed below, or open this portion of the Help table of contents to see an
alphabetical list of Visual Basic operators.
Categories of Operators
OPERATORS DESCRIPTION
Bit Shift Operators These operators perform arithmetic shifts on bit patterns.
See Also
Operators and Expressions
Operator Precedence in Visual Basic
& Operator (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
Syntax
result = expression1 & expression2
Parts
result
Required. Any String or Object variable.
expression1
Required. Any expression with a data type that widens to String .
expression2
Required. Any expression with a data type that widens to String .
Remarks
If the data type of expression1 or expression2 is not String but widens to String , it is converted to String . If
either of the data types does not widen to String , the compiler generates an error.
The data type of result is String . If one or both expressions evaluate to Nothing or have a value of
System.DBNull.Value, they are treated as a string with a value of "".
NOTE
The & operator can be overloaded, which means that a class or structure can redefine its behavior when an operand has
the type of that class or structure. If your code uses this operator on such a class or structure, be sure you understand its
redefined behavior. For more information, see Operator Procedures.
NOTE
The ampersand (&) character can also be used to identify variables as type Long . For more information, see Type
Characters.
Example
This example uses the & operator to force string concatenation. The result is a string value representing the
concatenation of the two string operands.
Concatenates a String expression to a String variable or property and assigns the result to the variable or
property.
Syntax
variableorproperty &= expression
Parts
variableorproperty
Required. Any String variable or property.
expression
Required. Any String expression.
Remarks
The element on the left side of the &= operator can be a simple scalar variable, a property, or an element of an
array. The variable or property cannot be ReadOnly. The &= operator concatenates the String expression on its
right to the String variable or property on its left, and assigns the result to the variable or property on its left.
Overloading
The & Operator can be overloaded, which means that a class or structure can redefine its behavior when an
operand has the type of that class or structure. Overloading the & operator affects the behavior of the &=
operator. If your code uses &= on a class or structure that overloads & , be sure you understand its redefined
behavior. For more information, see Operator Procedures.
Example
The following example uses the &= operator to concatenate two String variables and assign the result to the
first variable.
See Also
& Operator
+= Operator
Assignment Operators
Concatenation Operators
Operator Precedence in Visual Basic
Operators Listed by Functionality
Statements
* Operator (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
Syntax
number1 * number2
Parts
TERM DEFINITION
Result
The result is the product of number1 and number2 .
Supported Types
All numeric types, including the unsigned and floating-point types and Decimal .
Remarks
The data type of the result depends on the types of the operands. The following table shows how the data type of
the result is determined.
Both expressions are integral data types (SByte, Byte, Short, A numeric data type appropriate for the data types of
UShort, Integer, UInteger, Long, ULong) number1 and number2 . See the "Integer Arithmetic" tables
in Data Types of Operator Results.
Overloading
The * operator can be overloaded, which means that a class or structure can redefine its behavior when an
operand has the type of that class or structure. If your code uses this operator on such a class or structure, be sure
you understand its redefined behavior. For more information, see Operator Procedures.
Example
This example uses the * operator to multiply two numbers. The result is the product of the two operands.
See Also
*= Operator
Arithmetic Operators
Operator Precedence in Visual Basic
Operators Listed by Functionality
Arithmetic Operators in Visual Basic
*= Operator (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
Multiplies the value of a variable or property by the value of an expression and assigns the result to the variable or
property.
Syntax
variableorproperty *= expression
Parts
variableorproperty
Required. Any numeric variable or property.
expression
Required. Any numeric expression.
Remarks
The element on the left side of the *= operator can be a simple scalar variable, a property, or an element of an
array. The variable or property cannot be ReadOnly.
The *= operator first multiplies the value of the expression (on the right-hand side of the operator) by the value
of the variable or property (on the left-hand side of the operator). The operator then assigns the result of that
operation to the variable or property.
Overloading
The * Operator can be overloaded, which means that a class or structure can redefine its behavior when an
operand has the type of that class or structure. Overloading the * operator affects the behavior of the *=
operator. If your code uses *= on a class or structure that overloads * , be sure you understand its redefined
behavior. For more information, see Operator Procedures.
Example
The following example uses the *= operator to multiply one Integer variable by a second and assign the result
to the first variable.
See Also
* Operator
Assignment Operators
Arithmetic Operators
Operator Precedence in Visual Basic
Operators Listed by Functionality
Statements
+ Operator (Visual Basic)
7/29/2017 • 4 min to read • Edit Online
Adds two numbers or returns the positive value of a numeric expression. Can also be used to concatenate two
string expressions.
Syntax
expression1 + expression2
- or -
+ expression1
Parts
TERM DEFINITION
Result
If expression1 and expression2 are both numeric, the result is their arithmetic sum.
If expression2 is absent, the + operator is the unary identity operator for the unchanged value of an expression.
In this sense, the operation consists of retaining the sign of expression1 , so the result is negative if expression1 is
negative.
If expression1 and expression2 are both strings, the result is the concatenation of their values.
If expression1 and expression2 are of mixed types, the action taken depends on their types, their contents, and
the setting of the Option Strict Statement. For more information, see the tables in "Remarks."
Supported Types
All numeric types, including the unsigned and floating-point types and Decimal , and String .
Remarks
In general, + performs arithmetic addition when possible, and concatenates only when both expressions are
strings.
If neither expression is an Object , Visual Basic takes the following actions.
DATA TYPES OF EXPRESSIONS ACTION BY COMPILER
Both expressions are numeric data types ( SByte , Byte , Add. The result data type is a numeric type appropriate for
Short , UShort , Integer , UInteger , Long , ULong , the data types of expression1 and expression2 . See the
Decimal , Single , or Double ) "Integer Arithmetic" tables in Data Types of Operator Results.
One expression is a numeric data type and the other is a If Option Strict is On , then generate a compiler error.
string
If Option Strict is Off , then implicitly convert the
String to Double and add.
One expression is a numeric data type, and the other is Add, with Nothing valued as zero.
Nothing
One expression is a string, and the other is Nothing Concatenate, with Nothing valued as "".
If one expression is an Object expression, Visual Basic takes the following actions.
Object expression holds a numeric value and the other is a If Option Strict is On , then generate a compiler error.
numeric data type
If Option Strict is Off , then add.
Object expression holds a numeric value and the other is of If Option Strict is On , then generate a compiler error.
type String
If Option Strict is Off , then implicitly convert the
String to Double and add.
Object expression holds a string and the other is a numeric If Option Strict is On , then generate a compiler error.
data type
If Option Strict is Off , then implicitly convert the string
Object to Double and add.
Object expression holds a string and the other is of type If Option Strict is On , then generate a compiler error.
String
If Option Strict is Off , then implicitly convert Object
to String and concatenate.
If both expressions are Object expressions, Visual Basic takes the following actions ( Option Strict Off only).
One Object expression holds a numeric value and the other Implicitly convert the string Object to Double and add.
holds a string
If the string Object cannot be converted to a numeric value,
then throw an InvalidCastException exception.
If either Object expression evaluates to Nothing or DBNull, the + operator treats it as a String with a value of
"".
NOTE
When you use the + operator, you might not be able to determine whether addition or string concatenation will occur.
Use the & operator for concatenation to eliminate ambiguity and to provide self-documenting code.
Overloading
The + operator can be overloaded, which means that a class or structure can redefine its behavior when an
operand has the type of that class or structure. If your code uses this operator on such a class or structure, be sure
you understand its redefined behavior. For more information, see Operator Procedures.
Example
The following example uses the + operator to add numbers. If the operands are both numeric, Visual Basic
computes the arithmetic result. The arithmetic result represents the sum of the two operands.
You can also use the + operator to concatenate strings. If the operands are both strings, Visual Basic
concatenates them. The concatenation result represents a single string consisting of the contents of the two
operands one after the other.
If the operands are of mixed types, the result depends on the setting of the Option Strict Statement. The following
example illustrates the result when Option Strict is On .
Option Strict On
The following example illustrates the result when Option Strict is Off .
Option Strict Off
To eliminate ambiguity, you should use the & operator instead of + for concatenation.
See Also
& Operator
Concatenation Operators
Arithmetic Operators
Operators Listed by Functionality
Operator Precedence in Visual Basic
Arithmetic Operators in Visual Basic
Option Strict Statement
+= Operator (Visual Basic)
7/29/2017 • 2 min to read • Edit Online
Adds the value of a numeric expression to the value of a numeric variable or property and assigns the result to the
variable or property. Can also be used to concatenate a String expression to a String variable or property and
assign the result to the variable or property.
Syntax
variableorproperty += expression
Parts
variableorproperty
Required. Any numeric or String variable or property.
expression
Required. Any numeric or String expression.
Remarks
The element on the left side of the += operator can be a simple scalar variable, a property, or an element of an
array. The variable or property cannot be ReadOnly.
The += operator adds the value on its right to the variable or property on its left, and assigns the result to the
variable or property on its left. The += operator can also be used to concatenate the String expression on its
right to the String variable or property on its left, and assign the result to the variable or property on its left.
NOTE
When you use the += operator, you might not be able to determine whether addition or string concatenation will occur.
Use the &= operator for concatenation to eliminate ambiguity and to provide self-documenting code.
This assignment operator implicitly performs widening but not narrowing conversions if the compilation
environment enforces strict semantics. For more information on these conversions, see Widening and Narrowing
Conversions. For more information on strict and permissive semantics, see Option Strict Statement.
If permissive semantics are allowed, the += operator implicitly performs a variety of string and numeric
conversions identical to those performed by the + operator. For details on these conversions, see + Operator.
Overloading
The + operator can be overloaded, which means that a class or structure can redefine its behavior when an
operand has the type of that class or structure. Overloading the + operator affects the behavior of the +=
operator. If your code uses += on a class or structure that overloads + , be sure you understand its redefined
behavior. For more information, see Operator Procedures.
Example
The following example uses the += operator to combine the value of one variable with another. The first part uses
+= with numeric variables to add one value to another. The second part uses += with String variables to
concatenate one value with another. In both cases, the result is assigned to the first variable.
The value of num1 is now 13, and the value of str1 is now "103".
See Also
+ Operator
Assignment Operators
Arithmetic Operators
Concatenation Operators
Operator Precedence in Visual Basic
Operators Listed by Functionality
Statements
= Operator (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
Syntax
variableorproperty = value
Parts
variableorproperty
Any writable variable or any property.
value
Any literal, constant, or expression.
Remarks
The element on the left side of the equal sign ( = ) can be a simple scalar variable, a property, or an element of an
array. The variable or property cannot be ReadOnly. The = operator assigns the value on its right to the variable
or property on its left.
NOTE
The = operator is also used as a comparison operator. For details, see Comparison Operators.
Overloading
The = operator can be overloaded only as a relational comparison operator, not as an assignment operator. For
more information, see Operator Procedures.
Example
The following example demonstrates the assignment operator. The value on the right is assigned to the variable
on the left.
See Also
&= Operator
*= Operator
+= Operator
-= Operator (Visual Basic)
/= Operator (Visual Basic)
\= Operator
^= Operator
Statements
Comparison Operators
ReadOnly
Local Type Inference
- Operator (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
Returns the difference between two numeric expressions or the negative value of a numeric expression.
Syntax
expression1 – expression2
- or -
– expression1
Parts
expression1
Required. Any numeric expression.
expression2
Required unless the – operator is calculating a negative value. Any numeric expression.
Result
The result is the difference between expression1 and expression2 , or the negated value of expression1 .
The result data type is a numeric type appropriate for the data types of expression1 and expression2 . See the
"Integer Arithmetic" tables in Data Types of Operator Results.
Supported Types
All numeric types. This includes the unsigned and floating-point types and Decimal .
Remarks
In the first usage shown in the syntax shown previously, the – operator is the binary arithmetic subtraction
operator for the difference between two numeric expressions.
In the second usage shown in the syntax shown previously, the – operator is the unary negation operator for the
negative value of an expression. In this sense, the negation consists of reversing the sign of expression1 so that
the result is positive if expression1 is negative.
If either expression evaluates to Nothing, the – operator treats it as zero.
NOTE
The – operator can be overloaded, which means that a class or structure can redefine its behavior when an operand has
the type of that class or structure. If your code uses this operator on such a class or structure, make sure that you
understand its redefined behavior. For more information, see Operator Procedures.
Example
The following example uses the – operator to calculate and return the difference between two numbers, and then
to negate a number.
Following the execution of these statements, binaryResult contains 124.45 and unaryResult contains –334.90.
See Also
-= Operator (Visual Basic) Arithmetic Operators
Operator Precedence in Visual Basic
Operators Listed by Functionality
Arithmetic Operators in Visual Basic
-= Operator (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
Subtracts the value of an expression from the value of a variable or property and assigns the result to the variable
or property.
Syntax
variableorproperty -= expression
Parts
variableorproperty
Required. Any numeric variable or property.
expression
Required. Any numeric expression.
Remarks
The element on the left side of the -= operator can be a simple scalar variable, a property, or an element of an
array. The variable or property cannot be ReadOnly.
The -= operator first subtracts the value of the expression (on the right-hand side of the operator) from the value
of the variable or property (on the left-hand side of the operator). The operator then assigns the result of that
operation to the variable or property.
Overloading
The - Operator (Visual Basic) can be overloaded, which means that a class or structure can redefine its behavior
when an operand has the type of that class or structure. Overloading the - operator affects the behavior of the
-= operator. If your code uses -= on a class or structure that overloads - , be sure you understand its redefined
behavior. For more information, see Operator Procedures.
Example
The following example uses the -= operator to subtract one Integer variable from another and assign the result
to the latter variable.
See Also
- Operator (Visual Basic)
Assignment Operators
Arithmetic Operators
Operator Precedence in Visual Basic
Operators Listed by Functionality
Statements
<< Operator (Visual Basic)
7/29/2017 • 2 min to read • Edit Online
Syntax
result = pattern << amount
Parts
result
Required. Integral numeric value. The result of shifting the bit pattern. The data type is the same as that of pattern .
pattern
Required. Integral numeric expression. The bit pattern to be shifted. The data type must be an integral type ( SByte ,
Byte , Short , UShort , Integer , UInteger , Long , or ULong ).
amount
Required. Numeric expression. The number of bits to shift the bit pattern. The data type must be Integer or widen
to Integer .
Remarks
Arithmetic shifts are not circular, which means the bits shifted off one end of the result are not reintroduced at the
other end. In an arithmetic left shift, the bits shifted beyond the range of the result data type are discarded, and the
bit positions vacated on the right are set to zero.
To prevent a shift by more bits than the result can hold, Visual Basic masks the value of amount with a size mask
that corresponds to the data type of pattern . The binary AND of these values is used for the shift amount. The size
masks are as follows:
If amount is zero, the value of result is identical to the value of pattern . If amount is negative, it is taken as an
unsigned value and masked with the appropriate size mask.
Arithmetic shifts never generate overflow exceptions.
NOTE
The << operator can be overloaded, which means that a class or structure can redefine its behavior when an operand has
the type of that class or structure. If your code uses this operator on such a class or structure, be sure that you understand
its redefined behavior. For more information, see Operator Procedures.
Example
The following example uses the << operator to perform arithmetic left shifts on integral values. The result always
has the same data type as that of the expression being shifted.
The shift amount for result4 is calculated as 17 AND 15, which equals 1.
See Also
Bit Shift Operators
Assignment Operators
<<= Operator
Operator Precedence in Visual Basic
Operators Listed by Functionality
Arithmetic Operators in Visual Basic
<<= Operator (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
Performs an arithmetic left shift on the value of a variable or property and assigns the result back to the variable or
property.
Syntax
variableorproperty <<= amount
Parts
variableorproperty
Required. Variable or property of an integral type ( SByte , Byte , Short , UShort , Integer , UInteger , Long , or
ULong ).
amount
Required. Numeric expression of a data type that widens to Integer .
Remarks
The element on the left side of the <<= operator can be a simple scalar variable, a property, or an element of an
array. The variable or property cannot be ReadOnly.
The <<= operator first performs an arithmetic left shift on the value of the variable or property. The operator then
assigns the result of that operation back to that variable or property.
Arithmetic shifts are not circular, which means the bits shifted off one end of the result are not reintroduced at the
other end. In an arithmetic left shift, the bits shifted beyond the range of the result data type are discarded, and the
bit positions vacated on the right are set to zero.
Overloading
The << Operator can be overloaded, which means that a class or structure can redefine its behavior when an
operand has the type of that class or structure. Overloading the << operator affects the behavior of the <<=
operator. If your code uses <<= on a class or structure that overloads << , be sure you understand its redefined
behavior. For more information, see Operator Procedures.
Example
The following example uses the <<= operator to shift the bit pattern of an Integer variable left by the specified
amount and assign the result to the variable.
Syntax
result = pattern >> amount
Parts
result
Required. Integral numeric value. The result of shifting the bit pattern. The data type is the same as that of pattern .
pattern
Required. Integral numeric expression. The bit pattern to be shifted. The data type must be an integral type ( SByte ,
Byte , Short , UShort , Integer , UInteger , Long , or ULong ).
amount
Required. Numeric expression. The number of bits to shift the bit pattern. The data type must be Integer or widen
to Integer .
Remarks
Arithmetic shifts are not circular, which means the bits shifted off one end of the result are not reintroduced at the
other end. In an arithmetic right shift, the bits shifted beyond the rightmost bit position are discarded, and the
leftmost (sign) bit is propagated into the bit positions vacated at the left. This means that if pattern has a negative
value, the vacated positions are set to one; otherwise they are set to zero.
Note that the data types Byte , UShort , UInteger , and ULong are unsigned, so there is no sign bit to propagate. If
pattern is of any unsigned type, the vacated positions are always set to zero.
To prevent shifting by more bits than the result can hold, Visual Basic masks the value of amount with a size mask
corresponding to the data type of pattern . The binary AND of these values is used for the shift amount. The size
masks are as follows:
If amount is zero, the value of result is identical to the value of pattern . If amount is negative, it is taken as an
unsigned value and masked with the appropriate size mask.
Arithmetic shifts never generate overflow exceptions.
Overloading
The >> operator can be overloaded, which means that a class or structure can redefine its behavior when an
operand has the type of that class or structure. If your code uses this operator on such a class or structure, be sure
you understand its redefined behavior. For more information, see Operator Procedures.
Example
The following example uses the >> operator to perform arithmetic right shifts on integral values. The result
always has the same data type as that of the expression being shifted.
See Also
Bit Shift Operators
Assignment Operators
>>= Operator
Operator Precedence in Visual Basic
Operators Listed by Functionality
Arithmetic Operators in Visual Basic
>>= Operator (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
Performs an arithmetic right shift on the value of a variable or property and assigns the result back to the variable
or property.
Syntax
variableorproperty >>= amount
Parts
variableorproperty
Required. Variable or property of an integral type ( SByte , Byte , Short , UShort , Integer , UInteger , Long , or
ULong ).
amount
Required. Numeric expression of a data type that widens to Integer .
Remarks
The element on the left side of the >>= operator can be a simple scalar variable, a property, or an element of an
array. The variable or property cannot be ReadOnly.
The >>= operator first performs an arithmetic right shift on the value of the variable or property. The operator
then assigns the result of that operation back to the variable or property.
Arithmetic shifts are not circular, which means the bits shifted off one end of the result are not reintroduced at the
other end. In an arithmetic right shift, the bits shifted beyond the rightmost bit position are discarded, and the
leftmost bit is propagated into the bit positions vacated at the left. This means that if variableorproperty has a
negative value, the vacated positions are set to one. If variableorproperty is positive, or if its data type is an
unsigned type, the vacated positions are set to zero.
Overloading
The >> Operator can be overloaded, which means that a class or structure can redefine its behavior when an
operand has the type of that class or structure. Overloading the >> operator affects the behavior of the >>=
operator. If your code uses >>= on a class or structure that overloads >> , be sure you understand its redefined
behavior. For more information, see Operator Procedures.
Example
The following example uses the >>= operator to shift the bit pattern of an Integer variable right by the specified
amount and assign the result to the variable.
Syntax
expression1 / expression2
Parts
expression1
Required. Any numeric expression.
expression2
Required. Any numeric expression.
Supported Types
All numeric types, including the unsigned and floating-point types and Decimal .
Result
The result is the full quotient of expression1 divided by expression2 , including any remainder.
The \ Operator (Visual Basic) returns the integer quotient, which drops the remainder.
Remarks
The data type of the result depends on the types of the operands. The following table shows how the data type of
the result is determined.
Both expressions are integral data types (SByte, Byte, Short, Double
UShort, Integer, UInteger, Long, ULong)
One expression is a Single data type and the other is not a Single
Double
One expression is a Decimal data type and the other is not a Decimal
Single or a Double
Before division is performed, any integral numeric expressions are widened to Double . If you assign the result to
an integral data type, Visual Basic attempts to convert the result from Double to that type. This can throw an
exception if the result does not fit in that type. In particular, see "Attempted Division by Zero" on this Help page.
If expression1 or expression2 evaluates to Nothing, it is treated as zero.
Attempted Division by Zero
If expression2 evaluates to zero, the / operator behaves differently for different operand data types. The
following table shows the possible behaviors.
NOTE
The / operator can be overloaded, which means that a class or structure can redefine its behavior when an operand has
the type of that class or structure. If your code uses this operator on such a class or structure, be sure you understand its
redefined behavior. For more information, see Operator Procedures.
Example
This example uses the / operator to perform floating-point division. The result is the quotient of the two
operands.
The expressions in the preceding example return values of 2.5 and 3.333333. Note that the result is always
floating-point ( Double ), even though both operands are integer constants.
See Also
/= Operator (Visual Basic)
\ Operator (Visual Basic)
Data Types of Operator Results
Arithmetic Operators
Operator Precedence in Visual Basic
Operators Listed by Functionality
Arithmetic Operators in Visual Basic
/= Operator (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
Divides the value of a variable or property by the value of an expression and assigns the floating-point result to
the variable or property.
Syntax
variableorproperty /= expression
Parts
variableorproperty
Required. Any numeric variable or property.
expression
Required. Any numeric expression.
Remarks
The element on the left side of the /= operator can be a simple scalar variable, a property, or an element of an
array. The variable or property cannot be ReadOnly.
The /= operator first divides the value of the variable or property (on the left-hand side of the operator) by the
value of the expression (on the right-hand side of the operator). The operator then assigns the floating-point result
of that operation to the variable or property.
This statement assigns a Double value to the variable or property on the left. If Option Strict is On ,
variableorproperty must be a Double . If Option Strict is Off , Visual Basic performs an implicit conversion and
assigns the resulting value to variableorproperty , with a possible error at run time. For more information, see
Widening and Narrowing Conversions and Option Strict Statement.
Overloading
The / Operator (Visual Basic) can be overloaded, which means that a class or structure can redefine its behavior
when an operand has the type of that class or structure. Overloading the / operator affects the behavior of the
/= operator. If your code uses /= on a class or structure that overloads / , be sure you understand its redefined
behavior. For more information, see Operator Procedures.
Example
The following example uses the /= operator to divide one Integer variable by a second and assign the quotient
to the first variable.
Syntax
expression1 \ expression2
Parts
expression1
Required. Any numeric expression.
expression2
Required. Any numeric expression.
Supported Types
All numeric types, including the unsigned and floating-point types and Decimal .
Result
The result is the integer quotient of expression1 divided by expression2 , which discards any remainder and
retains only the integer portion. This is known as truncation.
The result data type is a numeric type appropriate for the data types of expression1 and expression2 . See the
"Integer Arithmetic" tables in Data Types of Operator Results.
The / Operator (Visual Basic) returns the full quotient, which retains the remainder in the fractional portion.
Remarks
Before performing the division, Visual Basic attempts to convert any floating-point numeric expression to Long . If
Option Strict is On , a compiler error occurs. If Option Strict is Off , an OverflowException is possible if the
value is outside the range of the Long Data Type. The conversion to Long is also subject to banker's rounding. For
more information, see "Fractional Parts" in Type Conversion Functions.
If expression1 or expression2 evaluates to Nothing, it is treated as zero.
Example
The following example uses the \ operator to perform integer division. The result is an integer that represents
the integer quotient of the two operands, with the remainder discarded.
The expressions in the preceding example return values of 2, 3, 33, and -22, respectively.
See Also
\= Operator
/ Operator (Visual Basic)
Option Strict Statement
Arithmetic Operators
Operator Precedence in Visual Basic
Operators Listed by Functionality
Arithmetic Operators in Visual Basic
\= Operator
7/29/2017 • 1 min to read • Edit Online
Divides the value of a variable or property by the value of an expression and assigns the integer result to the
variable or property.
Syntax
variableorproperty \= expression
Parts
variableorproperty
Required. Any numeric variable or property.
expression
Required. Any numeric expression.
Remarks
The element on the left side of the \= operator can be a simple scalar variable, a property, or an element of an
array. The variable or property cannot be ReadOnly.
The \= operator divides the value of a variable or property on its left by the value on its right, and assigns the
integer result to the variable or property on its left
For further information on integer division, see \ Operator (Visual Basic).
Overloading
The \ operator can be overloaded, which means that a class or structure can redefine its behavior when an
operand has the type of that class or structure. Overloading the \ operator affects the behavior of the \=
operator. If your code uses \= on a class or structure that overloads \ , be sure you understand its redefined
behavior. For more information, see Operator Procedures.
Example
The following example uses the \= operator to divide one Integer variable by a second and assign the integer
result to the first variable.
See Also
\ Operator (Visual Basic)
/= Operator (Visual Basic)
Assignment Operators
Arithmetic Operators
Operator Precedence in Visual Basic
Operators Listed by Functionality
Statements
^ Operator (Visual Basic)
7/29/2017 • 2 min to read • Edit Online
Syntax
number ^ exponent
Parts
number
Required. Any numeric expression.
exponent
Required. Any numeric expression.
Result
The result is number raised to the power of exponent , always as a Double value.
Supported Types
Double . Operands of any different type are converted to Double .
Remarks
Visual Basic always performs exponentiation in the Double Data Type.
The value of exponent can be fractional, negative, or both.
When more than one exponentiation is performed in a single expression, the ^ operator is evaluated as it is
encountered from left to right.
NOTE
The ^ operator can be overloaded, which means that a class or structure can redefine its behavior when an operand has
the type of that class or structure. If your code uses this operator on such a class or structure, be sure you understand its
redefined behavior. For more information, see Operator Procedures.
Example
The following example uses the ^ operator to raise a number to the power of an exponent. The result is the first
operand raised to the power of the second.
Dim exp1, exp2, exp3, exp4, exp5, exp6 As Double
exp1 = 2 ^ 2
exp2 = 3 ^ 3 ^ 3
exp3 = (-5) ^ 3
exp4 = (-5) ^ 4
exp5 = 8 ^ (1.0 / 3.0)
exp6 = 8 ^ (-1.0 / 3.0)
exp4 = -5 ^ 4 would be calculated as –(5 to the fourth power), which would result in -625.
would be calculated as (8 to the –1 power, or 0.125) divided by 3.0, which would result in
exp6 = 8 ^ -1.0 / 3.0
0.041666666666666666666666666666667.
See Also
^= Operator
Arithmetic Operators
Operator Precedence in Visual Basic
Operators Listed by Functionality
Arithmetic Operators in Visual Basic
^= Operator (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
Raises the value of a variable or property to the power of an expression and assigns the result back to the variable
or property.
Syntax
variableorproperty ^= expression
Parts
variableorproperty
Required. Any numeric variable or property.
expression
Required. Any numeric expression.
Remarks
The element on the left side of the ^= operator can be a simple scalar variable, a property, or an element of an
array. The variable or property cannot be ReadOnly.
The ^= operator first raises the value of the variable or property (on the left-hand side of the operator) to the
power of the value of the expression (on the right-hand side of the operator). The operator then assigns the result
of that operation back to the variable or property.
Visual Basic always performs exponentiation in the Double Data Type. Operands of any different type are
converted to Double , and the result is always Double .
The value of expression can be fractional, negative, or both.
Overloading
The ^ Operator can be overloaded, which means that a class or structure can redefine its behavior when an
operand has the type of that class or structure. Overloading the ^ operator affects the behavior of the ^=
operator. If your code uses ^= on a class or structure that overloads ^ , be sure you understand its redefined
behavior. For more information, see Operator Procedures.
Example
The following example uses the ^= operator to raise the value of one Integer variable to the power of a second
variable and assign the result to the first variable.
Syntax
AddressOf procedurename
Parts
procedurename
Required. Specifies the procedure to be referenced by the newly created procedure delegate.
Remarks
The AddressOf operator creates a function delegate that points to the function specified by procedurename . When
the specified procedure is an instance method then the function delegate refers to both the instance and the
method. Then, when the function delegate is invoked the specified method of the specified instance is called.
The AddressOf operator can be used as the operand of a delegate constructor or it can be used in a context in
which the type of the delegate can be determined by the compiler.
Example
This example uses the AddressOf operator to designate a delegate to handle the Click event of a button.
Example
The following example uses the AddressOf operator to designate the startup function for a thread.
Sub UseThread()
Dim t As New System.Threading.Thread(AddressOf CountSheep)
t.Start()
End Sub
See Also
Declare Statement
Function Statement
Sub Statement
Delegates
And Operator (Visual Basic)
7/29/2017 • 2 min to read • Edit Online
Performs a logical conjunction on two Boolean expressions, or a bitwise conjunction on two numeric expressions.
Syntax
result = expression1 And expression2
Parts
result
Required. Any Boolean or numeric expression. For Boolean comparison, result is the logical conjunction of two
Boolean values. For bitwise operations, result is a numeric value representing the bitwise conjunction of two
numeric bit patterns.
expression1
Required. Any Boolean or numeric expression.
expression2
Required. Any Boolean or numeric expression.
Remarks
For Boolean comparison, result is True if and only if both expression1 and expression2 evaluate to True . The
following table illustrates how result is determined.
NOTE
In a Boolean comparison, the And operator always evaluates both expressions, which could include making procedure calls.
The AndAlso Operator performs short-circuiting, which means that if expression1 is False , then expression2 is not
evaluated.
When applied to numeric values, the And operator performs a bitwise comparison of identically positioned bits in
two numeric expressions and sets the corresponding bit in result according to the following table.
IF BIT IN EXPRESSION1 IS AND BIT IN EXPRESSION2 IS THE BIT IN RESULT IS
1 1 1
1 0 0
0 1 0
0 0 0
NOTE
Since the logical and bitwise operators have a lower precedence than other arithmetic and relational operators, any bitwise
operations should be enclosed in parentheses to ensure accurate results.
Data Types
If the operands consist of one Boolean expression and one numeric expression, Visual Basic converts the Boolean
expression to a numeric value (–1 for True and 0 for False ) and performs a bitwise operation.
For a Boolean comparison, the data type of the result is Boolean . For a bitwise comparison, the result data type is
a numeric type appropriate for the data types of expression1 and expression2 . See the "Relational and Bitwise
Comparisons" table in Data Types of Operator Results.
NOTE
The And operator can be overloaded, which means that a class or structure can redefine its behavior when an operand has
the type of that class or structure. If your code uses this operator on such a class or structure, be sure you understand its
redefined behavior. For more information, see Operator Procedures.
Example
The following example uses the And operator to perform a logical conjunction on two expressions. The result is a
Boolean value that represents whether both of the expressions are True .
Dim a As Integer = 10
Dim b As Integer = 8
Dim c As Integer = 6
Dim firstCheck, secondCheck As Boolean
firstCheck = a > b And b > c
secondCheck = b > a And b > c
Example
The following example uses the And operator to perform logical conjunction on the individual bits of two numeric
expressions. The bit in the result pattern is set if the corresponding bits in the operands are both set to 1.
Dim a As Integer = 10
Dim b As Integer = 8
Dim c As Integer = 6
Dim firstPattern, secondPattern, thirdPattern As Integer
firstPattern = (a And b)
secondPattern = (a And c)
thirdPattern = (b And c)
See Also
Logical/Bitwise Operators (Visual Basic)
Operator Precedence in Visual Basic
Operators Listed by Functionality
AndAlso Operator
Logical and Bitwise Operators in Visual Basic
AndAlso Operator (Visual Basic)
7/29/2017 • 2 min to read • Edit Online
Syntax
result = expression1 AndAlso expression2
Parts
TERM DEFINITION
Remarks
A logical operation is said to be short-circuiting if the compiled code can bypass the evaluation of one expression
depending on the result of another expression. If the result of the first expression evaluated determines the final
result of the operation, there is no need to evaluate the second expression, because it cannot change the final
result. Short-circuiting can improve performance if the bypassed expression is complex, or if it involves procedure
calls.
If both expressions evaluate to True , result is True . The following table illustrates how result is determined.
Data Types
The AndAlso operator is defined only for the Boolean Data Type. Visual Basic converts each operand as necessary
to Boolean and performs the operation entirely in Boolean . If you assign the result to a numeric type, Visual Basic
converts it from Boolean to that type. This could produce unexpected behavior. For example, 5 AndAlso 12 results
in –1 when converted to Integer .
Overloading
The And Operator and the IsFalse Operator can be overloaded, which means that a class or structure can redefine
their behavior when an operand has the type of that class or structure. Overloading the And and IsFalse
operators affects the behavior of the AndAlso operator. If your code uses AndAlso on a class or structure that
overloads And and IsFalse , be sure you understand their redefined behavior. For more information, see
Operator Procedures.
Example
The following example uses the AndAlso operator to perform a logical conjunction on two expressions. The result
is a Boolean value that represents whether the entire conjoined expression is true. If the first expression is False ,
the second is not evaluated.
Dim a As Integer = 10
Dim b As Integer = 8
Dim c As Integer = 6
Dim firstCheck, secondCheck, thirdCheck As Boolean
firstCheck = a > b AndAlso b > c
secondCheck = b > a AndAlso b > c
thirdCheck = a > b AndAlso c > b
The preceding example produces results of True , False , and False , respectively. In the calculation of
secondCheck , the second expression is not evaluated because the first is already False . However, the second
expression is evaluated in the calculation of thirdCheck .
Example
The following example shows a Function procedure that searches for a given value among the elements of an
array. If the array is empty, or if the array length has been exceeded, the While statement does not test the array
element against the search value.
See Also
Logical/Bitwise Operators (Visual Basic)
Operator Precedence in Visual Basic
Operators Listed by Functionality
And Operator
IsFalse Operator
Logical and Bitwise Operators in Visual Basic
Await Operator (Visual Basic)
7/29/2017 • 4 min to read • Edit Online
You apply the Await operator to an operand in an asynchronous method or lambda expression to suspend
execution of the method until the awaited task completes. The task represents ongoing work.
The method in which Await is used must have an Async modifier. Such a method, defined by using the Async
modifier, and usually containing one or more Await expressions, is referred to as an async method.
NOTE
The Async and Await keywords were introduced in Visual Studio 2012. For an introduction to async programming, see
Asynchronous Programming with Async and Await.
Typically, the task to which you apply the Await operator is the return value from a call to a method that
implements the Task-Based Asynchronous Pattern, that is, a Task or a Task<TResult>.
In the following code, the HttpClient method GetByteArrayAsync returns getContentsTask , a Task(Of Byte()) .
The task is a promise to produce the actual byte array when the operation is complete. The Await operator is
applied to getContentsTask to suspend execution in SumPageSizesAsync until getContentsTask is complete. In the
meantime, control is returned to the caller of SumPageSizesAsync . When getContentsTask is finished, the Await
expression evaluates to a byte array.
' To use the HttpClient type in desktop apps, you must include a using directive and add a
' reference for the System.Net.Http namespace.
Dim client As HttpClient = New HttpClient()
' . . .
Dim getContentsTask As Task(Of Byte()) = client.GetByteArrayAsync(url)
Dim urlContents As Byte() = Await getContentsTask
' Equivalently, now that you see how it works, you can write the same thing in a single line.
'Dim urlContents As Byte() = Await client.GetByteArrayAsync(url)
' . . .
End Function
IMPORTANT
For the complete example, see Walkthrough: Accessing the Web by Using Async and Await. You can download the sample
from Developer Code Samples on the Microsoft website. The example is in the AsyncWalkthrough_HttpClient project.
If Await is applied to the result of a method call that returns a Task(Of TResult) , the type of the Await
expression is TResult. If Await is applied to the result of a method call that returns a Task , the Await
expression doesn't return a value. The following example illustrates the difference.
Exceptions
Most async methods return a Task or Task<TResult>. The properties of the returned task carry information
about its status and history, such as whether the task is complete, whether the async method caused an
exception or was canceled, and what the final result is. The Await operator accesses those properties.
If you await a task-returning async method that causes an exception, the Await operator rethrows the exception.
If you await a task-returning async method that is canceled, the Await operator rethrows an
OperationCanceledException.
A single task that is in a faulted state can reflect multiple exceptions. For example, the task might be the result of
a call to System.Threading.Tasks.Task.WhenAll. When you await such a task, the await operation rethrows only
one of the exceptions. However, you can't predict which of the exceptions is rethrown.
For examples of error handling in async methods, see Try...Catch...Finally Statement.
Example
The following Windows Forms example illustrates the use of Await in an async method,
WaitAsynchronouslyAsync . Contrast the behavior of that method with the behavior of WaitSynchronously .
Without an Await operator, WaitSynchronously runs synchronously despite the use of the Async modifier in its
definition and a call to System.Threading.Thread.Sleep in its body.
Private Async Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
' Call the method that runs asynchronously.
Dim result As String = Await WaitAsynchronouslyAsync()
' The following method runs synchronously, despite the use of Async.
' You cannot move or resize the Form1 window while Thread.Sleep
' is running because the UI thread is blocked.
Public Async Function WaitSynchronously() As Task(Of String)
' Import System.Threading for the Sleep method.
Thread.Sleep(10000)
Return "Finished"
End Function
See Also
Asynchronous Programming with Async and Await
Walkthrough: Accessing the Web by Using Async and Await
Async
Function Expression (Visual Basic)
7/29/2017 • 2 min to read • Edit Online
Declares the parameters and code that define a function lambda expression.
Syntax
Function ( [ parameterlist ] ) expression
- or -
Function ( [ parameterlist ] )
[ statements ]
End Function
Parts
TERM DEFINITION
Remarks
A lambda expression is a function without a name that calculates and returns a value. You can use a lambda
expression anywhere you can use a delegate type, except as an argument to RemoveHandler . For more information
about delegates, and the use of lambda expressions with delegates, see Delegate Statement and Relaxed Delegate
Conversion.
The body of a single-line lambda expression must be an expression, not a statement. The body can consist of
a call to a function procedure, but not a call to a sub procedure.
Either all parameters must have specified data types or all must be inferred.
Optional and Paramarray parameters are not permitted.
Generic parameters are not permitted.
Example
The following examples show two ways to create simple lambda expressions. The first uses a Dim to provide a
name for the function. To call the function, you send in a value for the parameter.
Example
Alternatively, you can declare and run the function at the same time.
Example
Following is an example of a lambda expression that increments its argument and returns the value. The example
shows both the single-line and multiline lambda expression syntax for a function. For more examples, see Lambda
Expressions.
Example
Lambda expressions underlie many of the query operators in Language-Integrated Query (LINQ), and can be used
explicitly in method-based queries. The following example shows a typical LINQ query, followed by the translation
of the query into method format.
See Also
Function Statement
Lambda Expressions
Operators and Expressions
Statements
Value Comparisons
Boolean Expressions
If Operator
Relaxed Delegate Conversion
GetType Operator (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
Returns a Type object for the specified type. The Type object provides information about the type such as its
properties, methods, and events.
Syntax
GetType(typename)
Parameters
PARAMETER DESCRIPTION
typename The name of the type for which you desire information.
Remarks
The GetType operator returns the Type object for the specified typename . You can pass the name of any defined
type in typename . This includes the following:
Any Visual Basic data type, such as Boolean or Date .
Any .NET Framework class, structure, module, or interface, such as System.ArgumentException or
System.Double.
Any class, structure, module, or interface defined by your application.
Any array defined by your application.
Any delegate defined by your application.
Any enumeration defined by Visual Basic, the .NET Framework, or your application.
If you want to get the type object of an object variable, use the System.Type.GetType method.
The GetType operator can be useful in the following circumstances:
You must access the metadata for a type at run time. The Type object supplies metadata such as type
members and deployment information. You need this, for example, to reflect over an assembly. For more
information, see System.Reflection.
You want to compare two object references to see if they refer to instances of the same type. If they do,
GetType returns references to the same Type object.
Example
The following examples show the GetType operator in use.
' The following statement returns the Type object for Integer.
MsgBox(GetType(Integer).ToString())
' The following statement returns the Type object for one-dimensional string arrays.
MsgBox(GetType(String()).ToString())
See Also
Operator Precedence in Visual Basic
Operators Listed by Functionality
Operators and Expressions
GetXmlNamespace Operator (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
Gets the XNamespace object that corresponds to the specified XML namespace prefix.
Syntax
GetXmlNamespace(xmlNamespacePrefix)
Parts
xmlNamespacePrefix
Optional. The string that identifies the XML namespace prefix. If supplied, this string must be a valid XML identifier.
For more information, see Names of Declared XML Elements and Attributes. If no prefix is specified, the default
namespace is returned. If no default namespace is specified, the empty namespace is returned.
Return Value
The XNamespace object that corresponds to the XML namespace prefix.
Remarks
The GetXmlNamespace operator gets the XNamespace object that corresponds to the XML namespace prefix
xmlNamespacePrefix .
You can use XML namespace prefixes directly in XML literals and XML axis properties. However, you must use the
GetXmlNamespace operator to convert a namespace prefix to an XNamespace object before you can use it in your
code. You can append an unqualified element name to an XNamespace object to get a fully qualified XName object,
which many LINQ to XML methods require.
Example
The following example imports ns as an XML namespace prefix. It then uses the prefix of the namespace to create
an XML literal and access the first child node that has the qualified name ns:phone . It then passes that child node to
the ShowName subroutine, which constructs a qualified name by using the GetXmlNamespace operator. The ShowName
subroutine then passes the qualified name to the Ancestors method to get the parent ns:contact node.
' Place Imports statements at the top of your program.
Imports <xmlns:ns="http://SomeNamespace">
Module GetXmlNamespaceSample
Sub RunSample()
Dim contact =
<ns:contact>
<ns:name>Patrick Hines</ns:name>
<ns:phone ns:type="home">206-555-0144</ns:phone>
<ns:phone ns:type="work">425-555-0145</ns:phone>
</ns:contact>
ShowName(contact.<ns:phone>(0))
End Sub
End Module
When you call TestGetXmlNamespace.RunSample() , it displays a message box that contains the following text:
Name: Patrick Hines
See Also
Imports Statement (XML Namespace)
Accessing XML in Visual Basic
If Operator (Visual Basic)
7/29/2017 • 3 min to read • Edit Online
Uses short-circuit evaluation to conditionally return one of two values. The If operator can be called with three
arguments or with two arguments.
Syntax
If( [argument1,] argument2, argument3 )
Parts
TERM DEFINITION
An If operator that is called with three arguments works like an IIf function except that it uses short-circuit
evaluation. An IIf function always evaluates all three of its arguments, whereas an If operator that has three
arguments evaluates only two of them. The first If argument is evaluated and the result is cast as a Boolean
value, True or False . If the value is True , argument2 is evaluated and its value is returned, but argument3 is not
evaluated. If the value of the Boolean expression is False , argument3 is evaluated and its value is returned, but
argument2 is not evaluated. The following examples illustrate the use of If when three arguments are used:
' This statement prints TruePart, because the first argument is true.
Console.WriteLine(If(True, "TruePart", "FalsePart"))
' This statement prints FalsePart, because the first argument is false.
Console.WriteLine(If(False, "TruePart", "FalsePart"))
Dim number = 3
' With number set to 3, this statement prints Positive.
Console.WriteLine(If(number >= 0, "Positive", "Negative"))
number = -1
' With number set to -1, this statement prints Negative.
Console.WriteLine(If(number >= 0, "Positive", "Negative"))
The following example illustrates the value of short-circuit evaluation. The example shows two attempts to divide
variable number by variable divisor except when divisor is zero. In that case, a 0 should be returned, and no
attempt should be made to perform the division because a run-time error would result. Because the If
expression uses short-circuit evaluation, it evaluates either the second or the third argument, depending on the
value of the first argument. If the first argument is true, the divisor is not zero and it is safe to evaluate the second
argument and perform the division. If the first argument is false, only the third argument is evaluated and a 0 is
returned. Therefore, when the divisor is 0, no attempt is made to perform the division and no error results.
However, because IIf does not use short-circuit evaluation, the second argument is evaluated even when the
first argument is false. This causes a run-time divide-by-zero error.
number = 12
' When the divisor is 0, IIf causes a run-time error, but If does not.
divisor = 0
Console.WriteLine(If(divisor <> 0, number \ divisor, 0))
' Console.WriteLine(IIf(divisor <> 0, number \ divisor, 0))
Parts
TERM DEFINITION
When the Boolean argument is omitted, the first argument must be a reference or nullable type. If the first
argument evaluates to Nothing , the value of the second argument is returned. In all other cases, the value of the
first argument is returned. The following example illustrates how this evaluation works.
' Variable first is a nullable type.
Dim first? As Integer = 3
Dim second As Integer = 6
second = Nothing
' Variable first <> Nothing, so the value of first is returned again.
Console.WriteLine(If(first, second))
first = Nothing
second = 6
' Variable first = Nothing, so 6 is returned.
Console.WriteLine(If(first, second))
See Also
IIf
Nullable Value Types
Nothing
Is Operator (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
Syntax
result = object1 Is object2
Parts
result
Required. Any Boolean value.
object1
Required. Any Object name.
object2
Required. Any Object name.
Remarks
The Is operator determines if two object references refer to the same object. However, it does not perform value
comparisons. If object1 and object2 both refer to the exact same object instance, result is True ; if they do
not, result is False .
Is can also be used with the TypeOf keyword to make a TypeOf ... Is expression, which tests whether an object
variable is compatible with a data type.
NOTE
The Is keyword is also used in the Select...Case Statement.
Example
The following example uses the Is operator to compare pairs of object references. The results are assigned to a
Boolean value representing whether the two objects are identical.
Dim myObject As New Object
Dim otherObject As New Object
Dim yourObject, thisObject, thatObject As Object
Dim myCheck As Boolean
yourObject = myObject
thisObject = myObject
thatObject = otherObject
' The following statement sets myCheck to True.
myCheck = yourObject Is thisObject
' The following statement sets myCheck to False.
myCheck = thatObject Is thisObject
' The following statement sets myCheck to False.
myCheck = myObject Is thatObject
thatObject = myObject
' The following statement sets myCheck to True.
myCheck = thisObject Is thatObject
As the preceding example demonstrates, you can use the Is operator to test both early bound and late bound
objects.
See Also
TypeOf Operator
IsNot Operator
Comparison Operators in Visual Basic
Operator Precedence in Visual Basic
Operators Listed by Functionality
Operators and Expressions
IsFalse Operator (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
NOTE
The IsFalse operator can be overloaded, which means that a class or structure can redefine its behavior when its operand
has the type of that class or structure. If your code uses this operator on such a class or structure, be sure you understand
its redefined behavior. For more information, see Operator Procedures.
Example
The following code example defines the outline of a structure that includes definitions for the IsFalse and
IsTrue operators.
Public Structure p
Dim a As Double
Public Shared Operator IsFalse(ByVal w As p) As Boolean
Dim b As Boolean
' Insert code to calculate IsFalse of w.
Return b
End Operator
Public Shared Operator IsTrue(ByVal w As p) As Boolean
Dim b As Boolean
' Insert code to calculate IsTrue of w.
Return b
End Operator
End Structure
See Also
IsTrue Operator
How to: Define an Operator
AndAlso Operator
IsNot Operator (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
Syntax
result = object1 IsNot object2
Parts
result
Required. A Boolean value.
object1
Required. Any Object variable or expression.
object2
Required. Any Object variable or expression.
Remarks
The IsNot operator determines if two object references refer to different objects. However, it does not perform
value comparisons. If object1 and object2 both refer to the exact same object instance, result is False ; if they
do not, result is True .
IsNot is the opposite of the Is operator. The advantage of IsNot is that you can avoid awkward syntax with
Not and Is , which can be difficult to read.
You can use the Is and IsNot operators to test both early-bound and late-bound objects.
NOTE
The IsNot operator cannot be used to compare expressions returned from the TypeOf operator. Instead, you must use
the Not and Is operators.
Example
The following code example uses both the Is operator and the IsNot operator to accomplish the same
comparison.
See Also
Is Operator
TypeOf Operator
Operator Precedence in Visual Basic
How to: Test Whether Two Objects Are the Same
IsTrue Operator (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
NOTE
The IsTrue operator can be overloaded, which means that a class or structure can redefine its behavior when its operand
has the type of that class or structure. If your code uses this operator on such a class or structure, be sure you understand
its redefined behavior. For more information, see Operator Procedures.
Example
The following code example defines the outline of a structure that includes definitions for the IsFalse and
IsTrue operators.
Public Structure p
Dim a As Double
Public Shared Operator IsFalse(ByVal w As p) As Boolean
Dim b As Boolean
' Insert code to calculate IsFalse of w.
Return b
End Operator
Public Shared Operator IsTrue(ByVal w As p) As Boolean
Dim b As Boolean
' Insert code to calculate IsTrue of w.
Return b
End Operator
End Structure
See Also
IsFalse Operator
How to: Define an Operator
OrElse Operator
Like Operator (Visual Basic)
7/29/2017 • 5 min to read • Edit Online
Syntax
result = string Like pattern
Parts
result
Required. Any Boolean variable. The result is a Boolean value indicating whether or not the string satisfies the
pattern .
string
Required. Any String expression.
pattern
Required. Any String expression conforming to the pattern-matching conventions described in "Remarks."
Remarks
If the value in string satisfies the pattern contained in pattern , result is True . If the string does not satisfy the
pattern, result is False . If both string and pattern are empty strings, the result is True .
Comparison Method
The behavior of the Like operator depends on the Option Compare Statement. The default string comparison
method for each source file is Option Compare Binary .
Pattern Options
Built-in pattern matching provides a versatile tool for string comparisons. The pattern-matching features allow you
to match each character in string against a specific character, a wildcard character, a character list, or a character
range. The following table shows the characters allowed in pattern and what they match.
Special Characters
To match the special characters left bracket ( [ ), question mark ( ? ), number sign ( # ), and asterisk ( * ), enclose
them in brackets. The right bracket ( ] ) cannot be used within a group to match itself, but it can be used outside a
group as an individual character.
The character sequence [] is considered a zero-length string ( "" ). However, it cannot be part of a character list
enclosed in brackets. If you want to check whether a position in string contains one of a group of characters or
no character at all, you can use Like twice. For an example, see How to: Match a String against a Pattern.
Character Ranges
By using a hyphen ( – ) to separate the lower and upper bounds of the range, charlist can specify a range of
characters. For example, [A–Z] results in a match if the corresponding character position in string contains any
character within the range A – Z , and [!H–L] results in a match if the corresponding character position contains
any character outside the range H – L .
When you specify a range of characters, they must appear in ascending sort order, that is, from lowest to highest.
Thus, [A–Z] is a valid pattern, but [Z–A] is not.
Multiple Character Ranges
To specify multiple ranges for the same character position, put them within the same brackets without delimiters.
For example, [A–CX–Z] results in a match if the corresponding character position in string contains any
character within either the range A – C or the range X – Z .
Usage of the Hyphen
A hyphen ( – ) can appear either at the beginning (after an exclamation point, if any) or at the end of charlist to
match itself. In any other location, the hyphen identifies a range of characters delimited by the characters on either
side of the hyphen.
Collating Sequence
The meaning of a specified range depends on the character ordering at run time, as determined by
Option``Compare and the locale setting of the system the code is running on. With Option``Compare``Binary , the
range [A–E] matches A , B , C , D , and E . With Option``Compare``Text , [A–E] matches A , a , À , à , B , b ,
C , c , D , d , E , and e . The range does not match Ê or ê because accented characters collate after
unaccented characters in the sort order.
Digraph Characters
In some languages, there are alphabetic characters that represent two separate characters. For example, several
languages use the character æ to represent the characters a and e when they appear together. The Like
operator recognizes that the single digraph character and the two individual characters are equivalent.
When a language that uses a digraph character is specified in the system locale settings, an occurrence of the
single digraph character in either pattern or string matches the equivalent two-character sequence in the other
string. Similarly, a digraph character in pattern enclosed in brackets (by itself, in a list, or in a range) matches the
equivalent two-character sequence in string .
Overloading
The Like operator can be overloaded, which means that a class or structure can redefine its behavior when an
operand has the type of that class or structure. If your code uses this operator on such a class or structure, be sure
you understand its redefined behavior. For more information, see Operator Procedures.
Example
This example uses the Like operator to compare strings to various patterns. The results go into a Boolean
variable indicating whether each string satisfies the pattern.
See Also
InStr
StrComp
Comparison Operators
Operator Precedence in Visual Basic
Operators Listed by Functionality
Option Compare Statement
Operators and Expressions
How to: Match a String against a Pattern
Mod Operator (Visual Basic)
7/29/2017 • 2 min to read • Edit Online
Syntax
number1 Mod number2
Parts
number1
Required. Any numeric expression.
number2
Required. Any numeric expression.
Supported Types
All numeric types. This includes the unsigned and floating-point types and Decimal .
Result
The result is the remainder after number1 is divided by number2 . For example, the expression 14 Mod 4 evaluates
to 2.
Remarks
If either number1 or number2 is a floating-point value, the floating-point remainder of the division is returned. The
data type of the result is the smallest data type that can hold all possible values that result from division with the
data types of number1 and number2 .
If number1 or number2 evaluates to Nothing, it is treated as zero.
Related operators include the following:
The \ Operator (Visual Basic) returns the integer quotient of a division. For example, the expression 14 \ 4
evaluates to 3.
The / Operator (Visual Basic) returns the full quotient, including the remainder, as a floating-point number.
For example, the expression 14 / 4 evaluates to 3.5.
Equivalent Formula
The expression a Mod b is equivalent to either of the following formulas:
a - (b * (a \ b))
a - (b * Fix(a / b))
Floating-Point Imprecision
When you work with floating-point numbers, remember that they do not always have a precise representation in
memory. This could lead to unexpected results from certain operations, such as value comparison and the Mod
operator. For more information, see Troubleshooting Data Types.
Overloading
The Mod operator can be overloaded, which means that a class or structure can redefine its behavior. If your code
applies Mod to an instance of a class or structure that includes such an overload, be sure you understand its
redefined behavior. For more information, see Operator Procedures.
Example
The following example uses the Mod operator to divide two numbers and return only the remainder. If either
number is a floating-point number, the result is a floating-point number that represents the remainder.
Debug.WriteLine(10 Mod 5)
' Output: 0
Debug.WriteLine(10 Mod 3)
' Output: 1
Debug.WriteLine(-10 Mod 3)
' Output: -1
Debug.WriteLine(12 Mod 4.3)
' Output: 3.4
Debug.WriteLine(12.6 Mod 5)
' Output: 2.6
Debug.WriteLine(47.9 Mod 9.35)
' Output: 1.15
Example
The following example demonstrates the potential imprecision of floating-point operands. In the first statement,
the operands are Double , and 0.2 is an infinitely repeating binary fraction with a stored value of
0.20000000000000001. In the second statement, the literal type character D forces both operands to Decimal ,
and 0.2 has a precise representation.
See Also
Int
Fix
Arithmetic Operators
Operator Precedence in Visual Basic
Operators Listed by Functionality
Troubleshooting Data Types
Arithmetic Operators in Visual Basic
\ Operator (Visual Basic)
Not Operator (Visual Basic)
7/29/2017 • 2 min to read • Edit Online
Syntax
result = Not expression
Parts
result
Required. Any Boolean or numeric expression.
expression
Required. Any Boolean or numeric expression.
Remarks
For Boolean expressions, the following table illustrates how result is determined.
True False
False True
For numeric expressions, the Not operator inverts the bit values of any numeric expression and sets the
corresponding bit in result according to the following table.
1 0
0 1
NOTE
Since the logical and bitwise operators have a lower precedence than other arithmetic and relational operators, any bitwise
operations should be enclosed in parentheses to ensure accurate execution.
Data Types
For a Boolean negation, the data type of the result is Boolean . For a bitwise negation, the result data type is the
same as that of expression . However, if expression is Decimal , the result is Long .
Overloading
The Not operator can be overloaded, which means that a class or structure can redefine its behavior when its
operand has the type of that class or structure. If your code uses this operator on such a class or structure, be sure
you understand its redefined behavior. For more information, see Operator Procedures.
Example
The following example uses the Not operator to perform logical negation on a Boolean expression. The result is a
Boolean value that represents the reverse of the value of the expression.
Dim a As Integer = 10
Dim b As Integer = 8
Dim c As Integer = 6
Dim firstCheck, secondCheck As Boolean
firstCheck = Not (a > b)
secondCheck = Not (b > a)
Example
The following example uses the Not operator to perform logical negation of the individual bits of a numeric
expression. The bit in the result pattern is set to the reverse of the corresponding bit in the operand pattern,
including the sign bit.
Dim a As Integer = 10
Dim b As Integer = 8
Dim c As Integer = 6
Dim firstPattern, secondPattern, thirdPattern As Integer
firstPattern = (Not a)
secondPattern = (Not b)
thirdPattern = (Not c)
The preceding example produces results of –11, –9, and –7, respectively.
See Also
Logical/Bitwise Operators (Visual Basic)
Operator Precedence in Visual Basic
Operators Listed by Functionality
Logical and Bitwise Operators in Visual Basic
Or Operator (Visual Basic)
7/29/2017 • 2 min to read • Edit Online
Performs a logical disjunction on two Boolean expressions, or a bitwise disjunction on two numeric expressions.
Syntax
result = expression1 Or expression2
Parts
result
Required. Any Boolean or numeric expression. For Boolean comparison, result is the inclusive logical
disjunction of two Boolean values. For bitwise operations, result is a numeric value representing the inclusive
bitwise disjunction of two numeric bit patterns.
expression1
Required. Any Boolean or numeric expression.
expression2
Required. Any Boolean or numeric expression.
Remarks
For Boolean comparison, result is False if and only if both expression1 and expression2 evaluate to False .
The following table illustrates how result is determined.
NOTE
In a Boolean comparison, the Or operator always evaluates both expressions, which could include making procedure calls.
The OrElse Operator performs short-circuiting, which means that if expression1 is True , then expression2 is not
evaluated.
For bitwise operations, the Or operator performs a bitwise comparison of identically positioned bits in two
numeric expressions and sets the corresponding bit in result according to the following table.
IF BIT IN EXPRESSION1 IS AND BIT IN EXPRESSION2 IS THE BIT IN RESULT IS
1 1 1
1 0 1
0 1 1
0 0 0
NOTE
Since the logical and bitwise operators have a lower precedence than other arithmetic and relational operators, any bitwise
operations should be enclosed in parentheses to ensure accurate execution.
Data Types
If the operands consist of one Boolean expression and one numeric expression, Visual Basic converts the Boolean
expression to a numeric value (–1 for True and 0 for False ) and performs a bitwise operation.
For a Boolean comparison, the data type of the result is Boolean . For a bitwise comparison, the result data type is
a numeric type appropriate for the data types of expression1 and expression2 . See the "Relational and Bitwise
Comparisons" table in Data Types of Operator Results.
Overloading
The Or operator can be overloaded, which means that a class or structure can redefine its behavior when an
operand has the type of that class or structure. If your code uses this operator on such a class or structure, be sure
you understand its redefined behavior. For more information, see Operator Procedures.
Example
The following example uses the Or operator to perform an inclusive logical disjunction on two expressions. The
result is a Boolean value that represents whether either of the two expressions is True .
Dim a As Integer = 10
Dim b As Integer = 8
Dim c As Integer = 6
Dim firstCheck, secondCheck, thirdCheck As Boolean
firstCheck = a > b Or b > c
secondCheck = b > a Or b > c
thirdCheck = b > a Or c > b
The preceding example produces results of True , True , and False , respectively.
Example
The following example uses the Or operator to perform inclusive logical disjunction on the individual bits of two
numeric expressions. The bit in the result pattern is set if either of the corresponding bits in the operands is set to
1.
Dim a As Integer = 10
Dim b As Integer = 8
Dim c As Integer = 6
Dim firstPattern, secondPattern, thirdPattern As Integer
firstPattern = (a Or b)
secondPattern = (a Or c)
thirdPattern = (b Or c)
The preceding example produces results of 10, 14, and 14, respectively.
See Also
Logical/Bitwise Operators (Visual Basic)
Operator Precedence in Visual Basic
Operators Listed by Functionality
OrElse Operator
Logical and Bitwise Operators in Visual Basic
OrElse Operator (Visual Basic)
7/29/2017 • 2 min to read • Edit Online
Syntax
result = expression1 OrElse expression2
Parts
result
Required. Any Boolean expression.
expression1
Required. Any Boolean expression.
expression2
Required. Any Boolean expression.
Remarks
A logical operation is said to be short-circuiting if the compiled code can bypass the evaluation of one expression
depending on the result of another expression. If the result of the first expression evaluated determines the final
result of the operation, there is no need to evaluate the second expression, because it cannot change the final
result. Short-circuiting can improve performance if the bypassed expression is complex, or if it involves procedure
calls.
If either or both expressions evaluate to True , result is True . The following table illustrates how result is
determined.
Data Types
The OrElse operator is defined only for the Boolean Data Type. Visual Basic converts each operand as necessary
to Boolean and performs the operation entirely in Boolean . If you assign the result to a numeric type, Visual Basic
converts it from Boolean to that type. This could produce unexpected behavior. For example, 5 OrElse 12 results
in –1 when converted to Integer .
Overloading
The Or Operator and the IsTrue Operator can be overloaded, which means that a class or structure can redefine
their behavior when an operand has the type of that class or structure. Overloading the Or and IsTrue
operators affects the behavior of the OrElse operator. If your code uses OrElse on a class or structure that
overloads Or and IsTrue , be sure you understand their redefined behavior. For more information, see Operator
Procedures.
Example
The following example uses the OrElse operator to perform logical disjunction on two expressions. The result is a
Boolean value that represents whether either of the two expressions is true. If the first expression is True , the
second is not evaluated.
Dim a As Integer = 10
Dim b As Integer = 8
Dim c As Integer = 6
Dim firstCheck, secondCheck, thirdCheck As Boolean
firstCheck = a > b OrElse b > c
secondCheck = b > a OrElse b > c
thirdCheck = b > a OrElse c > b
The preceding example produces results of True , True , and False respectively. In the calculation of firstCheck ,
the second expression is not evaluated because the first is already True . However, the second expression is
evaluated in the calculation of secondCheck .
Example
The following example shows an If ... Then statement containing two procedure calls. If the first call returns
True , the second procedure is not called. This could produce unexpected results if the second procedure
performs important tasks that should always be performed when this section of the code runs.
See Also
Logical/Bitwise Operators (Visual Basic)
Operator Precedence in Visual Basic
Operators Listed by Functionality
Or Operator
IsTrue Operator
Logical and Bitwise Operators in Visual Basic
Sub Expression (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
Declares the parameters and code that define a subroutine lambda expression.
Syntax
Sub ( [ parameterlist ] ) statement
- or -
Sub ( [ parameterlist ] )
[ statements ]
End Sub
Parts
TERM DEFINITION
Remarks
A lambda expression is a subroutine that does not have a name and that executes one or more statements. You can
use a lambda expression anywhere that you can use a delegate type, except as an argument to RemoveHandler . For
more information about delegates, and the use of lambda expressions with delegates, see Delegate Statement and
Relaxed Delegate Conversion.
See Also
Sub Statement
Lambda Expressions
Operators and Expressions
Statements
Relaxed Delegate Conversion
TypeOf Operator (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
Syntax
result = TypeOf objectexpression Is typename
Parts
result
Returned. A Boolean value.
objectexpression
Required. Any expression that evaluates to a reference type.
typename
Required. Any data type name.
Remarks
The TypeOf operator determines whether the run-time type of objectexpression is compatible with typename .
The compatibility depends on the type category of typename . The following table shows how compatibility is
determined.
If the run-time type of objectexpression satisfies the compatibility criterion, result is True . Otherwise, result
is False . If objectexpression is null, then TypeOf ... Is returns False , and ... IsNot returns True .
TypeOf is always used with the Is keyword to construct a TypeOf ... Is expression, or with the IsNot keyword
to construct a TypeOf ... IsNot expression.
Example
The following example uses TypeOf ... Is expressions to test the type compatibility of two object reference
variables with various data types.
Dim refInteger As Object = 2
MsgBox("TypeOf Object[Integer] Is Integer? " & TypeOf refInteger Is Integer)
MsgBox("TypeOf Object[Integer] Is Double? " & TypeOf refInteger Is Double)
Dim refForm As Object = New System.Windows.Forms.Form
MsgBox("TypeOf Object[Form] Is Form? " & TypeOf refForm Is System.Windows.Forms.Form)
MsgBox("TypeOf Object[Form] Is Label? " & TypeOf refForm Is System.Windows.Forms.Label)
MsgBox("TypeOf Object[Form] Is Control? " & TypeOf refForm Is System.Windows.Forms.Control)
MsgBox("TypeOf Object[Form] Is IComponent? " & TypeOf refForm Is System.ComponentModel.IComponent)
The variable refInteger has a run-time type of Integer . It is compatible with Integer but not with Double . The
variable refForm has a run-time type of Form. It is compatible with Form because that is its type, with Control
because Form inherits from Control, and with IComponent because Form inherits from Component, which
implements IComponent. However, refForm is not compatible with Label.
See Also
Is Operator
IsNot Operator
Comparison Operators in Visual Basic
Operator Precedence in Visual Basic
Operators Listed by Functionality
Operators and Expressions
Xor Operator (Visual Basic)
7/29/2017 • 3 min to read • Edit Online
Performs a logical exclusion on two Boolean expressions, or a bitwise exclusion on two numeric expressions.
Syntax
result = expression1 Xor expression2
Parts
result
Required. Any Boolean or numeric variable. For Boolean comparison, result is the logical exclusion (exclusive
logical disjunction) of two Boolean values. For bitwise operations, result is a numeric value that represents the
bitwise exclusion (exclusive bitwise disjunction) of two numeric bit patterns.
expression1
Required. Any Boolean or numeric expression.
expression2
Required. Any Boolean or numeric expression.
Remarks
For Boolean comparison, result is True if and only if exactly one of expression1 and expression2 evaluates to
True . That is, if and only if expression1 and expression2 evaluate to opposite Boolean values. The following
table illustrates how result is determined.
NOTE
In a Boolean comparison, the Xor operator always evaluates both expressions, which could include making procedure calls.
There is no short-circuiting counterpart to Xor , because the result always depends on both operands. For short-circuiting
logical operators, see AndAlso Operator and OrElse Operator.
For bitwise operations, the Xor operator performs a bitwise comparison of identically positioned bits in two
numeric expressions and sets the corresponding bit in result according to the following table.
IF BIT IN EXPRESSION1 IS AND BIT IN EXPRESSION2 IS THE BIT IN RESULT IS
1 1 0
1 0 1
0 1 1
0 0 0
NOTE
Since the logical and bitwise operators have a lower precedence than other arithmetic and relational operators, any bitwise
operations should be enclosed in parentheses to ensure accurate execution.
For example, 5 Xor 3 is 6. To see why this is so, convert 5 and 3 to their binary representations, 101 and 011. Then
use the previous table to determine that 101 Xor 011 is 110, which is the binary representation of the decimal
number 6.
Data Types
If the operands consist of one Boolean expression and one numeric expression, Visual Basic converts the Boolean
expression to a numeric value (–1 for True and 0 for False ) and performs a bitwise operation.
For a Boolean comparison, the data type of the result is Boolean . For a bitwise comparison, the result data type is
a numeric type appropriate for the data types of expression1 and expression2 . See the "Relational and Bitwise
Comparisons" table in Data Types of Operator Results.
Overloading
The Xor operator can be overloaded, which means that a class or structure can redefine its behavior when an
operand has the type of that class or structure. If your code uses this operator on such a class or structure, make
sure you understand its redefined behavior. For more information, see Operator Procedures.
Example
The following example uses the Xor operator to perform logical exclusion (exclusive logical disjunction) on two
expressions. The result is a Boolean value that represents whether exactly one of the expressions is True .
Dim a As Integer = 10
Dim b As Integer = 8
Dim c As Integer = 6
Dim firstCheck, secondCheck, thirdCheck As Boolean
firstCheck = a > b Xor b > c
secondCheck = b > a Xor b > c
thirdCheck = b > a Xor c > b
The previous example produces results of False , True , and False , respectively.
Example
The following example uses the Xor operator to perform logical exclusion (exclusive logical disjunction) on the
individual bits of two numeric expressions. The bit in the result pattern is set if exactly one of the corresponding
bits in the operands is set to 1.
See Also
Logical/Bitwise Operators (Visual Basic)
Operator Precedence in Visual Basic
Operators Listed by Functionality
Logical and Bitwise Operators in Visual Basic
Data Types of Operator Results (Visual Basic)
7/29/2017 • 7 min to read • Edit Online
Visual Basic determines the result data type of an operation based on the data types of the operands. In some
cases this might be a data type with a greater range than that of either operand.
Decimal Arithmetic
Note that the Decimal data type is neither floating-point nor integer.
If either operand of a + , – , * , / , or Mod operation is Decimal and the other is not Single or Double , Visual
Basic widens the other operand to Decimal . It performs the operation in Decimal , and the result data type is
Decimal .
Floating-Point Arithmetic
Visual Basic performs most floating-point arithmetic in Double, which is the most efficient data type for such
operations. However, if one operand is Single and the other is not Double , Visual Basic performs the operation in
Single . It widens each operand as necessary to the appropriate data type before the operation, and the result
has that data type.
/ and ^ Operators
The / operator is defined only for the Decimal, Single, and Double data types. Visual Basic widens each operand
as necessary to the appropriate data type before the operation, and the result has that data type.
The following table shows the result data types for the / operator. Note that this table is symmetric; for a given
combination of operand data types, the result data type is the same regardless of the order of the operands.
Decimal Single Double Any integer type
The operator is defined only for the Double data type. Visual Basic widens each operand as necessary to
^
Double before the operation, and the result data type is always Double .
Integer Arithmetic
The result data type of an integer operation depends on the data types of the operands. In general, Visual Basic
uses the following policies for determining the result data type:
If both operands of a binary operator have the same data type, the result has that data type. An exception
is Boolean , which is forced to Short .
If an unsigned operand participates with a signed operand, the result has a signed type with at least as
large a range as either operand.
Otherwise, the result usually has the larger of the two operand data types.
Note that the result data type might not be the same as either operand data type.
NOTE
The result data type is not always large enough to hold all possible values resulting from the operation. An
OverflowException exception can occur if the value is too large for the result data type.
Unary Short SByte Byte Short UShort Integer UIntege Long ULong
+ r
Unary Short SByte Short Short Integer Integer Long Long Decimal
–
If the left operand is Decimal , Single , Double , or String , Visual Basic attempts to convert it to Long before the
operation, and the result data type is Long . The right operand (the number of bit positions to shift) must be
Integer or a type that widens to Integer .
Boolean Short SByte Short Short Integer Integer Long Long Decimal
SByte SByte SByte Short Short Integer Integer Long Long Decimal
Byte Short Short Byte Short UShort Integer UIntege Long ULong
r
Short Short Short Short Short Integer Integer Long Long Decimal
UShort Integer Integer UShort Integer UShort Integer UIntege Long ULong
r
Integer Integer Integer Integer Integer Integer Integer Long Long Decimal
UInteger Long Long UIntege Long UIntege Long UIntege Long ULong
r r r
Long Long Long Long Long Long Long Long Long Decimal
ULong Decimal Decimal ULong Decimal ULong Decimal ULong Decimal ULong
\ Operator
The following table shows the result data types for the \ operator. Note that this table is symmetric; for a given
combination of operand data types, the result data type is the same regardless of the order of the operands.
Boolean Short SByte Short Short Integer Integer Long Long Long
SByte SByte SByte Short Short Integer Integer Long Long Long
Byte Short Short Byte Short UShort Integer UIntege Long ULong
r
Short Short Short Short Short Integer Integer Long Long Long
UShort Integer Integer UShort Integer UShort Integer UIntege Long ULong
r
Integer Integer Integer Integer Integer Integer Integer Long Long Long
UInteger Long Long UIntege Long UIntege Long UIntege Long ULong
r r r
Long Long Long Long Long Long Long Long Long Long
ULong Long Long ULong Long ULong Long ULong Long ULong
If either operand of the \ operator is Decimal, Single, or Double, Visual Basic attempts to convert it to Long
before the operation, and the result data type is Long .
The result data type of a bitwise logical operation depends on the data types of the operands. Note that AndAlso
and OrElse are defined only for Boolean , and Visual Basic converts each operand as necessary to Boolean
before performing the operation.
=, <>, <, >, <=, and >= Operators
If both operands are Boolean , Visual Basic considers True to be less than False . If a numeric type is compared
with a String , Visual Basic attempts to convert the String to Double before the operation. A Char or Date
operand can be compared only with another operand of the same data type. The result data type is always
Boolean .
Not Boolean SByte Byte Short UShort Integer UIntege Long ULong
r
If the operand is Decimal , Single , Double , or String , Visual Basic attempts to convert it to Long before the
operation, and the result data type is Long .
Bitwise And, Or, and Xor Operators
The following table shows the result data types for the bitwise And , Or , and Xor operators. Note that this table
is symmetric; for a given combination of operand data types, the result data type is the same regardless of the
order of the operands.
SByte SByte SByte Short Short Integer Integer Long Long Long
Byte Short Short Byte Short UShort Integer UIntege Long ULong
r
Short Short Short Short Short Integer Integer Long Long Long
UShort Integer Integer UShort Integer UShort Integer UIntege Long ULong
r
Integer Integer Integer Integer Integer Integer Integer Long Long Long
UInteger Long Long UIntege Long UIntege Long UIntege Long ULong
r r r
Long Long Long Long Long Long Long Long Long Long
ULong Long Long ULong Long ULong Long ULong Long ULong
If an operand is Decimal , Single , Double , or String , Visual Basic attempts to convert it to Long before the
operation, and the result data type is the same as if that operand had already been Long .
Miscellaneous Operators
The & operator is defined only for concatenation of String operands. Visual Basic converts each operand as
necessary to String before the operation, and the result data type is always String . For the purposes of the &
operator, all conversions to String are considered to be widening, even if Option Strict is On .
The Is and IsNot operators require both operands to be of a reference type. The TypeOf ... Is expression
requires the first operand to be of a reference type and the second operand to be the name of a data type. In all
these cases the result data type is Boolean .
The Like operator is defined only for pattern matching of String operands. Visual Basic attempts to convert
each operand as necessary to String before the operation. The result data type is always Boolean .
See Also
Data Types
Operators and Expressions
Arithmetic Operators in Visual Basic
Comparison Operators in Visual Basic
Operators
Operator Precedence in Visual Basic
Operators Listed by Functionality
Arithmetic Operators
Comparison Operators
Option Strict Statement
DirectCast Operator (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
Remarks
DirectCast does not use the Visual Basic run-time helper routines for conversion, so it can provide somewhat
better performance than CType when converting to and from data type Object .
You use the DirectCast keyword similar to the way you use the CType Function and the TryCast Operator
keyword. You supply an expression as the first argument and a type to convert it to as the second argument.
DirectCast requires an inheritance or implementation relationship between the data types of the two arguments.
This means that one type must inherit from or implement the other.
Conversion Keywords
A comparison of the type conversion keywords is as follows.
DirectCast Any data types One type must inherit from Throws InvalidCastException
or implement the other type
TryCast Operator Reference types only One type must inherit from Returns Nothing
or implement the other type
Example
The following example demonstrates two uses of DirectCast , one that fails at run time and one that succeeds.
In the preceding example, the run-time type of q is Double . CType succeeds because Double can be converted
to Integer . However, the first DirectCast fails at run time because the run-time type of Double has no
inheritance relationship with Integer , even though a conversion exists. The second DirectCast succeeds because
it converts from type Form to type Control, from which Form inherits.
See Also
System.Convert.ChangeType
Widening and Narrowing Conversions
Implicit and Explicit Conversions
TryCast Operator (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
Remarks
If an attempted conversion fails, CType and DirectCast both throw an InvalidCastException error. This can
adversely affect the performance of your application. TryCast returns Nothing, so that instead of having to
handle a possible exception, you need only test the returned result against Nothing .
You use the TryCast keyword the same way you use the CType Function and the DirectCast Operator keyword.
You supply an expression as the first argument and a type to convert it to as the second argument. TryCast
operates only on reference types, such as classes and interfaces. It requires an inheritance or implementation
relationship between the two types. This means that one type must inherit from or implement the other.
Conversion Keywords
A comparison of the type conversion keywords is as follows.
DirectCast Operator Any data types One type must inherit from Throws InvalidCastException
or implement the other type
TryCast Reference types only One type must inherit from Returns Nothing
or implement the other type
Example
The following example shows how to use TryCast .
Introduces a New clause to create a new object instance, specifies a constructor constraint on a type parameter,
or identifies a Sub procedure as a class constructor.
Remarks
In a declaration or assignment statement, a New clause must specify a defined class from which the instance can
be created. This means that the class must expose one or more constructors that the calling code can access.
You can use a New clause in a declaration statement or an assignment statement. When the statement runs, it
calls the appropriate constructor of the specified class, passing any arguments you have supplied. The following
example demonstrates this by creating instances of a Customer class that has two constructors, one that takes no
parameters and one that takes a string parameter.
' For customer2, call the constructor that takes the name of the
' customer as an argument.
Dim customer2 As New Customer("Blue Yonder Airlines")
' With Option Infer set to On, the following declaration declares
' and instantiates a new instance of Customer.
Dim customer4 = New Customer("Coho Winery")
Since arrays are classes, New can create a new array instance, as shown in the following examples.
' The following example requires that Option Infer be set to On.
Dim intArray3() = New Integer() {6, 7, 8}
The common language runtime (CLR) throws an OutOfMemoryException error if there is insufficient memory to
create the new instance.
NOTE
The New keyword is also used in type parameter lists to specify that the supplied type must expose an accessible
parameterless constructor. For more information about type parameters and constraints, see Type List.
To create a constructor procedure for a class, set the name of a Sub procedure to the New keyword. For more
information, see Object Lifetime: How Objects Are Created and Destroyed.
The New keyword can be used in these contexts:
Dim Statement
Of
Sub Statement
See Also
OutOfMemoryException
Keywords
Type List
Generic Types in Visual Basic
Object Lifetime: How Objects Are Created and Destroyed
Arithmetic Operators (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
See Also
Operator Precedence in Visual Basic
Arithmetic Operators in Visual Basic
Assignment Operators (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
See Also
Operator Precedence in Visual Basic
Operators Listed by Functionality
Statements
Bit Shift Operators (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
The following are the bit shift operators defined in Visual Basic.
<< Operator
>> Operator
See Also
Operators Listed by Functionality
Comparison Operators (Visual Basic)
7/29/2017 • 5 min to read • Edit Online
Syntax
result = expression1 comparisonoperator expression2
result = object1 [Is | IsNot] object2
result = string Like pattern
Parts
result
Required. A Boolean value representing the result of the comparison.
expression
Required. Any expression.
comparisonoperator
Required. Any relational comparison operator.
object1 , object2
Required. Any reference object names.
string
Required. Any String expression.
pattern
Required. Any String expression or range of characters.
Remarks
The following table contains a list of the relational comparison operators and the conditions that determine
whether result is True or False .
<= (Less than or equal to) expression1 <= expression2 expression1 > expression2
>= (Greater than or equal to) expression1 >= expression2 expression1 < expression2
NOTE
The = Operator is also used as an assignment operator.
The Is operator, the IsNot operator, and the Like operator have specific comparison functionalities that
differ from the operators in the preceding table.
Comparing Numbers
When you compare an expression of type Single to one of type Double , the Single expression is converted to
Double . This behavior is opposite to the behavior found in Visual Basic 6.
Similarly, when you compare an expression of type Decimal to an expression of type Single or Double , the
Decimal expression is converted to Single or Double . For Decimal expressions, any fractional value less than
1E-28 might be lost. Such fractional value loss may cause two values to compare as equal when they are not.
For this reason, you should take care when using equality ( = ) to compare two floating-point variables. It is
safer to test whether the absolute value of the difference between the two numbers is less than a small
acceptable tolerance.
Floating-point Imprecision
When you work with floating-point numbers, keep in mind that they do not always have a precise
representation in memory. This could lead to unexpected results from certain operations, such as value
comparison and the Mod Operator. For more information, see Troubleshooting Data Types.
Comparing Strings
When you compare strings, the string expressions are evaluated based on their alphabetical sort order, which
depends on the Option Compare setting.
Option Compare Binary bases string comparisons on a sort order derived from the internal binary
representations of the characters. The sort order is determined by the code page. The following example shows
a typical binary sort order.
A < B < E < Z < a < b < e < z < À < Ê < Ø < à < ê < ø
Option Compare Text bases string comparisons on a case-insensitive, textual sort order determined by your
application's locale. When you set Option Compare Text and sort the characters in the preceding example, the
following text sort order applies:
(A=a) < (À= à) < (B=b) < (E=e) < (Ê= ê) < (Ø = ø) < (Z=z)
Locale Dependence
When you set Option Compare Text , the result of a string comparison can depend on the locale in which the
application is running. Two characters might compare as equal in one locale but not in another. If you are using
a string comparison to make important decisions, such as whether to accept an attempt to log on, you should be
alert to locale sensitivity. Consider either setting Option Compare Binary or calling the StrComp, which takes the
locale into account.
One numeric and one String The String is converted to a Double and numeric
comparison is performed. If the String cannot be
converted to Double , an InvalidCastException is thrown.
Either or both are reference types other than String An InvalidCastException is thrown.
Numeric comparisons treat Nothing as 0. String comparisons treat Nothing as "" (an empty string).
Overloading
The relational comparison operators ( < . <= , > , >= , = , <> ) can be overloaded, which means that a class or
structure can redefine their behavior when an operand has the type of that class or structure. If your code uses
any of these operators on such a class or structure, be sure you understand the redefined behavior. For more
information, see Operator Procedures.
Notice that the = Operator can be overloaded only as a relational comparison operator, not as an assignment
operator.
Example
The following example shows various uses of relational comparison operators, which you use to compare
expressions. Relational comparison operators return a Boolean result that represents whether or not the stated
expression evaluates to True . When you apply the > and < operators to strings, the comparison is made
using the normal alphabetical sorting order of the strings. This order can be dependent on your locale setting.
Whether the sort is case-sensitive or not depends on the Option Compare setting.
Dim x As testClass
Dim y As New testClass()
x = y
If x Is y Then
' Insert code to run if x and y point to the same instance.
End If
In the preceding example, the first comparison returns False and the remaining comparisons return True .
See Also
InvalidCastException
= Operator
Operator Precedence in Visual Basic
Operators Listed by Functionality
Troubleshooting Data Types
Comparison Operators in Visual Basic
Concatenation Operators (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
See Also
System.Text
StringBuilder
Operator Precedence in Visual Basic
Concatenation Operators in Visual Basic
Logical/Bitwise Operators (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
See Also
Operator Precedence in Visual Basic
Logical and Bitwise Operators in Visual Basic
Miscellaneous Operators (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
See Also
Operators Listed by Functionality
Properties (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
This page lists the properties that are members of Visual Basic modules. Other properties that are members of
specific Visual Basic objects are listed in Objects.
Now Returns a Date value containing the current date and time
according to your system.
See Also
Visual Basic Language Reference
Visual Basic
Queries (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
Visual Basic enables you to create Language-Integrated Query (LINQ) expressions in your code.
In This Section
Aggregate Clause
Describes the Aggregate clause, which applies one or more aggregate functions to a collection.
Distinct Clause
Describes the Distinct clause, which restricts the values of the current range variable to eliminate duplicate
values in query results.
From Clause
Describes the From clause, which specifies a collection and a range variable for a query.
Group By Clause
Describes the Group By clause, which groups the elements of a query result and can be used to apply aggregate
functions to each group.
Group Join Clause
Describes the Group Join clause, which combines two collections into a single hierarchical collection.
Join Clause
Describes the Join clause, which combines two collections into a single collection.
Let Clause
Describes the Let clause, which computes a value and assigns it to a new variable in the query.
Order By Clause
Describes the Order By clause, which specifies the sort order for columns in a query.
Select Clause
Describes the Select clause, which declares a set of range variables for a query.
Skip Clause
Describes the Skip clause, which bypasses a specified number of elements in a collection and then returns the
remaining elements.
Skip While Clause
Describes the Skip While clause, which bypasses elements in a collection as long as a specified condition is
true and then returns the remaining elements.
Take Clause
Describes the Take clause, which returns a specified number of contiguous elements from the start of a
collection.
Take While Clause
Describes the Take While clause, which includes elements in a collection as long as a specified condition is true
and bypasses the remaining elements.
Where Clause
Describes the Where clause, which specifies a filtering condition for a query.
See Also
LINQ
Introduction to LINQ in Visual Basic
Aggregate Clause (Visual Basic)
7/29/2017 • 6 min to read • Edit Online
Syntax
Aggregate element [As type] In collection _
[, element2 [As type2] In collection2, [...]]
[ clause ]
Into expressionList
Parts
TERM DEFINITION
Remarks
The Aggregate clause can be used to include aggregate functions in your queries. Aggregate functions perform
checks and computations over a set of values and return a single value. You can access the computed value by
using a member of the query result type. The standard aggregate functions that you can use are the All , Any ,
Average , Count , LongCount , Max , Min , and Sum functions. These functions are familiar to developers who are
familiar with aggregates in SQL. They are described in the following section of this topic.
The result of an aggregate function is included in the query result as a field of the query result type. You can
supply an alias for the aggregate function result to specify the name of the member of the query result type that
will hold the aggregate value. If no alias is supplied, the name of the aggregate function is used.
The Aggregate clause can begin a query, or it can be included as an additional clause in a query. If the Aggregate
clause begins a query, the result is a single value that is the result of the aggregate function specified in the Into
clause. If more than one aggregate function is specified in the Into clause, the query returns a single type with a
separate property to reference the result of each aggregate function in the Into clause. If the Aggregate clause is
included as an additional clause in a query, the type returned in the query collection will have a separate property
to reference the result of each aggregate function in the Into clause.
Aggregate Functions
The following list describes the standard aggregate functions that can be used with the Aggregate clause.
FUNCTION DESCRIPTION
Example
The following code example shows how to use the Aggregate clause to apply aggregate functions to a query
result.
Public Sub AggregateSample()
Dim customers = GetCustomerList()
Dim customerOrderTotal =
From cust In customers
Aggregate order In cust.Orders
Into Sum(order.Total), MaxOrder = Max(order.Total),
MinOrder = Min(order.Total), Avg = Average(order.Total)
Module UserDefinedAggregates
Return medianValue
End Function
' "Cast" the collection of generic items as type Double and call the
' Median() method to calculate the median value.
<Extension()>
Function Median(Of T)(ByVal values As IEnumerable(Of T),
ByVal selector As Func(Of T, Double)) As Double
Return (From element In values Select selector(element)).Median()
End Function
End Module
The following code example shows sample queries that call the Median aggregate function on a collection of type
Integer , and a collection of type Double . The query that calls the Median aggregate function on the collection of
type Double calls the overload of the Median method that accepts, as input, a collection of type Double . The
query that calls the Median aggregate function on the collection of type Integer calls the generic overload of the
Median method.
Module Module1
Sub Main()
Dim numbers1 = {1, 2, 3, 4, 5}
End Module
See Also
Introduction to LINQ in Visual Basic
Queries
Select Clause
From Clause
Where Clause
Group By Clause
Distinct Clause (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
Restricts the values of the current range variable to eliminate duplicate values in subsequent query clauses.
Syntax
Distinct
Remarks
You can use the Distinct clause to return a list of unique items. The Distinct clause causes the query to ignore
duplicate query results. The Distinct clause applies to duplicate values for all return fields specified by the
Select clause. If no Select clause is specified, the Distinct clause is applied to the range variable for the query
identified in the From clause. If the range variable is not an immutable type, the query will only ignore a query
result if all members of the type match an existing query result.
Example
The following query expression joins a list of customers and a list of customer orders. The Distinct clause is
included to return a list of unique customer names and order dates.
See Also
Introduction to LINQ in Visual Basic
Queries
From Clause
Select Clause
Where Clause
Equals Clause (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
Remarks
The Equals keyword is used in the following contexts:
Group Join Clause
Join Clause
See Also
Keywords
From Clause (Visual Basic)
7/29/2017 • 3 min to read • Edit Online
Syntax
From element [ As type ] In collection [ _ ]
[, element2 [ As type2 ] In collection2 [, ... ] ]
Parts
TERM DEFINITION
Remarks
The From clause is used to identify the source data for a query and the variables that are used to refer to an
element from the source collection. These variables are called range variables. The From clause is required for a
query, except when the Aggregate clause is used to identify a query that returns only aggregated results. For
more information, see Aggregate Clause.
You can specify multiple From clauses in a query to identify multiple collections to be joined. When multiple
collections are specified, they are iterated over independently, or you can join them if they are related. You can
join collections implicitly by using the Select clause, or explicitly by using the Join or Group Join clauses. As
an alternative, you can specify multiple range variables and collections in a single From clause, with each related
range variable and collection separated from the others by a comma. The following code example shows both
syntax options for the From clause.
The clause defines the scope of a query, which is similar to the scope of a For loop. Therefore, each
From
element range variable in the scope of a query must have a unique name. Because you can specify multiple
From clauses for a query, subsequent From clauses can refer to range variables in the From clause, or they can
refer to range variables in a previous From clause. For example, the following example shows a nested From
clause where the collection in the second clause is based on a property of the range variable in the first clause.
Each From clause can be followed by any combination of additional query clauses to refine the query. You can
refine the query in the following ways:
Combine multiple collections implicitly by using the From and Select clauses, or explicitly by using the
Join or Group Join clauses.
Example
The following query expression uses a From clause to declare a range variable cust for each Customer object
in the customers collection. The Where clause uses the range variable to restrict the output to customers from
the specified region. The For Each loop displays the company name for each customer in the query result.
See Also
Queries
Introduction to LINQ in Visual Basic
For Each...Next Statement
For...Next Statement
Select Clause
Where Clause
Aggregate Clause
Distinct Clause
Join Clause
Group Join Clause
Order By Clause
Let Clause
Skip Clause
Take Clause
Skip While Clause
Take While Clause
Group By Clause (Visual Basic)
7/29/2017 • 2 min to read • Edit Online
Groups the elements of a query result. Can also be used to apply aggregate functions to each group. The grouping
operation is based on one or more keys.
Syntax
Group [ listField1 [, listField2 [...] ] By keyExp1 [, keyExp2 [...] ]
Into aggregateList
Parts
listField1 , listField2
Optional. One or more fields of the query variable or variables that explicitly identify the fields to be
included in the grouped result. If no fields are specified, all fields of the query variable or variables are
included in the grouped result.
keyExp1
Required. An expression that identifies the key to use to determine the groups of elements. You can specify
more than one key to specify a composite key.
keyExp2
Optional. One or more additional keys that are combined with keyExp1 to create a composite key.
aggregateList
Required. One or more expressions that identify how the groups are aggregated. To identify a member
name for the grouped results, use the Group keyword, which can be in either of the following forms:
Into Group
-or-
Remarks
You can use the Group By clause to break the results of a query into groups. The grouping is based on a key or a
composite key consisting of multiple keys. Elements that are associated with matching key values are included in
the same group.
You use the aggregateList parameter of the Into clause and the Group keyword to identify the member name
that is used to reference the group. You can also include aggregate functions in the Into clause to compute
values for the grouped elements. For a list of standard aggregate functions, see Aggregate Clause.
Example
The following code example groups a list of customers based on their location (country) and provides a count of
the customers in each group. The results are ordered by country name. The grouped results are ordered by city
name.
See Also
Introduction to LINQ in Visual Basic
Queries
Select Clause
From Clause
Order By Clause
Aggregate Clause
Group Join Clause
Group Join Clause (Visual Basic)
7/29/2017 • 3 min to read • Edit Online
Combines two collections into a single hierarchical collection. The join operation is based on matching keys.
Syntax
Group Join element [As type] In collection _
On key1 Equals key2 [ And key3 Equals key4 [... ] ] _
Into expressionList
Parts
TERM DEFINITION
element Required. The control variable for the collection being joined.
key1 Equals key2 Required. Identifies keys for the collections being joined. You
must use the Equals operator to compare keys from the
collections being joined. You can combine join conditions by
using the And operator to identify multiple keys. The key1
parameter must be from the collection on the left side of the
Join operator. The key2 parameter must be from the
collection on the right side of the Join operator.
Remarks
The Group Join clause combines two collections based on matching key values from the collections being joined.
The resulting collection can contain a member that references a collection of elements from the second collection
that match the key value from the first collection. You can also specify aggregate functions to apply to the
grouped elements from the second collection. For information about aggregate functions, see Aggregate Clause.
Consider, for example, a collection of managers and a collection of employees. Elements from both collections
have a ManagerID property that identifies the employees that report to a particular manager. The results from a
join operation would contain a result for each manager and employee with a matching ManagerID value. The
results from a Group Join operation would contain the complete list of managers. Each manager result would
have a member that referenced the list of employees that were a match for the specific manager.
The collection resulting from a Group Join operation can contain any combination of values from the collection
identified in the From clause and the expressions identified in the Into clause of the Group Join clause. For
more information about valid expressions for the Into clause, see Aggregate Clause.
A Group Join operation will return all results from the collection identified on the left side of the Group Join
operator. This is true even if there are no matches in the collection being joined. This is like a LEFT OUTER JOIN in
SQL.
You can use the Join clause to combine collections into a single collection. This is equivalent to an INNER JOIN
in SQL.
Example
The following code example joins two collections by using the Group Join clause.
See Also
Introduction to LINQ in Visual Basic
Queries
Select Clause
From Clause
Join Clause
Where Clause
Group By Clause
Join Clause (Visual Basic)
7/29/2017 • 3 min to read • Edit Online
Combines two collections into a single collection. The join operation is based on matching keys and uses the
Equals operator.
Syntax
Join element In collection _
[ joinClause _ ]
[ groupJoinClause ... _ ]
On key1 Equals key2 [ And key3 Equals key4 [... ]
Parts
element
Required. The control variable for the collection being joined.
collection
Required. The collection to combine with the collection identified on the left side of the Join operator. A Join
clause can be nested in another Join clause, or in a Group Join clause.
joinClause
Optional. One or more additional Join clauses to further refine the query.
groupJoinClause
Optional. One or more additional Group Join clauses to further refine the query.
key1 Equals key2
Required. Identifies keys for the collections being joined. You must use the Equals operator to compare keys
from the collections being joined. You can combine join conditions by using the And operator to identify multiple
keys. key1 must be from the collection on the left side of the Join operator. key2 must be from the collection
on the right side of the Join operator.
The keys used in the join condition can be expressions that include more than one item from the collection.
However, each key expression can contain only items from its respective collection.
Remarks
The Join clause combines two collections based on matching key values from the collections being joined. The
resulting collection can contain any combination of values from the collection identified on the left side of the
Join operator and the collection identified in the Join clause. The query will return only results for which the
condition specified by the Equals operator is met. This is equivalent to an INNER JOIN in SQL.
You can use multiple Join clauses in a query to join two or more collections into a single collection.
You can perform an implicit join to combine collections without the Join clause. To do this, include multiple In
clauses in your From clause and specify a Where clause that identifies the keys that you want to use for the join.
You can use the Group Join clause to combine collections into a single hierarchical collection. This is like a
LEFT OUTER JOIN in SQL.
Example
The following code example performs an implicit join to combine a list of customers with their orders.
Example
The following code example joins two collections by using the Join clause.
Imports System.Diagnostics
Imports System.Security.Permissions
<SecurityPermission(SecurityAction.Demand)>
Public Sub ListProcesses()
Dim processDescriptions As New List(Of ProcessDescription)
processDescriptions.Add(New ProcessDescription With {
.ProcessName = "explorer",
.Description = "Windows Explorer"})
processDescriptions.Add(New ProcessDescription With {
.ProcessName = "winlogon",
.Description = "Windows Logon"})
processDescriptions.Add(New ProcessDescription With {
.ProcessName = "cmd",
.Description = "Command Window"})
processDescriptions.Add(New ProcessDescription With {
.ProcessName = "iexplore",
.Description = "Internet Explorer"})
End Class
Example
The following code example joins two collections by using the Join clause with two key columns.
Imports System.Diagnostics
Imports System.Security.Permissions
<SecurityPermission(SecurityAction.Demand)>
Public Sub ListProcesses()
Dim processDescriptions As New List(Of ProcessDescription2)
End Class
Syntax
Let variable = expression [, ...]
Parts
TERM DEFINITION
Remarks
The Let clause enables you to compute values for each query result and reference them by using an alias. The
alias can be used in other clauses, such as the Where clause. The Let clause enables you to create a query
statement that is easier to read because you can specify an alias for an expression clause included in the query and
substitute the alias each time the expression clause is used.
You can include any number of variable and expression assignments in the Let clause. Separate each
assignment with a comma (,).
Example
The following code example uses the Let clause to compute a 10 percent discount on products.
See Also
Introduction to LINQ in Visual Basic
Queries
Select Clause
From Clause
Where Clause
Order By Clause (Visual Basic)
7/29/2017 • 2 min to read • Edit Online
Syntax
Order By orderExp1 [ Ascending | Descending ] [, orderExp2 [...] ]
Parts
orderExp1
Required. One or more fields from the current query result that identify how to order the returned values. The
field names must be separated by commas (,). You can identify each field as sorted in ascending or descending
order by using the Ascending or Descending keywords. If no Ascending or Descending keyword is specified, the
default sort order is ascending. The sort order fields are given precedence from left to right.
Remarks
You can use the Order By clause to sort the results of a query. The Order By clause can only sort a result based
on the range variable for the current scope. For example, the Select clause introduces a new scope in a query
expression with new iteration variables for that scope. Range variables defined before a Select clause in a query
are not available after the Select clause. Therefore, if you want to order your results by a field that is not
available in the Select clause, you must put the Order By clause before the Select clause. One example of
when you would have to do this is when you want to sort your query by fields that are not returned as part of the
result.
Ascending and descending order for a field is determined by the implementation of the IComparable interface for
the data type of the field. If the data type does not implement the IComparable interface, the sort order is ignored.
Example
The following query expression uses a From clause to declare a range variable book for the books collection.
The Order By clause sorts the query result by price in ascending order (the default). Books with the same price
are sorted by title in ascending order. The Select clause selects the Title and Price properties as the values
returned by the query.
Example
The following query expression uses the Order By clause to sort the query result by price in descending order.
Books with the same price are sorted by title in ascending order.
Dim titlesDescendingPrice = From book In books
Order By book.Price Descending, book.Title
Select book.Title, book.Price
Example
The following query expression uses a Select clause to select the book title, price, publish date, and author. It
then populates the Title , Price , PublishDate , and Author fields of the range variable for the new scope. The
Order By clause orders the new range variable by author name, book title, and then price. Each column is sorted
in the default order (ascending).
Dim bookOrders =
From book In books
Select book.Title, book.Price, book.PublishDate, book.Author
Order By Author, Title, Price
See Also
Introduction to LINQ in Visual Basic
Queries
Select Clause
From Clause
Select Clause (Visual Basic)
7/29/2017 • 3 min to read • Edit Online
Syntax
Select [ var1 = ] fieldName1 [, [ var2 = ] fieldName2 [...] ]
Parts
var1
Optional. An alias that can be used to reference the results of the column expression.
fieldName1
Required. The name of the field to return in the query result.
Remarks
You can use the Select clause to define the results to return from a query. This enables you to either define the
members of a new anonymous type that is created by a query, or to target the members of a named type that is
returned by a query. The Select clause is not required for a query. If no Select clause is specified, the query
will return a type based on all members of the range variables identified for the current scope. For more
information, see Anonymous Types. When a query creates a named type, it will return a result of type
IEnumerable<T> where T is the created type.
The Selectclause can reference any variables in the current scope. This includes range variables identified in
the Fromclause (or From clauses). It also includes any new variables created with an alias by the Aggregate ,
Let , Group By , or Group Join clauses, or variables from a previous Select clause in the query expression. The
Select clause can also include static values. For example, the following code example shows a query expression
in which the Select clause defines the query result as a new anonymous type with four members: ProductName ,
Price , Discount , and DiscountedPrice . The ProductName and Price member values are taken from the
product range variable that is defined in the From clause. The DiscountedPrice member value is calculated in
the Let clause. The Discount member is a static value.
The Select clause introduces a new set of range variables for subsequent query clauses, and previous range
variables are no longer in scope. The last Select clause in a query expression determines the return value of the
query. For example, the following query returns the company name and order ID for every customer order for
which the total exceeds 500. The first Select clause identifies the range variables for the Where clause and the
second Select clause. The second Select clause identifies the values returned by the query as a new
anonymous type.
Dim customerList = From cust In customers, ord In cust.Orders
Select Name = cust.CompanyName,
Total = ord.Total, ord.OrderID
Where Total > 500
Select Name, OrderID
If the Select clause identifies a single item to return, the query expression returns a collection of the type of
that single item. If the Select clause identifies multiple items to return, the query expression returns a collection
of a new anonymous type, based on the selected items. For example, the following two queries return collections
of two different types based on the Select clause. The first query returns a collection of company names as
strings. The second query returns a collection of Customer objects populated with the company names and
address information.
Example
The following query expression uses a From clause to declare a range variable cust for the customers
collection. The Select clause selects the customer name and ID value and populates the CompanyName and
CustomerID columns of the new range variable. The For Each statement loops over each returned object and
displays the CompanyName and CustomerID columns for each record.
See Also
Introduction to LINQ in Visual Basic
Queries
From Clause
Where Clause
Order By Clause
Anonymous Types
Skip Clause (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
Bypasses a specified number of elements in a collection and then returns the remaining elements.
Syntax
Skip count
Parts
count
Required. A value or an expression that evaluates to the number of elements of the sequence to skip.
Remarks
The Skip clause causes a query to bypass elements at the beginning of a results list and return the remaining
elements. The number of elements to skip is identified by the count parameter.
You can use the Skip clause with the Take clause to return a range of data from any segment of a query. To do
this, pass the index of the first element of the range to the Skip clause and the size of the range to the Take
clause.
When you use the Skip clause in a query, you may also need to ensure that the results are returned in an order
that will enable the Skip clause to bypass the intended results. For more information about ordering query
results, see Order By Clause.
You can use the SkipWhile clause to specify that only certain elements are ignored, depending on a supplied
condition.
Example
The following code example uses the Skip clause together with the Take clause to return data from a query in
pages. The GetCustomers function uses the Skip clause to bypass the customers in the list until the supplied
starting index value, and uses the Take clause to return a page of customers starting from that index value.
Public Sub PagingSample()
Dim pageNumber As Integer = 0
Dim pageSize As Integer = 10
Console.WriteLine(vbCrLf)
pageNumber += 1
customersPage = GetCustomers(pageNumber * pageSize, pageSize)
Loop
End Sub
Return returnCustomers
End Function
See Also
Introduction to LINQ in Visual Basic
Queries
Select Clause
From Clause
Order By Clause
Skip While Clause
Take Clause
Skip While Clause (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
Bypasses elements in a collection as long as a specified condition is true and then returns the remaining
elements.
Syntax
Skip While expression
Parts
TERM DEFINITION
Remarks
The Skip While clause bypasses elements from the beginning of a query result until the supplied expression
returns false . After expression returns false , the query returns all the remaining elements. The expression is
ignored for the remaining results.
The Skip While clause differs from the Where clause in that the Where clause can be used to exclude all elements
from a query that do not meet a particular condition. The Skip While clause excludes elements only until the first
time that the condition is not satisfied. The Skip While clause is most useful when you are working with an
ordered query result.
You can bypass a specific number of results from the beginning of a query result by using the Skip clause.
Example
The following code example uses the Skip While clause to bypass results until the first customer from the United
States is found.
Public Sub SkipWhileSample()
Dim customers = GetCustomerList()
' Return customers starting from the first U.S. customer encountered.
Dim customerList = From cust In customers
Order By cust.Country
Skip While IsInternationalCustomer(cust)
Return True
End Function
See Also
Introduction to LINQ in Visual Basic
Queries
Select Clause
From Clause
Skip Clause
Take While Clause
Where Clause
Take Clause (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
Syntax
Take count
Parts
count
Required. A value or an expression that evaluates to the number of elements of the sequence to return.
Remarks
The Take clause causes a query to include a specified number of contiguous elements from the start of a results
list. The number of elements to include is specified by the count parameter.
You can use the Take clause with the Skip clause to return a range of data from any segment of a query. To do
this, pass the index of the first element of the range to the Skip clause and the size of the range to the Take
clause. In this case, the Take clause must be specified after the Skip clause.
When you use the Take clause in a query, you may also need to ensure that the results are returned in an order
that will enable the Take clause to include the intended results. For more information about ordering query
results, see Order By Clause.
You can use the TakeWhile clause to specify that only certain elements be returned, depending on a supplied
condition.
Example
The following code example uses the Take clause together with the Skip clause to return data from a query in
pages. The GetCustomers function uses the Skip clause to bypass the customers in the list until the supplied
starting index value, and uses the Take clause to return a page of customers starting from that index value.
Public Sub PagingSample()
Dim pageNumber As Integer = 0
Dim pageSize As Integer = 10
Console.WriteLine(vbCrLf)
pageNumber += 1
customersPage = GetCustomers(pageNumber * pageSize, pageSize)
Loop
End Sub
Return returnCustomers
End Function
See Also
Introduction to LINQ in Visual Basic
Queries
Select Clause
From Clause
Order By Clause
Take While Clause
Skip Clause
Take While Clause (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
Includes elements in a collection as long as a specified condition is true and bypasses the remaining elements.
Syntax
Take While expression
Parts
TERM DEFINITION
Remarks
The Take While clause includes elements from the start of a query result until the supplied expression returns
false . After the expression returns false , the query will bypass all remaining elements. The expression is
ignored for the remaining results.
The Take While clause differs from the Where clause in that the Where clause can be used to include all elements
from a query that meet a particular condition. The Take While clause includes elements only until the first time
that the condition is not satisfied. The Take While clause is most useful when you are working with an ordered
query result.
Example
The following code example uses the Take While clause to retrieve results until the first customer without any
orders is found.
Public Sub TakeWhileSample()
Dim customers = GetCustomerList()
' Return customers until the first customer with no orders is found.
Dim customersWithOrders = From cust In customers
Order By cust.Orders.Count Descending
Take While HasOrders(cust)
Return False
End Function
See Also
Introduction to LINQ in Visual Basic
Queries
Select Clause
From Clause
Take Clause
Skip While Clause
Where Clause
Where Clause (Visual Basic)
7/29/2017 • 2 min to read • Edit Online
Syntax
Where condition
Parts
condition
Required. An expression that determines whether the values for the current item in the collection are included in
the output collection. The expression must evaluate to a Boolean value or the equivalent of a Boolean value. If
the condition evaluates to True , the element is included in the query result; otherwise, the element is excluded
from the query result.
Remarks
The Where clause enables you to filter query data by selecting only elements that meet certain criteria. Elements
whose values cause the Where clause to evaluate to True are included in the query result; other elements are
excluded. The expression that is used in a Where clause must evaluate to a Boolean or the equivalent of a
Boolean , such as an Integer that evaluates to False when its value is zero. You can combine multiple
expressions in a Where clause by using logical operators such as And , Or , AndAlso , OrElse , Is , and IsNot .
By default, query expressions are not evaluated until they are accessed—for example, when they are data-bound
or iterated through in a For loop. As a result, the Where clause is not evaluated until the query is accessed. If
you have values external to the query that are used in the Where clause, ensure that the appropriate value is
used in the Where clause at the time the query is executed. For more information about query execution, see
Writing Your First LINQ Query.
You can call functions within a Where clause to perform a calculation or operation on a value from the current
element in the collection. Calling a function in a Where clause can cause the query to be executed immediately
when it is defined instead of when it is accessed. For more information about query execution, see Writing Your
First LINQ Query.
Example
The following query expression uses a From clause to declare a range variable cust for each Customer object
in the customers collection. The Where clause uses the range variable to restrict the output to customers from
the specified region. The For Each loop displays the company name for each customer in the query result.
Sub DisplayCustomersForRegion(ByVal customers As List(Of Customer),
ByVal region As String)
Example
The following example uses And and Or logical operators in the Where clause.
' Get a list of elements that have an atomic number from 12 to 14,
' or that have a name that ends in "r".
Dim subset = From theElement In elements
Where (theElement.AtomicNumber >= 12 And theElement.AtomicNumber < 15) _
Or theElement.Name.EndsWith("r")
Order By theElement.Name
' Output:
' Aluminum 13
' Magnesium 12
' Silicon 14
' Sulfur 16
End Sub
See Also
Introduction to LINQ in Visual Basic
Queries
From Clause
Select Clause
For Each...Next Statement
Statements (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
The topics in this section contain tables of the Visual Basic declaration and executable statements, and of
important lists that apply to many statements.
In This Section
A-E Statements
F-P Statements
Q-Z Statements
Clauses
Declaration Contexts and Default Access Levels
Attribute List
Parameter List
Type List
Related Sections
Visual Basic Language Reference
Visual Basic
A-E Statements
7/29/2017 • 1 min to read • Edit Online
Exit
See Also
F-P Statements
Q-Z Statements
Visual Basic Language Reference
AddHandler Statement
7/29/2017 • 1 min to read • Edit Online
Syntax
AddHandler event, AddressOf eventhandler
Parts
event
The name of the event to handle.
eventhandler
The name of a procedure that handles the event.
Remarks
The AddHandler and RemoveHandler statements allow you to start and stop event handling at any time during
program execution.
The signature of the eventhandler procedure must match the signature of the event event .
The Handles keyword and the AddHandler statement both allow you to specify that particular procedures handle
particular events, but there are differences. The AddHandler statement connects procedures to events at run time.
Use the Handles keyword when defining a procedure to specify that it handles a particular event. For more
information, see Handles.
NOTE
For custom events, the AddHandler statement invokes the event's AddHandler accessor. For more information on
custom events, see Event Statement.
Example
Sub TestEvents()
Dim Obj As New Class1
' Associate an event handler with an event.
AddHandler Obj.Ev_Event, AddressOf EventHandler
' Call the method to raise the event.
Obj.CauseSomeEvent()
' Stop handling events.
RemoveHandler Obj.Ev_Event, AddressOf EventHandler
' This event will not be handled.
Obj.CauseSomeEvent()
End Sub
Sub EventHandler()
' Handle the event.
MsgBox("EventHandler caught event.")
End Sub
See Also
RemoveHandler Statement
Handles
Event Statement
Events
Call Statement (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
Syntax
[ Call ] procedureName [ (argumentList) ]
Parts
procedureName
Required. Name of the procedure to call.
argumentList
Optional. List of variables or expressions representing arguments that are passed to the procedure when it is
called. Multiple arguments are separated by commas. If you include argumentList , you must enclose it in
parentheses.
Remarks
You can use the Call keyword when you call a procedure. For most procedure calls, you aren’t required to use
this keyword.
You typically use the Call keyword when the called expression doesn’t start with an identifier. Use of the Call
keyword for other uses isn’t recommended.
If the procedure returns a value, the Call statement discards it.
Example
The following code shows two examples where the Call keyword is necessary to call a procedure. In both
examples, the called expression doesn't start with an identifier.
Sub TestCall()
Call (Sub() Console.Write("Hello"))()
Class TheClass
Public Sub ShowText()
Console.Write(" World")
End Sub
End Class
See Also
Function Statement
Sub Statement
Declare Statement
Lambda Expressions
Class Statement (Visual Basic)
7/29/2017 • 4 min to read • Edit Online
Declares the name of a class and introduces the definition of the variables, properties, events, and procedures
that the class comprises.
Syntax
[ <attributelist> ] [ accessmodifier ] [ Shadows ] [ MustInherit | NotInheritable ] [ Partial ] _
Class name [ ( Of typelist ) ]
[ Inherits classname ]
[ Implements interfacenames ]
[ statements ]
End Class
Parts
TERM DEFINITION
- Public
- Protected
- Friend
- Private
- Protected Friend
Remarks
A Class statement defines a new data type. A class is a fundamental building block of object-oriented
programming (OOP). For more information, see Objects and Classes.
You can use Class only at namespace or module level. This means the declaration context for a class must
be a source file, namespace, class, structure, module, or interface, and cannot be a procedure or block. For
more information, see Declaration Contexts and Default Access Levels.
Each instance of a class has a lifetime independent of all other instances. This lifetime begins when it is
created by a New Operator clause or by a function such as CreateObject. It ends when all variables pointing
to the instance have been set to Nothing or to instances of other classes.
Classes default to Friend access. You can adjust their access levels with the access modifiers. For more
information, see Access levels in Visual Basic.
Rules
Nesting. You can define one class within another. The outer class is called the containing class, and
the inner class is called a nested class.
Inheritance. If the class uses the Inherits Statement, you can specify only one base class or interface.
A class cannot inherit from more than one element.
A class cannot inherit from another class with a more restrictive access level. For example, a Public
class cannot inherit from a Friend class.
A class cannot inherit from a class nested within it.
Implementation. If the class uses the Implements Statement, you must implement every member
defined by every interface you specify in interfacenames . An exception to this is reimplementation of a
base class member. For more information, see "Reimplementation" in Implements.
Default Property. A class can specify at most one property as its default property. For more
information, see Default.
Behavior
Access Level. Within a class, you can declare each member with its own access level. Class members
default to Public access, except variables and constants, which default to Private access. When a class
has more restricted access than one of its members, the class access level takes precedence.
Scope. A class is in scope throughout its containing namespace, class, structure, or module.
The scope of every class member is the entire class.
Lifetime. Visual Basic does not support static classes. The functional equivalent of a static class is
provided by a module. For more information, see Module Statement.
Class members have lifetimes depending on how and where they are declared. For more information,
see Lifetime in Visual Basic.
Qualification. Code outside a class must qualify a member's name with the name of that class.
If code inside a nested class makes an unqualified reference to a programming element, Visual Basic
searches for the element first in the nested class, then in its containing class, and so on out to the
outermost containing element.
Example
The following example uses a Class statement to define a class and several members.
Class bankAccount
Shared interestRate As Decimal
Private accountNumber As String
Private accountBalance As Decimal
Public holdOnAccount As Boolean = False
Syntax
[ <attributelist> ] [ accessmodifier ] [ Shadows ]
Const constantlist
Parts
attributelist
Optional. List of attributes that apply to all the constants declared in this statement. See Attribute List in angle
brackets (" < " and " > ").
accessmodifier
Optional. Use this to specify what code can access these constants. Can be Public, Protected, Friend,
Protected Friend , or Private.
Shadows
Optional. Use this to redeclare and hide a programming element in a base class. See Shadows.
constantlist
Required. List of constants being declared in this statement.
constant [ , constant ... ]
PART DESCRIPTION
Remarks
If you have a value that never changes in your application, you can define a named constant and use it in place
of a literal value. A name is easier to remember than a value. You can define the constant just once and use it in
many places in your code. If in a later version you need to redefine the value, the Const statement is the only
place you need to make a change.
You can use Const only at module or procedure level. This means the declaration context for a variable must
be a class, structure, module, procedure, or block, and cannot be a source file, namespace, or interface. For
more information, see Declaration Contexts and Default Access Levels.
Local constants (inside a procedure) default to public access, and you cannot use any access modifiers on them.
Class and module member constants (outside any procedure) default to private access, and structure member
constants default to public access. You can adjust their access levels with the access modifiers.
Rules
Declaration Context. A constant declared at module level, outside any procedure, is a member
constant; it is a member of the class, structure, or module that declares it.
A constant declared at procedure level is a local constant; it is local to the procedure or block that
declares it.
Attributes. You can apply attributes only to member constants, not to local constants. An attribute
contributes information to the assembly's metadata, which is not meaningful for temporary storage
such as local constants.
Modifiers. By default, all constants are Shared , Static , and ReadOnly . You cannot use any of these
keywords when declaring a constant.
At procedure level, you cannot use Shadows or any access modifiers to declare local constants.
Multiple Constants. You can declare several constants in the same declaration statement, specifying
the constantname part for each one. Multiple constants are separated by commas.
Behavior
Scope. Local constants are accessible only from within their procedure or block. Member constants are
accessible from anywhere within their class, structure, or module.
Qualification. Code outside a class, structure, or module must qualify a member constant's name with
the name of that class, structure, or module. Code outside a procedure or block cannot refer to any local
constants within that procedure or block.
Example
The following example uses the Const statement to declare constants for use in place of literal values.
Example
If you define a constant with data type Object , the Visual Basic compiler gives it the type of initializer ,
instead of Object . In the following example, the constant naturalLogBase has the run-time type Decimal .
The preceding example uses the ToString method on the Type object returned by the GetType Operator,
because Type cannot be converted to String using CStr .
See Also
Asc
AscW
Enum Statement
#Const Directive
Dim Statement
ReDim Statement
Implicit and Explicit Conversions
Constants and Enumerations
Constants and Enumerations
Type Conversion Functions
Continue Statement (Visual Basic)
7/29/2017 • 2 min to read • Edit Online
Syntax
Continue { Do | For | While }
Remarks
You can transfer from inside a Do , For , or While loop to the next iteration of that loop. Control passes
immediately to the loop condition test, which is equivalent to transferring to the For or While statement, or to
the Do or Loop statement that contains the Until or While clause.
You can use Continue at any location in the loop that allows transfers. The rules allowing transfer of control are
the same as with the GoTo Statement.
For example, if a loop is totally contained within a Try block, a Catch block, or a Finally block, you can use
Continue to transfer out of the loop. If, on the other hand, the Try ... End Try structure is contained within the
loop, you cannot use Continue to transfer control out of the Finally block, and you can use it to transfer out of a
Try or Catch block only if you transfer completely out of the Try ... End Try structure.
If you have nested loops of the same type, for example a Do loop within another Do loop, a Continue Do
statement skips to the next iteration of the innermost Do loop that contains it. You cannot use Continue to skip to
the next iteration of a containing loop of the same type.
If you have nested loops of different types, for example a Do loop within a For loop, you can skip to the next
iteration of either loop by using either Continue Do or Continue For .
Example
The following code example uses the Continue While statement to skip to the next column of an array if a divisor
is zero. The Continue While is inside a For loop. It transfers to the While col < lastcol statement, which is the
next iteration of the innermost While loop that contains the For loop.
Dim row, col As Integer
Dim lastrow As Integer = 6
Dim lastcol As Integer = 10
Dim a(,) As Double = New Double(lastrow, lastcol) {}
Dim b(7) As Double
row = -1
While row < lastrow
row += 1
col = -1
While col < lastcol
col += 1
a(row, col) = 0
For i As Integer = 0 To b.GetUpperBound(0)
If b(i) = col Then
Continue While
Else
a(row, col) += (row + b(i)) / (col - b(i))
End If
Next i
End While
End While
See Also
Do...Loop Statement
For...Next Statement
While...End While Statement
Try...Catch...Finally Statement
Declare Statement
7/29/2017 • 8 min to read • Edit Online
Syntax
[ <attributelist> ] [ accessmodifier ] [ Shadows ] [ Overloads ] _
Declare [ charsetmodifier ] [ Sub ] name Lib "libname" _
[ Alias "aliasname" ] [ ([ parameterlist ]) ]
' -or-
[ <attributelist> ] [ accessmodifier ] [ Shadows ] [ Overloads ] _
Declare [ charsetmodifier ] [ Function ] name Lib "libname" _
[ Alias "aliasname" ] [ ([ parameterlist ]) ] [ As returntype ]
Parts
TERM DEFINITION
- Public
- Protected
- Friend
- Private
- Protected Friend
- Ansi (default)
- Unicode
- Auto
-or-
Remarks
Sometimes you need to call a procedure defined in a file (such as a DLL or code resource) outside your
project. When you do this, the Visual Basic compiler does not have access to the information it needs to call
the procedure correctly, such as where the procedure is located, how it is identified, its calling sequence and
return type, and the string character set it uses. The Declare statement creates a reference to an external
procedure and supplies this necessary information.
You can use Declare only at module level. This means the declaration context for an external reference
must be a class, structure, or module, and cannot be a source file, namespace, interface, procedure, or block.
For more information, see Declaration Contexts and Default Access Levels.
External references default to Public access. You can adjust their access levels with the access modifiers.
Rules
Attributes. You can apply attributes to an external reference. Any attribute you apply has effect only
in your project, not in the external file.
Modifiers. External procedures are implicitly Shared. You cannot use the Shared keyword when
declaring an external reference, and you cannot alter its shared status.
An external procedure cannot participate in overriding, implement interface members, or handle
events. Accordingly, you cannot use the Overrides , Overridable , NotOverridable , MustOverride ,
Implements , or Handles keyword in a Declare statement.
External Procedure Name. You do not have to give this external reference the same name (in
name ) as the procedure's entry-point name within its external file ( aliasname ). You can use an
Alias clause to specify the entry-point name. This can be useful if the external procedure has the
same name as a Visual Basic reserved modifier or a variable, procedure, or any other programming
element in the same scope.
NOTE
Entry-point names in most DLLs are case-sensitive.
External Procedure Number. Alternatively, you can use an Alias clause to specify the ordinal
number of the entry point within the export table of the external file. To do this, you begin
aliasname with a number sign ( # ). This can be useful if any character in the external procedure
name is not allowed in Visual Basic, or if the external file exports the procedure without a name.
NOTE
If the external procedure was not written for the .NET Framework, you must take care that the data types
correspond. For example, if you declare an external reference to a Visual Basic 6.0 procedure with an
Integer parameter (16 bits in Visual Basic 6.0), you must identify the corresponding argument as Short
in the Declare statement, because that is the 16-bit integer type in Visual Basic. Similarly, Long has a
different data width in Visual Basic 6.0, and Date is implemented differently.
Return Data Type. If the external procedure is a Function and Option Strict is On , you must
specify the data type of the value returned to the calling code. This can be any data type or the name
of an enumeration, structure, class, or interface.
NOTE
The Visual Basic compiler does not verify that your data types are compatible with those of the external
procedure. If there is a mismatch, the common language runtime generates a MarshalDirectiveException
exception at run time.
Default Data Types. If Option Strict is Off and you do not specify the data type of a parameter
in parameterlist , the Visual Basic compiler converts the corresponding argument to the Object Data
Type. Similarly, if you do not specify returntype , the compiler takes the return data type to be
Object .
NOTE
Because you are dealing with an external procedure that might have been written on a different platform, it
is dangerous to make any assumptions about data types or to allow them to default. It is much safer to
specify the data type of every parameter and of the return value, if any. This also improves the readability of
your code.
Behavior
Scope. An external reference is in scope throughout its class, structure, or module.
Lifetime. An external reference has the same lifetime as the class, structure, or module in which it is
declared.
Calling an External Procedure. You call an external procedure the same way you call a Function
or Sub procedure—by using it in an expression if it returns a value, or by specifying it in a Call
Statement if it does not return a value.
You pass arguments to the external procedure exactly as specified by parameterlist in the Declare
statement. Do not take into account how the parameters were originally declared in the external file.
Similarly, if there is a return value, use it exactly as specified by returntype in the Declare
statement.
Character Sets. You can specify in charsetmodifier how Visual Basic should marshal strings when
it calls the external procedure. The Ansi modifier directs Visual Basic to marshal all strings to ANSI
values, and the Unicode modifier directs it to marshal all strings to Unicode values. The Auto
modifier directs Visual Basic to marshal strings according to .NET Framework rules based on the
external reference name , or aliasname if specified. The default value is Ansi .
charsetmodifier also specifies how Visual Basic should look up the external procedure within its
external file. Ansi and Unicode both direct Visual Basic to look it up without modifying its name
during the search. Auto directs Visual Basic to determine the base character set of the run-time
platform and possibly modify the external procedure name, as follows:
On an ANSI platform, such as Windows 95, Windows 98, or Windows Millennium Edition, first
look up the external procedure with no name modification. If that fails, append "A" to the end
of the external procedure name and look it up again.
On a Unicode platform, such as Windows NT, Windows 2000, or Windows XP, first look up
the external procedure with no name modification. If that fails, append "W" to the end of the
external procedure name and look it up again.
Mechanism. Visual Basic uses the .NET Framework platform invoke (PInvoke) mechanism to
resolve and access external procedures. The Declare statement and the DllImportAttribute class
both use this mechanism automatically, and you do not need any knowledge of PInvoke. For more
information, see Walkthrough: Calling Windows APIs.
IMPORTANT
If the external procedure runs outside the common language runtime (CLR), it is unmanaged code. When you call
such a procedure, for example a Win32 API function or a COM method, you might expose your application to
security risks. For more information, see Secure Coding Guidelines for Unmanaged Code.
Example
The following example declares an external reference to a Function procedure that returns the current user
name. It then calls the external procedure GetUserNameA as part of the getUser procedure.
Declare Function getUserName Lib "advapi32.dll" Alias "GetUserNameA" (
ByVal lpBuffer As String, ByRef nSize As Integer) As Integer
Sub getUser()
Dim buffer As String = New String(CChar(" "), 25)
Dim retVal As Integer = getUserName(buffer, 25)
Dim userName As String = Strings.Left(buffer, InStr(buffer, Chr(0)) - 1)
MsgBox(userName)
End Sub
Example
The DllImportAttribute provides an alternative way of using functions in unmanaged code. The following
example declares an imported function without using a Declare statement.
<DllImportAttribute("kernel32.dll", EntryPoint:="MoveFileW",
SetLastError:=True, CharSet:=CharSet.Unicode,
ExactSpelling:=True,
CallingConvention:=CallingConvention.StdCall)>
Public Shared Function moveFile(ByVal src As String,
ByVal dst As String) As Boolean
' This function copies a file from the path src to the path dst.
' Leave this function empty. The DLLImport attribute forces calls
' to moveFile to be forwarded to MoveFileW in KERNEL32.DLL.
End Function
See Also
LastDllError
Imports Statement (.NET Namespace and Type)
AddressOf Operator
Function Statement
Sub Statement
Parameter List
Call Statement
Walkthrough: Calling Windows APIs
Delegate Statement
8/11/2017 • 3 min to read • Edit Online
Used to declare a delegate. A delegate is a reference type that refers to a Shared method of a type or to an
instance method of an object. Any procedure with matching parameter and return types can be used to create
an instance of this delegate class. The procedure can then later be invoked by means of the delegate instance.
Syntax
[ <attrlist> ] [ accessmodifier ] _
[ Shadows ] Delegate [ Sub | Function ] name [( Of typeparamlist )] [([ parameterlist ])] [ As type ]
Parts
TERM DEFINITION
accessmodifier Optional. Specifies what code can access the delegate. Can
be one of the following:
- Public. Any code that can access the element that declares
the delegate can access it.
- Protected. Only code within the delegate's class or a
derived class can access it.
- Friend. Only code within the same assembly can access the
delegate.
- Private. Only code within the element that declares the
delegate can access it.
Remarks
The Delegate statement defines the parameter and return types of a delegate class. Any procedure with
matching parameters and return types can be used to create an instance of this delegate class. The procedure
can then later be invoked by means of the delegate instance, by calling the delegate's Invoke method.
Delegates can be declared at the namespace, module, class, or structure level, but not within a procedure.
Each delegate class defines a constructor that is passed the specification of an object method. An argument to a
delegate constructor must be a reference to a method, or a lambda expression.
To specify a reference to a method, use the following syntax:
AddressOf [ expression .] methodname
The compile-time type of the expression must be the name of a class or an interface that contains a method of
the specified name whose signature matches the signature of the delegate class. The methodname can be either
a shared method or an instance method. The methodname is not optional, even if you create a delegate for the
default method of the class.
To specify a lambda expression, use the following syntax:
Function ([ parm As type , parm2 As type2 , ...]) expression
The signature of the function must match that of the delegate type. For more information about lambda
expressions, see Lambda Expressions.
For more information about delegates, see Delegates.
Example
The following example uses the Delegate statement to declare a delegate for operating on two numbers and
returning a number. The DelegateTest method takes an instance of a delegate of this type and uses it to
operate on pairs of numbers.
Delegate Function MathOperator(
ByVal x As Double,
ByVal y As Double
) As Double
Function AddNumbers(
ByVal x As Double,
ByVal y As Double
) As Double
Return x + y
End Function
Function SubtractNumbers(
ByVal x As Double,
ByVal y As Double
) As Double
Return x - y
End Function
Sub DelegateTest(
ByVal x As Double,
ByVal op As MathOperator,
ByVal y As Double
)
Dim ret As Double
ret = op.Invoke(x, y) ' Call the method.
MsgBox(ret)
End Sub
See Also
AddressOf Operator
Of
Delegates
How to: Use a Generic Class
Generic Types in Visual Basic
Covariance and Contravariance
In
Out
Dim Statement (Visual Basic)
7/29/2017 • 12 min to read • Edit Online
Syntax
[ <attributelist> ] [ accessmodifier ] [[ Shared ] [ Shadows ] | [ Static ]] [ ReadOnly ]
Dim [ WithEvents ] variablelist
Parts
attributelist
Optional. Specifies that these are object variables that refer to instances of a class that can raise
events. See WithEvents.
variablelist
PART DESCRIPTION
Remarks
The Visual Basic compiler uses the Dim statement to determine the variable's data type and other
information, such as what code can access the variable. The following example declares a variable to hold
an Integer value.
You can specify any data type or the name of an enumeration, structure, class, or interface.
For a reference type, you use the New keyword to create a new instance of the class or structure that is
specified by the data type. If you use New , you do not use an initializer expression. Instead, you supply
arguments, if they are required, to the constructor of the class from which you are creating the variable.
You can declare a variable in a procedure, block, class, structure, or module. You cannot declare a variable
in a source file, namespace, or interface. For more information, see Declaration Contexts and Default Access
Levels.
A variable that is declared at module level, outside any procedure, is a member variable or field. Member
variables are in scope throughout their class, structure, or module. A variable that is declared at procedure
level is a local variable. Local variables are in scope only within their procedure or block.
The following access modifiers are used to declare variables outside a procedure: Public , Protected ,
Friend , Protected Friend , and Private . For more information, see Access levels in Visual Basic.
The Dimkeyword is optional and usually omitted if you specify any of the following modifiers: Public ,
Protected , Friend , Protected Friend , Private , Shared , Shadows , Static , ReadOnly , or WithEvents .
If Option Explicit is on (the default), the compiler requires a declaration for every variable you use. For
more information, see Option Explicit Statement.
If an initializer is specified and a data type is not specified in an As clause, type inference is used to infer
the data type from the initializer. In the following example, both num1 and num2 are strongly typed as
integers. In the second declaration, type inference infers the type from the value 3.
Type inference applies at the procedure level. It does not apply outside a procedure in a class, structure,
module, or interface. For more information about type inference, see Option Infer Statement and Local
Type Inference.
For information about what happens when a data type or initializer is not specified, see Default Data Types
and Values later in this topic.
You can use an object initializer to declare instances of named and anonymous types. The following code
creates an instance of a Student class and uses an object initializer to initialize properties.
For more information about object initializers, see How to: Declare an Object by Using an Object Initializer,
Object Initializers: Named and Anonymous Types, and Anonymous Types.
Declaring Multiple Variables
You can declare several variables in one declaration statement, specifying the variable name for each one,
and following each array name with parentheses. Multiple variables are separated by commas.
If you declare more than one variable with one As clause, you cannot supply an initializer for that group of
variables.
You can specify different data types for different variables by using a separate As clause for each variable
you declare. Each variable takes the data type specified in the first As clause encountered after its
variablename part.
Arrays
You can declare a variable to hold an array, which can hold multiple values. To specify that a variable holds
an array, follow its variablename immediately with parentheses. For more information about arrays, see
Arrays.
You can specify the lower and upper bound of each dimension of an array. To do this, include a boundslist
inside the parentheses. For each dimension, the boundslist specifies the upper bound and optionally the
lower bound. The lower bound is always zero, whether you specify it or not. Each index can vary from zero
through its upper bound value.
The following two statements are equivalent. Each statement declares an array of 21 Integer elements.
When you access the array, the index can vary from 0 through 20.
The following statement declares a two-dimensional array of type Double . The array has 4 rows (3 + 1) of
6 columns (5 + 1) each. Note that an upper bound represents the highest possible value for the index, not
the length of the dimension. The length of the dimension is the upper bound plus one.
If the array has more than one dimension, you must include commas between the parentheses to indicate
the number of dimensions.
You can declare a zero-length array by declaring one of the array's dimensions to be -1. A variable that
holds a zero-length array does not have the value Nothing . Zero-length arrays are required by certain
common language runtime functions. If you try to access such an array, a runtime exception occurs. For
more information, see Arrays.
You can initialize the values of an array by using an array literal. To do this, surround the initialization
values with braces ( {} ).
For multidimensional arrays, the initialization for each separate dimension is enclosed in braces in the
outer dimension. The elements are specified in row-major order.
If you specify a data type but do not specify an initializer, Visual Basic initializes the variable to the default
value for its data type. The following table shows the default initialization values.
Char Binary 0
Boolean False
Each element of a structure is initialized as if it were a separate variable. If you declare the length of an
array but do not initialize its elements, each element is initialized as if it were a separate variable.
In a module The first time the procedure is called When your program stops execution
In a class or structure, procedure is The first time the procedure is called When your program stops execution
Shared either on a specific instance or on
the class or structure itself
In a class or structure, procedure The first time the procedure is called When the instance is released for
isn't Shared on a specific instance garbage collection (GC)
NOTE
Code outside a class, structure, or module must qualify a member variable's name with the name of that class,
structure, or module. Code outside a procedure or block cannot refer to any local variables within that procedure or
block.
Example
The following example declares variables by using the Dim statement with various options.
Example
The following example lists the prime numbers between 1 and 30. The scope of local variables is described
in code comments.
Public Sub ListPrimes()
' The sb variable can be accessed only
' within the ListPrimes procedure.
Dim sb As New System.Text.StringBuilder()
Debug.WriteLine(sb.ToString)
' Output: 2 3 5 7 11 13 17 19 23 29
End Sub
Return True
End If
End Function
Example
In the following example, the speedValue variable is declared at the class level. The Private keyword is
used to declare the variable. The variable can be accessed by any procedure in the Car class.
Debug.WriteLine(theCar.Speed.ToString)
' Output: 45
Public Class Car
' The speedValue variable can be accessed by
' any procedure in the Car class.
Private speedValue As Integer = 0
See Also
Const Statement
ReDim Statement
Option Explicit Statement
Option Infer Statement
Option Strict Statement
Compile Page, Project Designer (Visual Basic)
Variable Declaration
Arrays
Object Initializers: Named and Anonymous Types
Anonymous Types
Object Initializers: Named and Anonymous Types
How to: Declare an Object by Using an Object Initializer
Local Type Inference
Do...Loop Statement (Visual Basic)
7/29/2017 • 4 min to read • Edit Online
Repeats a block of statements while a Boolean condition is True or until the condition becomes True .
Syntax
Do { While | Until } condition
[ statements ]
[ Continue Do ]
[ statements ]
[ Exit Do ]
[ statements ]
Loop
-or-
Do
[ statements ]
[ Continue Do ]
[ statements ]
[ Exit Do ]
[ statements ]
Loop { While | Until } condition
Parts
TERM DEFINITION
Remarks
Use a Do...Loop structure when you want to repeat a set of statements an indefinite number of times, until a
condition is satisfied. If you want to repeat the statements a set number of times, the For...Next Statement is
usually a better choice.
You can use either While or Until to specify condition , but not both.
You can test condition only one time, at either the start or the end of the loop. If you test condition at the start
of the loop (in the Do statement), the loop might not run even one time. If you test at the end of the loop (in the
Loop statement), the loop always runs at least one time.
The condition usually results from a comparison of two values, but it can be any expression that evaluates to a
Boolean Data Type value ( True or False ). This includes values of other data types, such as numeric types, that
have been converted to Boolean .
You can nest Do loops by putting one loop within another. You can also nest different kinds of control
structures within each other. For more information, see Nested Control Structures.
NOTE
The Do...Loop structure gives you more flexibility than the While...End While Statement because it enables you to decide
whether to end the loop when condition stops being True or when it first becomes True . It also enables you to test
condition at either the start or the end of the loop.
Exit Do
The Exit Do statement can provide an alternative way to exit a Do…Loop . Exit Do transfers control immediately
to the statement that follows the Loop statement.
Exit Do is often used after some condition is evaluated, for example in an If...Then...Else structure. You
might want to exit a loop if you detect a condition that makes it unnecessary or impossible to continue iterating,
such as an erroneous value or a termination request. One use of Exit Do is to test for a condition that could
cause an endless loop, which is a loop that could run a large or even infinite number of times. You can use
Exit Do to escape the loop.
Example
In the following example, the statements in the loop continue to run until the index variable is greater than 10.
The Until clause is at the end of the loop.
Debug.WriteLine("")
' Output: 0 1 2 3 4 5 6 7 8 9 10
Example
The following example uses a While clause instead of an Until clause, and condition is tested at the start of
the loop instead of at the end.
Debug.WriteLine("")
' Output: 0 1 2 3 4 5 6 7 8 9 10
Example
In the following example, condition stops the loop when the index variable is greater than 100. The If
statement in the loop, however, causes the Exit Do statement to stop the loop when the index variable is
greater than 10.
Debug.WriteLine("")
' Output: 0 1 2 3 4 5 6 7 8 9 10
Example
The following example reads all lines in a text file. The OpenText method opens the file and returns a
StreamReader that reads the characters. In the Do...Loop condition, the Peek method of the StreamReader
determines whether there are any additional characters.
sr.Close()
End If
End Sub
See Also
Loop Structures
For...Next Statement
Boolean Data Type
Nested Control Structures
Exit Statement
While...End While Statement
Else Statement (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
Introduces a group of statements to be run or compiled if no other conditional group of statements has been run
or compiled.
Remarks
The Else keyword can be used in these contexts:
If...Then...Else Statement
Select...Case Statement
#If...Then...#Else Directive
See Also
Keywords
End Statement
7/29/2017 • 1 min to read • Edit Online
Syntax
End
Remarks
You can place the End statement anywhere in a procedure to force the entire application to stop running. End
closes any files opened with an Open statement and clears all the application's variables. The application closes as
soon as there are no other programs holding references to its objects and none of its code is running.
NOTE
The End statement stops code execution abruptly, and does not invoke the Dispose or Finalize method, or any other
Visual Basic code. Object references held by other programs are invalidated. If an End statement is encountered within a
Try or Catch block, control does not pass to the corresponding Finally block.
The Stop statement suspends execution, but unlike End , it does not close any files or clear any variables, unless
it is encountered in a compiled executable (.exe) file.
Because End terminates your application without attending to any resources that might be open, you should try
to close down cleanly before using it. For example, if your application has any forms open, you should close them
before control reaches the End statement.
You should use End sparingly, and only when you need to stop immediately. The normal ways to terminate a
procedure (Return Statement and Exit Statement) not only close down the procedure cleanly but also give the
calling code the opportunity to close down cleanly. A console application, for example, can simply Return from
the Main procedure.
IMPORTANT
The End statement calls the Exit method of the Environment class in the System namespace. Exit requires that you have
UnmanagedCode permission. If you do not, a SecurityException error occurs.
When followed by an additional keyword, End <keyword> Statement delineates the end of the definition of the
appropriate procedure or block. For example, End Function terminates the definition of a Function procedure.
Example
The following example uses the End statement to terminate code execution if the user requests it.
Sub Form_Load()
Dim answer As MsgBoxResult
answer = MsgBox("Do you want to quit now?", MsgBoxStyle.YesNo)
If answer = MsgBoxResult.Yes Then
MsgBox("Terminating program")
End
End If
End Sub
See Also
SecurityPermissionFlag
Stop Statement
End <keyword> Statement
End <keyword> Statement (Visual Basic)
7/29/2017 • 2 min to read • Edit Online
When followed by an additional keyword, terminates the definition of the statement block introduced by that
keyword.
Syntax
End AddHandler
End Class
End Enum
End Event
End Function
End Get
End If
End Interface
End Module
End Namespace
End Operator
End Property
End RaiseEvent
End RemoveHandler
End Select
End Set
End Structure
End Sub
End SyncLock
End Try
End While
End With
Parts
End
Required. Terminates the definition of the programming element.
AddHandler
Required to terminate an AddHandler accessor begun by a matching AddHandler statement in a custom Event
Statement.
Class
Required to terminate a class definition begun by a matching Class Statement.
Enum
Required to terminate an enumeration definition begun by a matching Enum Statement.
Event
Required to terminate a Custom event definition begun by a matching Event Statement.
Function
Required to terminate a Function procedure definition begun by a matching Function Statement. If execution
encounters an End``Function statement, control returns to the calling code.
Get
Required to terminate a Property procedure definition begun by a matching Get Statement. If execution
encounters an End``Get statement, control returns to the statement requesting the property's value.
If
Required to terminate an If ... Then ... Else block definition begun by a matching If statement. See
If...Then...Else Statement.
Interface
Required to terminate an interface definition begun by a matching Interface Statement.
Module
Required to terminate a module definition begun by a matching Module Statement.
Namespace
Required to terminate a namespace definition begun by a matching Namespace Statement.
Operator
Required to terminate an operator definition begun by a matching Operator Statement.
Property
Required to terminate a property definition begun by a matching Property Statement.
RaiseEvent
Required to terminate a RaiseEvent accessor begun by a matching RaiseEvent statement in a custom Event
Statement.
RemoveHandler
Required to terminate a RemoveHandler accessor begun by a matching RemoveHandler statement in a custom
Event Statement.
Select
Required to terminate a Select ... Case block definition begun by a matching Select statement. See Select...Case
Statement.
Set
Required to terminate a Property procedure definition begun by a matching Set Statement. If execution
encounters an End``Set statement, control returns to the statement setting the property's value.
Structure
Required to terminate a structure definition begun by a matching Structure Statement.
Sub
Required to terminate a Sub procedure definition begun by a matching Sub Statement. If execution encounters
an End``Sub statement, control returns to the calling code.
SyncLock
Required to terminate a SyncLock block definition begun by a matching SyncLock statement. See SyncLock
Statement.
Try
Required to terminate a Try ... Catch ... Finally block definition begun by a matching Try statement. See
Try...Catch...Finally Statement.
While
Required to terminate a While loop definition begun by a matching While statement. See While...End While
Statement.
With
Required to terminate a With block definition begun by a matching With statement. See With...End With
Statement.
Remarks
The End Statement, without an additional keyword, terminates execution immediately.
When preceded by a number sign ( # ), the End keyword terminates a preprocessing block introduced by the
corresponding directive.
#End
Required. Terminates the definition of the preprocessing block.
#ExternalSource
Required to terminate an external source block begun by a matching #ExternalSource Directive.
#If
Required to terminate a conditional compilation block begun by a matching #If directive. See #If...Then...#Else
Directives.
#Region
Required to terminate a source region block begun by a matching #Region Directive.
See Also
End Statement
Enum Statement (Visual Basic)
7/29/2017 • 7 min to read • Edit Online
Syntax
[ <attributelist> ] [ accessmodifier ] [ Shadows ]
Enum enumerationname [ As datatype ]
memberlist
End Enum
Parts
attributelist
Optional. List of attributes that apply to this enumeration. You must enclose the attribute list in angle
brackets (" < " and " > ").
The FlagsAttribute attribute indicates that the value of an instance of the enumeration can include
multiple enumeration members, and that each member represents a bit field in the enumeration value.
accessmodifier
Optional. Specifies what code can access this enumeration. Can be one of the following:
Public
Protected
Friend
Private
You can specify Protected``Friend to allow access from code within the enumeration's class, a derived
class, or the same assembly.
Shadows
Optional. Specifies that this enumeration redeclares and hides an identically named programming
element, or set of overloaded elements, in a base class. You can specify Shadows only on the
enumeration itself, not on any of its members.
enumerationname
Required. Name of the enumeration. For information on valid names, see Declared Element Names.
datatype
Required. List of member constants being declared in this statement. Multiple members appear on
individual source code lines.
Each member has the following syntax and parts: [<attribute list>] member name [ = initializer ]
PART DESCRIPTION
End Enum
Remarks
If you have a set of unchanging values that are logically related to each other, you can define them together in
an enumeration. This provides meaningful names for the enumeration and its members, which are easier to
remember than their values. You can then use the enumeration members in many places in your code.
The benefits of using enumerations include the following:
Reduces errors caused by transposing or mistyping numbers.
Makes it easy to change values in the future.
Makes code easier to read, which means it is less likely that errors will be introduced.
Ensures forward compatibility. If you use enumerations, your code is less likely to fail if in the future
someone changes the values corresponding to the member names.
An enumeration has a name, an underlying data type, and a set of members. Each member represents a
constant.
An enumeration declared at class, structure, module, or interface level, outside any procedure, is a member
enumeration. It is a member of the class, structure, module, or interface that declares it.
Member enumerations can be accessed from anywhere within their class, structure, module, or interface. Code
outside a class, structure, or module must qualify a member enumeration's name with the name of that class,
structure, or module. You can avoid the need to use fully qualified names by adding an Imports statement to
the source file.
An enumeration declared at namespace level, outside any class, structure, module, or interface, is a member of
the namespace in which it appears.
The declaration context for an enumeration must be a source file, namespace, class, structure, module, or
interface, and cannot be a procedure. For more information, see Declaration Contexts and Default Access
Levels.
You can apply attributes to an enumeration as a whole, but not to its members individually. An attribute
contributes information to the assembly's metadata.
Data Type
The Enum statement can declare the data type of an enumeration. Each member takes the enumeration's data
type. You can specify Byte , Integer , Long , SByte , Short , UInteger , ULong , or UShort .
If you do not specify datatype for the enumeration, each member takes the data type of its initializer . If you
specify both datatype and initializer , the data type of initializer must be convertible to datatype . If
neither datatype nor initializer is present, the data type defaults to Integer .
Initializing Members
The Enum statement can initialize the contents of selected members in memberlist . You use initializer to
supply an expression to be assigned to the member.
If you do not specify initializer for a member, Visual Basic initializes it either to zero (if it is the first member
in memberlist ), or to a value greater by one than that of the immediately preceding member .
The expression supplied in each initializer can be any combination of literals, other constants that are
already defined, and enumeration members that are already defined, including a previous member of this
enumeration. You can use arithmetic and logical operators to combine such elements.
You cannot use variables or functions in initializer . However, you can use conversion keywords such as
CByte and CShort . You can also use AscW if you call it with a constant String or Char argument, since that
can be evaluated at compile time.
Enumerations cannot have floating-point values. If a member is assigned a floating-point value and
Option Strict is set to on, a compiler error occurs. If Option Strict is off, the value is automatically converted
to the Enum type.
If the value of a member exceeds the allowable range for the underlying data type, or if you initialize any
member to the maximum value allowed by the underlying data type, the compiler reports an error.
Modifiers
Class, structure, module, and interface member enumerations default to public access. You can adjust their
access levels with the access modifiers. Namespace member enumerations default to friend access. You can
adjust their access levels to public, but not to private or protected. For more information, see Access levels in
Visual Basic.
All enumeration members have public access, and you cannot use any access modifiers on them. However, if
the enumeration itself has a more restricted access level, the specified enumeration access level takes
precedence.
By default, all enumerations are types and their fields are constants. Therefore the Shared , Static , and
ReadOnly keywords cannot be used when declaring an enumeration or its members.
Example
The following example shows how to use the Enum statement. Note that the member is referred to as
EggSizeEnum.Medium , and not as Medium .
Public Class Egg
Enum EggSizeEnum
Jumbo
ExtraLarge
Large
Medium
Small
End Enum
size = EggSizeEnum.Medium
' Continue processing...
End Sub
End Class
Example
The method in the following example is outside the Egg class. Therefore, EggSizeEnum is fully qualified as
Egg.EggSizeEnum .
Example
The following example uses the Enum statement to define a related set of named constant values. In this case,
the values are colors you might choose to design data entry forms for a database.
Example
The following example shows values that include both positive and negative numbers.
Enum SecurityLevel
IllegalEntry = -1
MinimumSecurity = 0
MaximumSecurity = 1
End Enum
Example
In the following example, an As clause is used to specify the datatype of an enumeration.
Example
The following example shows how to use a bitwise enumeration. Multiple values can be assigned to an instance
of a bitwise enumeration. The Enum declaration includes the FlagsAttribute attribute, which indicates that the
enumeration can be treated as a set of flags.
Example
The following example iterates through an enumeration. It uses the GetNames method to retrieve an array of
member names from the enumeration, and GetValues to retrieve an array of member values.
Enum EggSizeEnum
Jumbo
ExtraLarge
Large
Medium
Small
End Enum
See Also
Enum
AscW
Const Statement
Dim Statement
Implicit and Explicit Conversions
Type Conversion Functions
Constants and Enumerations
Erase Statement (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
Used to release array variables and deallocate the memory used for their elements.
Syntax
Erase arraylist
Parts
arraylist
Required. List of array variables to be erased. Multiple variables are separated by commas.
Remarks
The Erase statement can appear only at procedure level. This means you can release arrays inside a procedure
but not at class or module level.
The Erase statement is equivalent to assigning Nothing to each array variable.
Example
The following example uses the Erase statement to clear two arrays and free their memory (1000 and 100
storage elements, respectively). The ReDim statement then assigns a new array instance to the three-dimensional
array.
See Also
Nothing
ReDim Statement
Error Statement
7/29/2017 • 1 min to read • Edit Online
Syntax
Error errornumber
Parts
errornumber
Required. Can be any valid error number.
Remarks
The Error statement is supported for backward compatibility. In new code, especially when creating objects, use
the Err object's Raise method to generate run-time errors.
If errornumber is defined, the Error statement calls the error handler after the properties of the Err object are
assigned the following default values:
PROPERTY VALUE
HelpFile The fully qualified drive, path, and file name of the appropriate
Visual Basic Help file.
HelpContext The appropriate Visual Basic Help file context ID for the error
corresponding to the Number property.
LastDLLError Zero.
If no error handler exists, or if none is enabled, an error message is created and displayed from the Err object
properties.
NOTE
Some Visual Basic host applications cannot create objects. See your host application's documentation to determine whether
it can create classes and objects.
Example
This example uses the Error statement to generate error number 11.
Requirements
Namespace: Microsoft.VisualBasic
Assembly: Visual Basic Runtime Library (in Microsoft.VisualBasic.dll)
See Also
Clear
Err
Raise
On Error Statement
Resume Statement
Error Messages
Event Statement
7/29/2017 • 6 min to read • Edit Online
Syntax
[ <attrlist> ] [ accessmodifier ] _
[ Shared ] [ Shadows ] Event eventname[(parameterlist)] _
[ Implements implementslist ]
' -or-
[ <attrlist> ] [ accessmodifier ] _
[ Shared ] [ Shadows ] Event eventname As delegatename _
[ Implements implementslist ]
' -or-
[ <attrlist> ] [ accessmodifier ] _
[ Shared ] [ Shadows ] Custom Event eventname As delegatename _
[ Implements implementslist ]
[ <attrlist> ] AddHandler(ByVal value As delegatename)
[ statements ]
End AddHandler
[ <attrlist> ] RemoveHandler(ByVal value As delegatename)
[ statements ]
End RemoveHandler
[ <attrlist> ] RaiseEvent(delegatesignature)
[ statements ]
End RaiseEvent
End Event
Parts
PART DESCRIPTION
accessmodifier Optional. Specifies what code can access the event. Can be
one of the following:
interface . definedname
Remarks
Once the event has been declared, use the RaiseEvent statement to raise the event. A typical event might be
declared and raised as shown in the following fragments:
NOTE
You can declare event arguments just as you do arguments of procedures, with the following exceptions: events
cannot have named arguments, ParamArray arguments, or Optional arguments. Events do not have return
values.
To handle an event, you must associate it with an event handler subroutine using either the Handles or
AddHandler statement. The signatures of the subroutine and the event must match. To handle a shared
event, you must use the AddHandler statement.
You can use Event only at module level. This means the declaration context for an event must be a class,
structure, module, or interface, and cannot be a source file, namespace, procedure, or block. For more
information, see Declaration Contexts and Default Access Levels.
In most circumstances, you can use the first syntax in the Syntax section of this topic for declaring events.
However, some scenarios require that you have more control over the detailed behavior of the event. The
last syntax in the Syntax section of this topic, which uses the Custom keyword, provides that control by
enabling you to define custom events. In a custom event, you specify exactly what occurs when code adds or
removes an event handler to or from the event, or when code raises the event. For examples, see How to:
Declare Custom Events To Conserve Memory and How to: Declare Custom Events To Avoid Blocking.
Example
The following example uses events to count down seconds from 10 to 0. The code illustrates several of the
event-related methods, properties, and statements. This includes the RaiseEvent statement.
The class that raises an event is the event source, and the methods that process the event are the event
handlers. An event source can have multiple handlers for the events it generates. When the class raises the
event, that event is raised on every class that has elected to handle events for that instance of the object.
The example also uses a form ( Form1 ) with a button ( Button1 ) and a text box ( TextBox1 ). When you click
the button, the first text box displays a countdown from 10 to 0 seconds. When the full time (10 seconds)
has elapsed, the first text box displays "Done".
The code for Form1 specifies the initial and terminal states of the form. It also contains the code executed
when events are raised.
To use this example, open a new Windows Forms project. Then add a button named Button1 and a text box
named TextBox1 to the main form, named Form1 . Then right-click the form and click View Code to open
the code editor.
Add a WithEvents variable to the declarations section of the Form1 class:
Add the following code to the code for Form1 . Replace any duplicate procedures that may exist, such as
Form_Load or Button_Click .
Private Sub Form1_Load() Handles MyBase.Load
Button1.Text = "Start"
mText = New TimerState
End Sub
Private Sub Button1_Click() Handles Button1.Click
mText.StartCountdown(10.0, 0.1)
End Sub
Class TimerState
Public Event UpdateTime(ByVal Countdown As Double)
Public Event Finished()
Public Sub StartCountdown(ByVal Duration As Double,
ByVal Increment As Double)
Dim Start As Double = DateAndTime.Timer
Dim ElapsedTime As Double = 0
Press F5 to run the previous example, and click the button labeled Start. The first text box starts to count
down the seconds. When the full time (10 seconds) has elapsed, the first text box displays "Done".
NOTE
The My.Application.DoEvents method does not process events in the same way the form does. To enable the form
to handle the events directly, you can use multithreading. For more information, see Threading.
See Also
RaiseEvent Statement
Implements Statement
Events
AddHandler Statement
RemoveHandler Statement
Handles
Delegate Statement
How to: Declare Custom Events To Conserve Memory
How to: Declare Custom Events To Avoid Blocking
Shared
Shadows
Exit Statement (Visual Basic)
7/29/2017 • 3 min to read • Edit Online
Exits a procedure or block and transfers control immediately to the statement following the procedure call or the
block definition.
Syntax
Exit { Do | For | Function | Property | Select | Sub | Try | While }
Statements
Exit Do
Immediately exits the Do loop in which it appears. Execution continues with the statement following the Loop
statement. Exit Do can be used only inside a Do loop. When used within nested Do loops, Exit Do exits the
innermost loop and transfers control to the next higher level of nesting.
Exit For
Immediately exits the For loop in which it appears. Execution continues with the statement following the Next
statement. Exit For can be used only inside a For ... Next or For Each ... Next loop. When used within nested
For loops, Exit For exits the innermost loop and transfers control to the next higher level of nesting.
Exit Function
Immediately exits the Function procedure in which it appears. Execution continues with the statement following
the statement that called the Function procedure. Exit Function can be used only inside a Function
procedure.
To specify a return value, you can assign the value to the function name on a line before the Exit Function
statement. To assign the return value and exit the function in one statement, you can instead use the Return
Statement.
Exit Property
Immediately exits the Property procedure in which it appears. Execution continues with the statement that
called the Property procedure, that is, with the statement requesting or setting the property's value.
Exit Property can be used only inside a property's Get or Set procedure.
To specify a return value in a Get procedure, you can assign the value to the function name on a line before the
Exit Property statement. To assign the return value and exit the Get procedure in one statement, you can
instead use the Return statement.
In a Set procedure, the Exit Property statement is equivalent to the Return statement.
Exit Select
Immediately exits the Select Case block in which it appears. Execution continues with the statement following
the End Select statement. Exit Select can be used only inside a Select Case statement.
Exit Sub
Immediately exits the Sub procedure in which it appears. Execution continues with the statement following the
statement that called the Sub procedure. Exit Sub can be used only inside a Sub procedure.
In a Sub procedure, the Exit Sub statement is equivalent to the Return statement.
Exit Try
Immediately exits the Try or Catch block in which it appears. Execution continues with the Finally block if
there is one, or with the statement following the End Try statement otherwise. Exit Try can be used only
inside a Try or Catch block, and not inside a Finally block.
Exit While
Immediately exits the While loop in which it appears. Execution continues with the statement following the
End While statement. Exit While can be used only inside a While loop. When used within nested While
loops, Exit While transfers control to the loop that is one nested level above the loop where Exit While
occurs.
Remarks
Do not confuse Exit statements with End statements. Exit does not define the end of a statement.
Example
In the following example, the loop condition stops the loop when the index variable is greater than 100. The
If statement in the loop, however, causes the Exit Do statement to stop the loop when the index variable is
greater than 10.
Debug.WriteLine("")
' Output: 0 1 2 3 4 5 6 7 8 9 10
Example
The following example assigns the return value to the function name myFunction , and then uses Exit Function
to return from the function.
Example
The following example uses the Return Statement to assign the return value and exit the function.
See Also
A-E Statements
Q-Z Statements
Visual Basic Language Reference
For Each...Next Statement (Visual Basic)
7/29/2017 • 12 min to read • Edit Online
Syntax
For Each element [ As datatype ] In group
[ statements ]
[ Continue For ]
[ statements ]
[ Exit For ]
[ statements ]
Next [ element ]
Parts
TERM DEFINITION
Continue For Optional. Transfers control to the start of the For Each
loop.
Exit For Optional. Transfers control out of the For Each loop.
Simple Example
Use a For Each ... Next loop when you want to repeat a set of statements for each element of a collection or
array.
TIP
A For...Next Statement works well when you can associate each iteration of a loop with a control variable and determine
that variable's initial and final values. However, when you are dealing with a collection, the concept of initial and final
values isn't meaningful, and you don't necessarily know how many elements the collection has. In this kind of case, a
For Each ... Next loop is often a better choice.
In the following example, the For Each … Next statement iterates through all the elements of a List collection.
Nested Loops
You can nest For Each loops by putting one loop within another.
The following example demonstrates nested For Each … Next structures.
When you nest loops, each loop must have a unique element variable.
You can also nest different kinds of control structures within each other. For more information, see Nested
Control Structures.
You can put any number of Exit For statements in a For Each loop. When used within nested For Each
loops, Exit For causes execution to exit the innermost loop and transfers control to the next higher level of
nesting.
Exit For is often used after an evaluation of some condition, for example, in an If ... Then ... Else structure.
You might want to use Exit For for the following conditions:
Continuing to iterate is unnecessary or impossible. This might be caused by an erroneous value or a
termination request.
An exception is caught in a Try ... Catch ... Finally . You might use Exit For at the end of the Finally
block.
There an endless loop, which is a loop that could run a large or even infinite number of times. If you
detect such a condition, you can use Exit For to escape the loop. For more information, see Do...Loop
Statement.
Iterators
You use an iterator to perform a custom iteration over a collection. An iterator can be a function or a Get
accessor. It uses a Yield statement to return each element of the collection one at a time.
You call an iterator by using a For Each...Next statement. Each iteration of the For Each loop calls the
iterator. When a Yield statement is reached in the iterator, the expression in the Yield statement is
returned, and the current location in code is retained. Execution is restarted from that location the next time
that the iterator is called.
The following example uses an iterator function. The iterator function has a Yield statement that's inside a
For…Next loop. In the ListEvenNumbers method, each iteration of the For Each statement body creates a call
to the iterator function, which proceeds to the next Yield statement.
Public Sub ListEvenNumbers()
For Each number As Integer In EvenSequence(5, 18)
Debug.Write(number & " ")
Next
Debug.WriteLine("")
' Output: 6 8 10 12 14 16 18
End Sub
Technical Implementation
When a For Each … Next statement runs, Visual Basic evaluates the collection only one time, before the loop
starts. If your statement block changes element or group , these changes don't affect the iteration of the loop.
When all the elements in the collection have been successively assigned to element , the For Each loop stops
and control passes to the statement following the Next statement.
If element hasn't been declared outside this loop, you must declare it in the For Each statement. You can
declare the type of element explicitly by using an As statement, or you can rely on type inference to assign
the type. In either case, the scope of element is the body of the loop. However, you cannot declare element
both outside and inside the loop.
You can optionally specify element in the Next statement. This improves the readability of your program,
especially if you have nested For Each loops. You must specify the same variable as the one that appears in
the corresponding For Each statement.
You might want to avoid changing the value of element inside a loop. Doing this can make it more difficult to
read and debug your code. Changing the value of group doesn't affect the collection or its elements, which
were determined when the loop was first entered.
When you're nesting loops, if a Next statement of an outer nesting level is encountered before the Next of
an inner level, the compiler signals an error. However, the compiler can detect this overlapping error only if
you specify element in every Next statement.
If your code depends on traversing a collection in a particular order, a For Each ... Next loop isn't the best
choice, unless you know the characteristics of the enumerator object the collection exposes. The order of
traversal isn't determined by Visual Basic, but by the MoveNext method of the enumerator object. Therefore,
you might not be able to predict which element of the collection is the first to be returned in element , or
which is the next to be returned after a given element. You might achieve more reliable results using a
different loop structure, such as For ... Next or Do ... Loop .
The data type of element must be such that the data type of the elements of group can be converted to it.
The data type of group must be a reference type that refers to a collection or an array that's enumerable.
Most commonly this means that group refers to an object that implements the IEnumerable interface of the
System.Collections namespace or the IEnumerable<T> interface of the System.Collections.Generic
namespace. System.Collections.IEnumerable defines the GetEnumerator method, which returns an
enumerator object for the collection. The enumerator object implements the System.Collections.IEnumerator
interface of the System.Collections namespace and exposes the Current property and the Reset and
MoveNext methods. Visual Basic uses these to traverse the collection.
Narrowing Conversions
When Option Strict is set to On , narrowing conversions ordinarily cause compiler errors. In a For Each
statement, however, conversions from the elements in group to element are evaluated and performed at run
time, and compiler errors caused by narrowing conversions are suppressed.
In the following example, the assignment of m as the initial value for n doesn't compile when
Option Strict is on because the conversion of a Long to an Integer is a narrowing conversion. In the
For Each statement, however, no compiler error is reported, even though the assignment to number requires
the same conversion from Long to Integer . In the For Each statement that contains a large number, a run-
time error occurs when ToInteger is applied to the large number.
Option Strict On
Module Module1
Sub Main()
' The assignment of m to n causes a compiler error when
' Option Strict is on.
Dim m As Long = 987
'Dim n As Integer = m
' The For Each loop requires the same conversion but
' causes no errors, even when Option Strict is on.
For Each number As Integer In New Long() {45, 3, 987}
Console.Write(number & " ")
Next
Console.WriteLine()
' Output: 45 3 987
Console.ReadKey()
End Sub
End Module
IEnumerator Calls
When execution of a For Each ... Next loop starts, Visual Basic verifies that group refers to a valid collection
object. If not, it throws an exception. Otherwise, it calls the MoveNext method and the Current property of the
enumerator object to return the first element. If MoveNext indicates that there is no next element, that is, if the
collection is empty, the For Each loop stops and control passes to the statement following the Next
statement. Otherwise, Visual Basic sets element to the first element and runs the statement block.
Each time Visual Basic encounters the Next statement, it returns to the For Each statement. Again it calls
MoveNext and Current to return the next element, and again it either runs the block or stops the loop
depending on the result. This process continues until MoveNext indicates that there is no next element or an
Exit For statement is encountered.
Modifying the Collection. The enumerator object returned by GetEnumerator normally doesn't let you
change the collection by adding, deleting, replacing, or reordering any elements. If you change the collection
after you have initiated a For Each ... Next loop, the enumerator object becomes invalid, and the next attempt
to access an element causes an InvalidOperationException exception.
However, this blocking of modification isn't determined by Visual Basic, but rather by the implementation of
the IEnumerable interface. It is possible to implement IEnumerable in a way that allows for modification
during iteration. If you are considering doing such dynamic modification, make sure that you understand the
characteristics of the IEnumerable implementation on the collection you are using.
Modifying Collection Elements. The Current property of the enumerator object is ReadOnly, and it returns
a local copy of each collection element. This means that you cannot modify the elements themselves in a
For Each ... Next loop. Any modification you make affects only the local copy from Current and isn't reflected
back into the underlying collection. However, if an element is a reference type, you can modify the members
of the instance to which it points. The following example modifies the BackColor member of each
thisControl element. You cannot, however, modify thisControl itself.
The previous example can modify the BackColor member of each thisControl element, although it cannot
modify thisControl itself.
Traversing Arrays. Because the Array class implements the IEnumerable interface, all arrays expose the
GetEnumerator method. This means that you can iterate through an array with a For Each ... Next loop.
However, you can only read the array elements. You cannot change them.
Example
The following example lists all the folders in the C:\ directory by using the DirectoryInfo class.
Example
The following example illustrates a procedure for sorting a collection. The example sorts instances of a Car
class that are stored in a List<T>. The Car class implements the IComparable<T> interface, which requires
that the CompareTo method be implemented.
Each call to the CompareTo method makes a single comparison that's used for sorting. User-written code in
the CompareTo method returns a value for each comparison of the current object with another object. The
value returned is less than zero if the current object is less than the other object, greater than zero if the
current object is greater than the other object, and zero if they are equal. This enables you to define in code
the criteria for greater than, less than, and equal.
In the ListCars method, the cars.Sort() statement sorts the list. This call to the Sort method of the List<T>
causes the CompareTo method to be called automatically for the Car objects in the List .
' Output:
' blue 50 car4
' blue 30 car5
' blue 20 car1
' green 50 car7
' green 10 car3
' red 60 car6
' red 50 car2
End Sub
Return compare
End Function
End Class
See Also
Collections
For...Next Statement
Loop Structures
While...End While Statement
Do...Loop Statement
Widening and Narrowing Conversions
Object Initializers: Named and Anonymous Types
Collection Initializers
Arrays
For...Next Statement (Visual Basic)
7/29/2017 • 9 min to read • Edit Online
Syntax
For counter [ As datatype ] = start To end [ Step step ]
[ statements ]
[ Continue For ]
[ statements ]
[ Exit For ]
[ statements ]
Next [ counter ]
Parts
PART DESCRIPTION
NOTE
The To keyword is used in this statement to specify the range for the counter. You can also use this keyword in the
Select...Case Statement and in array declarations. For more information about array declarations, see Dim Statement.
Simple Examples
You use a For ... Next structure when you want to repeat a set of statements a set number of times.
In the following example, the index variable starts with a value of 1 and is incremented with each iteration of
the loop, ending after the value of index reaches 5.
In the following example, the number variable starts at 2 and is reduced by 0.25 on each iteration of the loop,
ending after the value of number reaches 0. The Step argument of -.25 reduces the value by 0.25 on each
iteration of the loop.
TIP
A While...End While Statement or Do...Loop Statement works well when you don't know in advance how many times to
run the statements in the loop. However, when you expect to run the loop a specific number of times, a For ... Next
loop is a better choice. You determine the number of iterations when you first enter the loop.
Nesting Loops
You can nest For loops by putting one loop within another. The following example demonstrates nested
For ... Next structures that have different step values. The outer loop creates a string for every iteration of the
loop. The inner loop decrements a loop counter variable for every iteration of the loop.
For indexA = 1 To 3
' Create a new StringBuilder, which is used
' to efficiently build strings.
Dim sb As New System.Text.StringBuilder()
When nesting loops, each loop must have a unique counter variable.
You can also nest different kinds control structures within each other. For more information, see Nested
Control Structures.
You can put any number of Exit For statements in a For … Next loop. When used within nested For …
Next loops, Exit For exits the innermost loop and transfers control to the next higher level of nesting.
Exit For is often used after you evaluate some condition (for example, in an If ... Then ... Else structure).
You might want to use Exit For for the following conditions:
Continuing to iterate is unnecessary or impossible. An erroneous value or a termination request might
create this condition.
A Try... Catch ... Finally statement catches an exception. You might use Exit For at the end of the
Finally block.
You have an endless loop, which is a loop that could run a large or even infinite number of times. If you
detect such a condition, you can use Exit For to escape the loop. For more information, see Do...Loop
Statement.
Technical Implementation
When a For ... Next loop starts, Visual Basic evaluates start , end , and step . Visual Basic evaluates these
values only at this time and then assigns start to counter . Before the statement block runs, Visual Basic
compares counter to end . If counter is already larger than the end value (or smaller if step is negative),
the For loop ends and control passes to the statement that follows the Next statement. Otherwise, the
statement block runs.
Each time Visual Basic encounters the Next statement, it increments counter by step and returns to the
For statement. Again it compares counter to end , and again it either runs the block or exits the loop,
depending on the result. This process continues until counter passes end or an Exit For statement is
encountered.
The loop doesn't stop until counter has passed end . If counter is equal to end, the loop continues. The
comparison that determines whether to run the block is counter <= end if step is positive and counter
>= end if step is negative.
If you change the value of counter while inside a loop, your code might be more difficult to read and debug.
Changing the value of start , end , or step doesn't affect the iteration values that were determined when
the loop was first entered.
If you nest loops, the compiler signals an error if it encounters the Next statement of an outer nesting level
before the Next statement of an inner level. However, the compiler can detect this overlapping error only if
you specify counter in every Next statement.
Step Argument
The value of step can be either positive or negative. This parameter determines loop processing according to
the following table:
Yes No Yes.
The data type of counter determines the type of the iteration, which must be one of the following types:
A Byte , SByte , UShort , Short , UInteger , Integer , ULong , Long , Decimal , Single , or Double .
An enumeration that you declare by using an Enum Statement.
An Object .
A type T that has the following operators, where B is a type that can be used in a Boolean
expression.
Public Shared Operator >= (op1 As T, op2 As T) As B
You can optionally specify the counter variable in the Next statement. This syntax improves the readability
of your program, especially if you have nested For loops. You must specify the variable that appears in the
corresponding For statement.
The start , end , and step expressions can evaluate to any data type that widens to the type of counter . If
you use a user-defined type for counter , you might have to define the CType conversion operator to convert
the types of start , end , or step to the type of counter .
Example
The following example removes all elements from a generic list. Instead of a For Each...Next Statement, the
example shows a For ... Next statement that iterates in descending order. The example uses this technique
because the removeAt method causes elements after the removed element to have a lower index value.
Dim lst As New List(Of Integer) From {10, 20, 30, 40}
Debug.WriteLine(lst.Count.ToString)
' Output: 0
Example
The following example iterates through an enumeration that's declared by using an Enum Statement.
Public Enum Mammals
Buffalo
Gazelle
Mongoose
Rhinoceros
Whale
End Enum
Example
In the following example, the statement parameters use a class that has operator overloads for the + , - , >=
, and <= operators.
Public Shared Operator -(ByVal op1 As Distance, ByVal op2 As Distance) As Distance
Return New Distance(op1.Number - op2.Number)
End Operator
Public Shared Operator >=(ByVal op1 As Distance, ByVal op2 As Distance) As Boolean
Return (op1.Number >= op2.Number)
End Operator
Public Shared Operator <=(ByVal op1 As Distance, ByVal op2 As Distance) As Boolean
Return (op1.Number <= op2.Number)
End Operator
End Class
' Output: 10 14 18 22
End Sub
See Also
List<T>
Loop Structures
While...End While Statement
Do...Loop Statement
Nested Control Structures
Exit Statement
Collections
Function Statement (Visual Basic)
7/29/2017 • 8 min to read • Edit Online
Declares the name, parameters, and code that define a Function procedure.
Syntax
[ <attributelist> ] [ accessmodifier ] [ proceduremodifiers ] [ Shared ] [ Shadows ] [ Async |
Iterator ]
Function name [ (Of typeparamlist) ] [ (parameterlist) ] [ As returntype ] [ Implements
implementslist | Handles eventlist ]
[ statements ]
[ Exit Function ]
[ statements ]
End Function
Parts
attributelist
NotOverridable Overrides
Shared
Optional. See Shared.
Shadows
Optional. List of type parameters for a generic procedure. See Type List.
parameterlist
Optional. List of local variable names representing the parameters of this procedure. See
Parameter List.
returntype
Required if Option Strict is On . Data type of the value returned by this procedure.
Implements
Optional. Indicates that this procedure implements one or more Function procedures, each one
defined in an interface implemented by this procedure's containing class or structure. See
Implements Statement.
implementslist
PART DESCRIPTION
Handles
Optional. Indicates that this procedure can handle one or more specific events. See Handles.
eventlist
PART DESCRIPTION
statements
Remarks
All executable code must be inside a procedure. Each procedure, in turn, is declared within a class, a
structure, or a module that is referred to as the containing class, structure, or module.
To return a value to the calling code, use a Function procedure; otherwise, use a Sub procedure.
Defining a Function
You can define a Function procedure only at the module level. Therefore, the declaration context for a
function must be a class, a structure, a module, or an interface and can't be a source file, a namespace, a
procedure, or a block. For more information, see Declaration Contexts and Default Access Levels.
Function procedures default to public access. You can adjust their access levels with the access
modifiers.
A Function procedure can declare the data type of the value that the procedure returns. You can specify
any data type or the name of an enumeration, a structure, a class, or an interface. If you don't specify the
returntype parameter, the procedure returns Object .
If this procedure uses the Implements keyword, the containing class or structure must also have an
Implements statement that immediately follows its Class or Structure statement. The Implements
statement must include each interface that's specified in implementslist . However, the name by which
an interface defines the Function (in definedname ) doesn't need to match the name of this procedure
(in name ).
NOTE
You can use lambda expressions to define function expressions inline. For more information, see Function
Expression and Lambda Expressions.
The Return statement simultaneously assigns the return value and exits the function, as the following
example shows.
The following example assigns the return value to the function name myFunction and then uses the
Exit Function statement to return.
The Exit Function and Return statements cause an immediate exit from a Function procedure. Any
number of Exit Function and Return statements can appear anywhere in the procedure, and you can
mix Exit Function and Return statements.
If you use Exit Function without assigning a value to name , the procedure returns the default value for
the data type that's specified in returntype . If returntype isn't specified, the procedure returns
Nothing , which is the default value for Object .
Calling a Function
You call a Function procedure by using the procedure name, followed by the argument list in
parentheses, in an expression. You can omit the parentheses only if you aren't supplying any arguments.
However, your code is more readable if you always include the parentheses.
You call a Function procedure the same way that you call any library function such as Sqrt , Cos , or
ChrW .
You can also call a function by using the Call keyword. In that case, the return value is ignored. Use of
the Call keyword isn't recommended in most cases. For more information, see Call Statement.
Visual Basic sometimes rearranges arithmetic expressions to increase internal efficiency. For that reason,
you shouldn't use a Function procedure in an arithmetic expression when the function changes the
value of variables in the same expression.
Async Functions
The Async feature allows you to invoke asynchronous functions without using explicit callbacks or
manually splitting your code across multiple functions or lambda expressions.
If you mark a function with the Async modifier, you can use the Await operator in the function. When
control reaches an Await expression in the Async function, control returns to the caller, and progress in
the function is suspended until the awaited task completes. When the task is complete, execution can
resume in the function.
NOTE
An Async procedure returns to the caller when either it encounters the first awaited object that’s not yet
complete, or it gets to the end of the Async procedure, whichever occurs first.
An Async function can have a return type of Task<TResult> or Task. An example of an Async function
that has a return type of Task<TResult> is provided below.
An Async function cannot declare any ByRef parameters.
A Sub Statement can also be marked with the Async modifier. This is primarily used for event handlers,
where a value cannot be returned. An Async``Sub procedure can't be awaited, and the caller of an
Async``Sub procedure can't catch exceptions that are thrown by the Sub procedure.
For more information about Async functions, see Asynchronous Programming with Async and Await,
Control Flow in Async Programs, and Async Return Types.
Iterator Functions
An iterator function performs a custom iteration over a collection, such as a list or array. An iterator
function uses the Yield statement to return each element one at a time. When a Yield statement is
reached, the current location in code is remembered. Execution is restarted from that location the next
time the iterator function is called.
You call an iterator from client code by using a For Each…Next statement.
The return type of an iterator function can be IEnumerable, IEnumerable<T>, IEnumerator, or
IEnumerator<T>.
For more information, see Iterators.
Example
The following example uses the Function statement to declare the name, parameters, and code that
form the body of a Function procedure. The ParamArray modifier enables the function to accept a
variable number of arguments.
Example
The following example invokes the function declared in the preceding example.
Module Module1
Sub Main()
' In the following function call, calcSum's local variables
' are assigned the following values: args(0) = 4, args(1) = 3,
' and so on. The displayed sum is 10.
Dim returnedValue As Double = calcSum(4, 3, 2, 1)
Console.WriteLine("Sum: " & returnedValue)
' Parameter args accepts zero or more arguments. The sum
' displayed by the following statements is 0.
returnedValue = calcSum()
Console.WriteLine("Sum: " & returnedValue)
End Sub
End Module
Example
In the following example, DelayAsync is an Async``Function that has a return type of Task<TResult>.
DelayAsync has a Return statement that returns an integer. Therefore the function declaration of
DelayAsync needs to have a return type of Task(Of Integer) . Because the return type is
Task(Of Integer) , the evaluation of the Await expression in DoSomethingAsync produces an integer.
This is demonstrated in this statement: Dim result As Integer = Await delayTask .
The startButton_Click procedure is an example of an Async Sub procedure. Because DoSomethingAsync
is an Async function, the task for the call to DoSomethingAsync must be awaited, as the following
statement demonstrates: Await DoSomethingAsync() . The startButton_Click``Sub procedure must be
defined with the Async modifier because it has an Await expression.
' Imports System.Diagnostics
' Imports System.Threading.Tasks
' Output:
' Result: 5
See Also
Sub Statement
Function Procedures
Parameter List
Dim Statement
Call Statement
Of
Parameter Arrays
How to: Use a Generic Class
Troubleshooting Procedures
Lambda Expressions
Function Expression
Get Statement
7/29/2017 • 3 min to read • Edit Online
Syntax
[ <attributelist> ] [ accessmodifier ] Get()
[ statements ]
End Get
Parts
TERM DEFINITION
- Protected
- Friend
- Private
- Protected Friend
statements Optional. One or more statements that run when the Get
property procedure is called.
Remarks
Every property must have a Get property procedure unless the property is marked WriteOnly . The Get
procedure is used to return the current value of the property.
Visual Basic automatically calls a property's Get procedure when an expression requests the property's value.
The body of the property declaration can contain only the property's Get and Set procedures between the
Property Statement and the End Property statement. It cannot store anything other than those procedures. In
particular, it cannot store the property's current value. You must store this value outside the property, because if
you store it inside either of the property procedures, the other property procedure cannot access it. The usual
approach is to store the value in a Private variable declared at the same level as the property. You must define a
Get procedure inside the property to which it applies.
The Get procedure defaults to the access level of its containing property unless you use accessmodifier in the
Get statement.
Rules
Mixed Access Levels. If you are defining a read-write property, you can optionally specify a different
access level for either the Get or the Set procedure, but not both. If you do this, the procedure access
level must be more restrictive than the property's access level. For example, if the property is declared
Friend , you can declare the Get procedure Private , but not Public .
If you are defining a ReadOnly property, the Get procedure represents the entire property. You cannot
declare a different access level for Get , because that would set two access levels for the property.
Return Type. The Property Statement can declare the data type of the value it returns. The Get procedure
automatically returns that data type. You can specify any data type or the name of an enumeration,
structure, class, or interface.
If the Property statement does not specify returntype , the procedure returns Object .
Behavior
Returning from a Procedure. When the Get procedure returns to the calling code, execution continues
within the statement that requested the property value.
Get property procedures can return a value using either the Return Statement or by assigning the return
value to the property name. For more information, see "Return Value" in Function Statement.
The Exit Property and Return statements cause an immediate exit from a property procedure. Any
number of Exit Property and Return statements can appear anywhere in the procedure, and you can
mix Exit Property and Return statements.
Return Value. To return a value from a Get procedure, you can either assign the value to the property
name or include it in a Return Statement. The Return statement simultaneously assigns the Get
procedure return value and exits the procedure.
If you use Exit Property without assigning a value to the property name, the Get procedure returns the
default value for the property's data type. For more information, see "Return Value" in Function Statement.
The following example illustrates two ways the read-only property quoteForTheDay can return the value
held in the private variable quoteValue .
Example
The following example uses the Get statement to return the value of a property.
Class propClass
' Define a private local variable to store the property value.
Private currentTime As String
' Define the read-only property.
Public ReadOnly Property dateAndTime() As String
Get
' The Get procedure is called automatically when the
' value of the property is retrieved.
currentTime = CStr(Now)
' Return the date and time As a string.
Return currentTime
End Get
End Property
End Class
See Also
Set Statement
Property Statement
Exit Statement
Objects and Classes
Walkthrough: Defining Classes
GoTo Statement
7/29/2017 • 1 min to read • Edit Online
Syntax
GoTo line
Part
line
Required. Any line label.
Remarks
The GoTo statement can branch only to lines in the procedure in which it appears. The line must have a line label
that GoTo can refer to. For more information, see How to: Label Statements.
NOTE
GoTo statements can make code difficult to read and maintain. Whenever possible, use a control structure instead. For
more information, see Control Flow.
You cannot use a GoTo statement to branch from outside a For ... Next , For Each ... Next , SyncLock ...
End SyncLock , Try ... Catch ... Finally , With ... End With , or Using ... End Using construction to a label inside.
Try block Only from a Catch block of the same Only to outside the whole construction
construction 1
1 If one Try ... Catch ... Finally construction is nested within another, a Catch block can branch into the Try
block at its own nesting level, but not into any other Try block. A nested Try ... Catch ... Finally construction
must be contained completely in a Try or Catch block of the construction within which it is nested.
The following illustration shows one Try construction nested within another. Various branches among the blocks
of the two constructions are indicated as valid or invalid.
Valid and invalid branches in Try constructions
Example
The following example uses the GoTo statement to branch to line labels in a procedure.
Sub gotoStatementDemo()
Dim number As Integer = 1
Dim sampleString As String
' Evaluate number and branch to appropriate label.
If number = 1 Then GoTo Line1 Else GoTo Line2
Line1:
sampleString = "Number equals 1"
GoTo LastLine
Line2:
' The following statement never gets executed because number = 1.
sampleString = "Number equals 2"
LastLine:
' Write "Number equals 1" in the Debug window.
Debug.WriteLine(sampleString)
End Sub
See Also
Do...Loop Statement
For...Next Statement
For Each...Next Statement
If...Then...Else Statement
Select...Case Statement
Try...Catch...Finally Statement
While...End While Statement
With...End With Statement
If...Then...Else Statement (Visual Basic)
7/29/2017 • 3 min to read • Edit Online
Syntax
' Multiple-line syntax:
If condition [ Then ]
[ statements ]
[ ElseIf elseifcondition [ Then ]
[ elseifstatements ] ]
[ Else
[ elsestatements ] ]
End If
Parts
condition
Required. Expression. Must evaluate to True or False , or to a data type that is implicitly convertible to Boolean
.
If the expression is a Nullable Boolean variable that evaluates to Nothing, the condition is treated as if the
expression is not True , and the Else block is executed.
Then
Required in the single-line syntax; optional in the multiple-line syntax.
statements
Optional. One or more statements following If ... Then that are executed if condition evaluates to True .
elseifcondition
Required if ElseIf is present. Expression. Must evaluate to True or False , or to a data type that is implicitly
convertible to Boolean .
elseifstatements
Optional. One or more statements following ElseIf ... Then that are executed if elseifcondition evaluates to
True .
elsestatements
Optional. One or more statements that are executed if no previous condition or elseifcondition expression
evaluates to True .
End If
Terminates the If ... Then ... Else block.
Remarks
Multiple-Line Syntax
When an If ... Then ... Else statement is encountered, condition is tested. If condition is True , the statements
following Then are executed. If condition is False , each ElseIf statement (if there are any) is evaluated in
order. When a True``elseifcondition is found, the statements immediately following the associated ElseIf are
executed. If no elseifcondition evaluates to True , or if there are no ElseIf statements, the statements
following Else are executed. After executing the statements following Then , ElseIf , or Else , execution
continues with the statement following End If .
The ElseIf and Else clauses are both optional. You can have as many ElseIf clauses as you want in an If ...
Then ... Else statement, but no ElseIf clause can appear after an Else clause. If ... Then ... Else statements
can be nested within each other.
In the multiple-line syntax, the If statement must be the only statement on the first line. The ElseIf , Else ,
and End If statements can be preceded only by a line label. The If ... Then ... Else block must end with an
End If statement.
TIP
The Select...Case Statement might be more useful when you evaluate a single expression that has several possible values.
Single-Line Syntax
You can use the single-line syntax for short, simple tests. However, the multiple-line syntax provides more
structure and flexibility and is usually easier to read, maintain, and debug.
What follows the Then keyword is examined to determine whether a statement is a single-line If . If anything
other than a comment appears after Then on the same line, the statement is treated as a single-line If
statement. If Then is absent, it must be the start of a multiple-line If ... Then ... Else .
In the single-line syntax, you can have multiple statements executed as the result of an If ... Then decision. All
statements must be on the same line and be separated by colons.
Example
The following example illustrates the use of the multiple-line syntax of the If ... Then ... Else statement.
If count = 0 Then
message = "There are no items."
ElseIf count = 1 Then
message = "There is 1 item."
Else
message = "There are " & count & " items."
End If
Example
The following example contains nested If ... Then ... Else statements.
Private Function CheckIfTime() As Boolean
' Determine the current day of week and hour of day.
Dim dayW As DayOfWeek = DateTime.Now.DayOfWeek
Dim hour As Integer = DateTime.Now.Hour
Example
The following example illustrates the use of the single-line syntax.
' If A > 10, execute the three colon-separated statements in the order
' that they appear
If A > 10 Then A = A + 1 : B = B + A : C = C + B
See Also
Choose
Switch
#If...Then...#Else Directives
Select...Case Statement
Nested Control Structures
Decision Structures
Logical and Bitwise Operators in Visual Basic
If Operator
Implements Statement
7/29/2017 • 2 min to read • Edit Online
Specifies one or more interfaces, or interface members, that must be implemented in the class or structure
definition in which it appears.
Syntax
Implements interfacename [, ...]
-or-
Implements interfacename.interfacemember [, ...]
Parts
interfacename
Required. An interface whose properties, procedures, and events are to be implemented by corresponding
members in the class or structure.
interfacemember
Required. The member of an interface that is being implemented.
Remarks
An interface is a collection of prototypes representing the members (properties, procedures, and events) the
interface encapsulates. Interfaces contain only the declarations for members; classes and structures implement
these members. For more information, see Interfaces.
The Implements statement must immediately follow the Class or Structure statement.
When you implement an interface, you must implement all the members declared in the interface. Omitting any
member is considered to be a syntax error. To implement an individual member, you specify the Implements
keyword (which is separate from the Implements statement) when you declare the member in the class or
structure. For more information, see Interfaces.
Classes can use Private implementations of properties and procedures, but these members are accessible only
by casting an instance of the implementing class into a variable declared to be of the type of the interface.
Example
The following example shows how to use the Implements statement to implement members of an interface. It
defines an interface named ICustomerInfo with an event, a property, and a procedure. The class customerInfo
implements all the members defined in the interface.
Public Interface ICustomerInfo
Event updateComplete()
Property customerName() As String
Sub updateCustomerStatus()
End Interface
Note that the class customerInfo uses the Implements statement on a separate source code line to indicate that
the class implements all the members of the ICustomerInfo interface. Then each member in the class uses the
Implements keyword as part of its member declaration to indicate that it implements that interface member.
Example
The following two procedures show how you could use the interface implemented in the preceding example. To
test the implementation, add these procedures to your project and call the testImplements procedure.
Sub handleUpdateComplete()
' This is the event handler for the updateComplete event.
MsgBox("Update is complete.")
End Sub
See Also
Implements
Interface Statement
Interfaces
Imports Statement (.NET Namespace and Type)
7/29/2017 • 4 min to read • Edit Online
Syntax
Imports [ aliasname = ] namespace
-or-
Imports [ aliasname = ] namespace.element
Parts
TERM DEFINITION
Remarks
The Imports statement enables types that are contained in a given namespace to be referenced directly.
You can supply a single namespace name or a string of nested namespaces. Each nested namespace is
separated from the next higher level namespace by a period ( . ), as the following example illustrates.
Imports System.Collections.Generic
Each source file can contain any number of Imports statements. These must follow any option declarations,
such as the Option Strict statement, and they must precede any programming element declarations, such as
Module or Class statements.
You can use Imports only at file level. This means the declaration context for importation must be a source file,
and cannot be a namespace, class, structure, module, interface, procedure, or block.
Note that the Imports statement does not make elements from other projects and assemblies available to your
project. Importing does not take the place of setting a reference. It only removes the need to qualify names that
are already available to your project. For more information, see "Importing Containing Elements" in References
to Declared Elements.
NOTE
You can define implicit Imports statements by using the References Page, Project Designer (Visual Basic). For more
information, see How to: Add or Remove Imported Namespaces (Visual Basic).
Import Aliases
An import alias defines the alias for a namespace or type. Import aliases are useful when you need to use items
with the same name that are declared in one or more namespaces. For more information and an example, see
"Qualifying an Element Name" in References to Declared Elements.
You should not declare a member at module level with the same name as aliasname . If you do, the Visual Basic
compiler uses aliasname only for the declared member and no longer recognizes it as an import alias.
Although the syntax used for declaring an import alias is like that used for importing an XML namespace prefix,
the results are different. An import alias can be used as an expression in your code, whereas an XML namespace
prefix can be used only in XML literals or XML axis properties as the prefix for a qualified element or attribute
name.
Element Names
If you supply element , it must represent a container element, that is, a programming element that can contain
other elements. Container elements include classes, structures, modules, interfaces, and enumerations.
The scope of the elements made available by an Imports statement depends on whether you specify element .
If you specify only namespace , all uniquely named members of that namespace, and members of container
elements within that namespace, are available without qualification. If you specify both namespace and element
, only the members of that element are available without qualification.
Example
The following example returns all the folders in the C:\ directory by using the DirectoryInfo class.
The code has no Imports statements at the top of the file. Therefore, the DirectoryInfo , StringBuilder, and CrLf
references are all fully qualified with the namespaces.
Return sb.ToString
End Function
Example
The following example includes Imports statements for the referenced namespaces. Therefore, the types do not
have to be fully qualified with the namespaces.
' Place Imports statements at the top of your program.
Imports System.Text
Imports System.IO
Imports Microsoft.VisualBasic.ControlChars
Return sb.ToString
End Function
Example
The following example includes Imports statements that create aliases for the referenced namespaces. The
types are qualified with the aliases.
Return sb.ToString
End Function
Example
The following example includes Imports statements that create aliases for the referenced types. Aliases are
used to specify the types.
Return sb.ToString
End Function
See Also
Namespace Statement
Namespaces in Visual Basic
References and the Imports Statement
Imports Statement (XML Namespace)
References to Declared Elements
Imports Statement (XML Namespace)
7/29/2017 • 4 min to read • Edit Online
Imports XML namespace prefixes for use in XML literals and XML axis properties.
Syntax
Imports <xmlns:xmlNamespacePrefix = "xmlNamespaceName">
Parts
xmlNamespacePrefix
Optional. The string by which XML elements and attributes can refer to xmlNamespaceName . If no
xmlNamespacePrefix is supplied, the imported XML namespace is the default XML namespace. Must be a valid
XML identifier. For more information, see Names of Declared XML Elements and Attributes.
xmlNamespaceName
Required. The string identifying the XML namespace being imported.
Remarks
You can use the Imports statement to define global XML namespaces that you can use with XML literals and XML
axis properties, or as parameters passed to the GetXmlNamespace operator. (For information about using the
Imports statement to import an alias that can be used where type names are used in your code, see Imports
Statement (.NET Namespace and Type).) The syntax for declaring an XML namespace by using the Imports
statement is identical to the syntax used in XML. Therefore, you can copy a namespace declaration from an XML
file and use it in an Imports statement.
XML namespace prefixes are useful when you want to repeatedly create XML elements that are from the same
namespace. The XML namespace prefix declared with the Imports statement is global in the sense that it is
available to all code in the file. You can use it when you create XML element literals and when you access XML axis
properties. For more information, see XML Element Literal and XML Axis Properties.
If you define a global XML namespace without a namespace prefix (for example,
Imports <xmlns="http://SomeNameSpace>" ), that namespace is considered the default XML namespace. The default
XML namespace is used for any XML element literals or XML attribute axis properties that do not explicitly specify
a namespace. The default namespace is also used if the specified namespace is the empty namespace (that is,
xmlns="" ). The default XML namespace does not apply to XML attributes in XML literals or to XML attribute axis
properties that do not have a namespace.
XML namespaces that are defined in an XML literal, which are called local XML namespaces, take precedence over
XML namespaces that are defined by the Imports statement as global. XML namespaces that are defined by the
Imports statement take precedence over XML namespaces imported for a Visual Basic project. If an XML literal
defines an XML namespace, that local namespace does not apply to embedded expressions.
Global XML namespaces follow the same scoping and definition rules as .NET Framework namespaces. As a
result, you can include an Imports statement to define a global XML namespace anywhere you can import a .NET
Framework namespace. This includes both code files and project-level imported namespaces. For information
about project-level imported namespaces, see References Page, Project Designer (Visual Basic).
Each source file can contain any number of Imports statements. These must follow option declarations, such as
the Option Strict statement, and they must precede programming element declarations, such as Module or
Class statements.
Example
The following example imports a default XML namespace and an XML namespace identified with the prefix ns . It
then creates XML literals that use both namespaces.
Module Module1
Sub Main()
' Create element by using the default global XML namespace.
Dim inner = <innerElement/>
' Create element by using both the default global XML namespace
' and the namespace identified with the "ns" prefix.
Dim outer = <ns:outer>
<ns:innerElement></ns:innerElement>
<siblingElement></siblingElement>
<%= inner %>
</ns:outer>
End Module
<ns:outer xmlns="http://DefaultNamespace"
xmlns:ns="http://NewNamespace">
<ns:innerElement></ns:innerElement>
<siblingElement></siblingElement>
<innerElement />
</ns:outer>
Example
The following example imports the XML namespace prefix ns . It then creates an XML literal that uses the
namespace prefix and displays the element's final form.
' Place Imports statements at the top of your program.
Imports <xmlns:ns="http://SomeNamespace">
Class TestClass1
Dim test =
<ns:outer>
<ns:middle xmlns:ns="http://NewNamespace">
<ns:inner1/>
<%= inner2 %>
</ns:middle>
</ns:outer>
End Class
<ns:outer xmlns:ns="http://SomeNamespace">
<ns:middle xmlns:ns="http://NewNamespace">
<ns:inner1 />
<inner2 xmlns="http://SomeNamespace" />
</ns:middle>
</ns:outer>
Notice that the compiler converted the XML namespace prefix from a global prefix to a local prefix definition.
Example
The following example imports the XML namespace prefix ns . It then uses the prefix of the namespace to create
an XML literal and access the first child node with the qualified name ns:name .
Class TestClass4
End Class
See Also
XML Element Literal
XML Axis Properties
Names of Declared XML Elements and Attributes
GetXmlNamespace Operator
Inherits Statement
7/29/2017 • 2 min to read • Edit Online
Causes the current class or interface to inherit the attributes, variables, properties, procedures, and events from
another class or set of interfaces.
Syntax
Inherits basetypenames
Parts
TERM DEFINITION
basetypenames Required. The name of the class from which this class
derives.
-or-
Remarks
If used, the Inherits statement must be the first non-blank, non-comment line in a class or interface definition.
It should immediately follow the Class or Interface statement.
You can use Inherits only in a class or interface. This means the declaration context for an inheritance cannot
be a source file, namespace, structure, module, procedure, or block.
Rules
Class Inheritance. If a class uses the Inherits statement, you can specify only one base class.
A class cannot inherit from a class nested within it.
Interface Inheritance. If an interface uses the Inherits statement, you can specify one or more base
interfaces. You can inherit from two interfaces even if they each define a member with the same name. If
you do so, the implementing code must use name qualification to specify which member it is
implementing.
An interface cannot inherit from another interface with a more restrictive access level. For example, a
Public interface cannot inherit from a Friend interface.
Example
The following example uses the Inherits statement to show how a class named thisClass can inherit all the
members of a base class named anotherClass .
Example
The following example shows inheritance of multiple interfaces.
The interface named thisInterface now includes all the definitions in the IComparable, IDisposable, and
IFormattable interfaces The inherited members provide respectively for type-specific comparison of two objects,
releasing allocated resources, and expressing the value of an object as a String . A class that implements
thisInterface must implement every member of every base interface.
See Also
MustInherit
NotInheritable
Objects and Classes
Inheritance Basics
Interfaces
Interface Statement (Visual Basic)
8/11/2017 • 5 min to read • Edit Online
Declares the name of an interface and introduces the definitions of the members that the interface comprises.
Syntax
[ <attributelist> ] [ accessmodifier ] [ Shadows ] _
Interface name [ ( Of typelist ) ]
[ Inherits interfacenames ]
[ [ modifiers ] Property membername ]
[ [ modifiers ] Function membername ]
[ [ modifiers ] Sub membername ]
[ [ modifiers ] Event membername ]
[ [ modifiers ] Interface membername ]
[ [ modifiers ] Class membername ]
[ [ modifiers ] Structure membername ]
End Interface
Parts
TERM DEFINITION
- Public
- Protected
- Friend
- Private
- Protected Friend
Remarks
An interface defines a set of members, such as properties and procedures, that classes and structures can
implement. The interface defines only the signatures of the members and not their internal workings.
A class or structure implements the interface by supplying code for every member defined by the interface.
Finally, when the application creates an instance from that class or structure, an object exists and runs in
memory. For more information, see Objects and Classes and Interfaces.
You can use Interface only at namespace or module level. This means the declaration context for an interface
must be a source file, namespace, class, structure, module, or interface, and cannot be a procedure or block.
For more information, see Declaration Contexts and Default Access Levels.
Interfaces default to Friend access. You can adjust their access levels with the access modifiers. For more
information, see Access levels in Visual Basic.
Rules
Nesting Interfaces. You can define one interface within another. The outer interface is called the
containing interface, and the inner interface is called a nested interface.
Member Declaration. When you declare a property or procedure as a member of an interface, you are
defining only the signature of that property or procedure. This includes the element type (property or
procedure), its parameters and parameter types, and its return type. Because of this, the member
definition uses only one line of code, and terminating statements such as End Function or
End Property are not valid in an interface.
In contrast, when you define an enumeration or structure, or a nested class or interface, it is necessary
to include their data members.
Member Modifiers. You cannot use any access modifiers when defining module members, nor can
you specify Shared or any procedure modifier except Overloads. You can declare any member with
Shadows, and you can use Default when defining a property, as well as ReadOnly or WriteOnly.
Inheritance. If the interface uses the Inherits Statement, you can specify one or more base interfaces.
You can inherit from two interfaces even if they each define a member with the same name. If you do
so, the implementing code must use name qualification to specify which member it is implementing.
An interface cannot inherit from another interface with a more restrictive access level. For example, a
Public interface cannot inherit from a Friend interface.
Behavior
Access Level. All interface members implicitly have Public access. You cannot use any access modifier
when defining a member. However, a class implementing the interface can declare an access level for
each implemented member.
If you assign a class instance to a variable, the access level of its members can depend on whether the
data type of the variable is the underlying interface or the implementing class. The following example
illustrates this.
Public Interface IDemo
Sub doSomething()
End Interface
Public Class implementIDemo
Implements IDemo
Private Sub doSomething() Implements IDemo.doSomething
End Sub
End Class
Dim varAsInterface As IDemo = New implementIDemo()
Dim varAsClass As implementIDemo = New implementIDemo()
If you access class members through varAsInterface , they all have public access. However, if you
access members through varAsClass , the Sub procedure doSomething has private access.
Scope. An interface is in scope throughout its namespace, class, structure, or module.
The scope of every interface member is the entire interface.
Lifetime. An interface does not itself have a lifetime, nor do its members. When a class implements an
interface and an object is created as an instance of that class, the object has a lifetime within the
application in which it is running. For more information, see "Lifetime" in Class Statement.
Example
The following example uses the Interface statement to define an interface named thisInterface , which
must be implemented with a Property statement and a Function statement.
Note that the Property and Function statements do not introduce blocks ending with End Property and
End Function within the interface. The interface defines only the signatures of its members. The full Property
and Function blocks appear in a class that implements thisInterface .
See Also
Interfaces
Class Statement
Module Statement
Structure Statement
Property Statement
Function Statement
Sub Statement
Generic Types in Visual Basic
Variance in Generic Interfaces
In
Out
Mid Statement
7/29/2017 • 1 min to read • Edit Online
Replaces a specified number of characters in a String variable with characters from another string.
Syntax
Mid( _
ByRef Target As String, _
ByVal Start As Integer, _
Optional ByVal Length As Integer _
) = StringExpression
Parts
Target
Required. Name of the String variable to modify.
Start
Required. Integer expression. Character position in Target where the replacement of text begins. Start uses a
one-based index.
Length
Optional. Integer expression. Number of characters to replace. If omitted, all of String is used.
StringExpression
Required. String expression that replaces part of Target .
Exceptions
EXCEPTION TYPE CONDITION
Remarks
The number of characters replaced is always less than or equal to the number of characters in Target .
Visual Basic has a Mid function and a Mid statement. These elements both operate on a specified number of
characters in a string, but the Mid function returns the characters while the Mid statement replaces the characters.
For more information, see Mid.
NOTE
The MidB statement of earlier versions of Visual Basic replaces a substring in bytes, rather than characters. It is used
primarily for converting strings in double-byte character set (DBCS) applications. All Visual Basic strings are in Unicode, and
MidB is no longer supported.
Example
This example uses the Mid statement to replace a specified number of characters in a string variable with
characters from another string.
Requirements
Namespace: Microsoft.VisualBasic
Module: Strings
See Also
Mid
Strings
Introduction to Strings in Visual Basic
Module Statement
7/29/2017 • 3 min to read • Edit Online
Declares the name of a module and introduces the definition of the variables, properties, events, and
procedures that the module comprises.
Syntax
[ <attributelist> ] [ accessmodifier ] Module name
[ statements ]
End Module
Parts
attributelist
Optional. See Attribute List.
accessmodifier
Optional. Can be one of the following:
Public
Friend
See Access levels in Visual Basic.
name
Required. Name of this module. See Declared Element Names.
statements
Optional. Statements which define the variables, properties, events, procedures, and nested types of this
module.
End Module
Terminates the Module definition.
Remarks
A Module statement defines a reference type available throughout its namespace. A module (sometimes called
a standard module)is similar to a class but with some important distinctions. Every module has exactly one
instance and does not need to be created or assigned to a variable. Modules do not support inheritance or
implement interfaces. Notice that a module is not a type in the sense that a class or structure is — you cannot
declare a programming element to have the data type of a module.
You can use Module only at namespace level. This means the declaration context for a module must be a
source file or namespace, and cannot be a class, structure, module, interface, procedure, or block. You cannot
nest a module within another module, or within any type. For more information, see Declaration Contexts and
Default Access Levels.
A module has the same lifetime as your program. Because its members are all Shared , they also have lifetimes
equal to that of the program.
Modules default to Friend access. You can adjust their access levels with the access modifiers. For more
information, see Access levels in Visual Basic.
All members of a module are implicitly Shared .
Rules
Modifiers. All module members are implicitly Shared. You cannot use the Shared keyword when
declaring a member, and you cannot alter the shared status of any member.
Inheritance. A module cannot inherit from any type other than Object, from which all modules inherit.
In particular, one module cannot inherit from another.
You cannot use the Inherits Statement in a module definition, even to specify Object.
Default Property. You cannot define any default properties in a module. For more information, see
Default.
Behavior
Access Level. Within a module, you can declare each member with its own access level. Module
members default to Public access, except variables and constants, which default to Private access. When
a module has more restricted access than one of its members, the specified module access level takes
precedence.
Scope. A module is in scope throughout its namespace.
The scope of every module member is the entire module. Notice that all members undergo type
promotion, which causes their scope to be promoted to the namespace containing the module. For
more information, see Type Promotion.
Qualification. You can have multiple modules in a project, and you can declare members with the
same name in two or more modules. However, you must qualify any reference to such a member with
the appropriate module name if the reference is from outside that module. For more information, see
References to Declared Elements.
Example
Public Module thisModule
Sub Main()
Dim userName As String = InputBox("What is your name?")
MsgBox("User name is" & userName)
End Sub
' Insert variable, property, procedure, and event declarations.
End Module
See Also
Class Statement
Namespace Statement
Structure Statement
Interface Statement
Property Statement
Type Promotion
Namespace Statement
7/29/2017 • 4 min to read • Edit Online
Declares the name of a namespace and causes the source code that follows the declaration to be compiled within
that namespace.
Syntax
Namespace [Global.] { name | name.name }
[ componenttypes ]
End Namespace
Parts
Global
Optional. Allows you to define a namespace out of the root namespace of your project. See Namespaces in
Visual Basic.
name
Required. A unique name that identifies the namespace. Must be a valid Visual Basic identifier. For more
information, see Declared Element Names.
componenttypes
Optional. Elements that make up the namespace. These include, but are not limited to, enumerations, structures,
interfaces, classes, modules, delegates, and other namespaces.
End Namespace
Terminates a Namespace block.
Remarks
Namespaces are used as an organizational system. They provide a way to classify and present programming
elements that are exposed to other programs and applications. Note that a namespace is not a type in the sense
that a class or structure is—you cannot declare a programming element to have the data type of a namespace.
All programming elements declared after a Namespace statement belong to that namespace. Visual Basic
continues to compile elements into the last declared namespace until it encounters either an End Namespace
statement or another Namespace statement.
If a namespace is already defined, even outside your project, you can add programming elements to it. To do
this, you use a Namespace statement to direct Visual Basic to compile elements into that namespace.
You can use a Namespace statement only at the file or namespace level. This means the declaration context for a
namespace must be a source file or another namespace, and cannot be a class, structure, module, interface, or
procedure. For more information, see Declaration Contexts and Default Access Levels.
You can declare one namespace within another. There is no strict limit to the levels of nesting you can declare,
but remember that when other code accesses the elements declared in the innermost namespace, it must use a
qualification string that contains all the namespace names in the nesting hierarchy.
Access Level
Namespaces are treated as if they have a Public access level. A namespace can be accessed from code
anywhere in the same project, from other projects that reference the project, and from any assembly built from
the project.
Programming elements declared at namespace level, meaning in a namespace but not inside any other element,
can have Public or Friend access. If unspecified, the access level of such an element uses Friend by default.
Elements you can declare at namespace level include classes, structures, modules, interfaces, enumerations, and
delegates. For more information, see Declaration Contexts and Default Access Levels.
Root Namespace
All namespace names in your project are based on a root namespace. Visual Studio assigns your project name as
the default root namespace for all code in your project. For example, if your project is named Payroll , its
programming elements belong to namespace Payroll . If you declare Namespace funding , the full name of that
namespace is Payroll.funding .
If you want to specify an existing namespace in a Namespace statement, such as in the generic list class example,
you can set your root namespace to a null value. To do this, click Project Properties from the Project menu and
then clear the Root namespace entry so that the box is empty. If you did not do this in the generic list class
example, the Visual Basic compiler would take System.Collections.Generic as a new namespace within project
Payroll , with the full name of Payroll.System.Collections.Generic .
Alternatively, you can use the Global keyword to refer to elements of namespaces defined outside your project.
Doing so lets you retain your project name as the root namespace. This reduces the chance of unintentionally
merging your programming elements together with those of existing namespaces. For more information, see the
"Global Keyword in Fully Qualified Names" section in Namespaces in Visual Basic.
The Global keyword can also be used in a Namespace statement. This lets you define a namespace out of the
root namespace of your project. For more information, see the "Global Keyword in Namespace Statements"
section in Namespaces in Visual Basic.
Troubleshooting. The root namespace can lead to unexpected concatenations of namespace names. If you
make reference to namespaces defined outside your project, the Visual Basic compiler can construe them as
nested namespaces in the root namespace. In such a case, the compiler does not recognize any types that have
been already defined in the external namespaces. To avoid this, either set your root namespace to a null value as
described in "Root Namespace," or use the Global keyword to access elements of external namespaces.
Example
The following example declares two namespaces, one nested in the other.
Namespace n1
Namespace n2
Class a
' Insert class definition.
End Class
End Namespace
End Namespace
Example
The following example declares multiple nested namespaces on a single line, and it is equivalent to the previous
example.
Namespace n1.n2
Class a
' Insert class definition.
End Class
End Namespace
Example
The following example accesses the class defined in the previous examples.
Example
The following example defines the skeleton of a new generic list class and adds it to the
System.Collections.Generic namespace.
Namespace System.Collections.Generic
Class specialSortedList(Of T)
Inherits List(Of T)
' Insert code to define the special generic list class.
End Class
End Namespace
See Also
Imports Statement (.NET Namespace and Type)
Declared Element Names
Namespaces in Visual Basic
On Error Statement (Visual Basic)
7/29/2017 • 7 min to read • Edit Online
Enables an error-handling routine and specifies the location of the routine within a procedure; can also be used to
disable an error-handling routine.
Without an On Error statement, any run-time error that occurs is fatal: an error message is displayed, and
execution stops.
Whenever possible, we suggest you use structured exception handling in your code, rather than using
unstructured exception handling and the On Error statement. For more information, see Try...Catch...Finally
Statement.
NOTE
The Error keyword is also used in the Error Statement, which is supported for backward compatibility.
Syntax
On Error { GoTo [ line | 0 | -1 ] | Resume Next }
Parts
TERM DEFINITION
GoTo line Enables the error-handling routine that starts at the line
specified in the required line argument. The line
argument is any line label or line number. If a run-time error
occurs, control branches to the specified line, making the
error handler active. The specified line must be in the same
procedure as the On Error statement, or a compile-time
error will occur.
Resume Next Specifies that when a run-time error occurs, control goes to
the statement immediately following the statement where the
error occurred, and execution continues from that point. Use
this form rather than On Error GoTo when accessing
objects.
Remarks
NOTE
We recommend that you use structured exception handling in your code whenever possible, rather than using unstructured
exception handling and the On Error statement. For more information, see Try...Catch...Finally Statement.
An "enabled" error handler is one that is turned on by an On Error statement. An "active" error handler is an
enabled handler that is in the process of handling an error.
If an error occurs while an error handler is active (between the occurrence of the error and a Resume , Exit Sub ,
Exit Function , or Exit Property statement), the current procedure's error handler cannot handle the error.
Control returns to the calling procedure.
If the calling procedure has an enabled error handler, it is activated to handle the error. If the calling procedure's
error handler is also active, control passes back through previous calling procedures until an enabled, but inactive,
error handler is found. If no such error handler is found, the error is fatal at the point at which it actually occurred.
Each time the error handler passes control back to a calling procedure, that procedure becomes the current
procedure. Once an error is handled by an error handler in any procedure, execution resumes in the current
procedure at the point designated by the Resume statement.
NOTE
An error-handling routine is not a Sub procedure or a Function procedure. It is a section of code marked by a line label
or a line number.
Number Property
Error-handling routines rely on the value in the Number property of the Err object to determine the cause of the
error. The routine should test or save relevant property values in the Err object before any other error can occur
or before a procedure that might cause an error is called. The property values in the Err object reflect only the
most recent error. The error message associated with Err.Number is contained in Err.Description .
Throw Statement
An error that is raised with the Err.Raise method sets the Exception property to a newly created instance of the
Exception class. In order to support the raising of exceptions of derived exception types, a Throw statement is
supported in the language. This takes a single parameter that is the exception instance to be thrown. The
following example shows how these features can be used with the existing exception handling support:
Notice that the On Error GoTo statement traps all errors, regardless of the exception class.
NOTE
The On Error Resume Next construct may be preferable to On Error GoTo when handling errors generated during
access to other objects. Checking Err after each interaction with an object removes ambiguity about which object was
accessed by the code. You can be sure which object placed the error code in Err.Number , as well as which object originally
generated the error (the object specified in Err.Source ).
On Error GoTo 0
On Error GoTo 0 disables error handling in the current procedure. It doesn't specify line 0 as the start of the
error-handling code, even if the procedure contains a line numbered 0. Without an On Error GoTo 0 statement,
an error handler is automatically disabled when a procedure is exited.
On Error GoTo -1
On Error GoTo -1 disables the exception in the current procedure. It does not specify line -1 as the start of the
error-handling code, even if the procedure contains a line numbered -1. Without an On Error GoTo -1 statement,
an exception is automatically disabled when a procedure is exited.
To prevent error-handling code from running when no error has occurred, place an Exit Sub , Exit Function , or
Exit Property statement immediately before the error-handling routine, as in the following fragment:
Here, the error-handling code follows the Exit Sub statement and precedes the End Sub statement to separate it
from the procedure flow. You can place error-handling code anywhere in a procedure.
Untrapped Errors
Untrapped errors in objects are returned to the controlling application when the object is running as an
executable file. Within the development environment, untrapped errors are returned to the controlling application
only if the proper options are set. See your host application's documentation for a description of which options
should be set during debugging, how to set them, and whether the host can create classes.
If you create an object that accesses other objects, you should try to handle any unhandled errors they pass back.
If you cannot, map the error codes in Err.Number to one of your own errors and then pass them back to the caller
of your object. You should specify your error by adding your error code to the VbObjectError constant. For
example, if your error code is 1052, assign it as follows:
Cau t i on
System errors during calls to Windows dynamic-link libraries (DLLs) do not raise exceptions and cannot be
trapped with Visual Basic error trapping. When calling DLL functions, you should check each return value for
success or failure (according to the API specifications), and in the event of a failure, check the value in the Err
object's LastDLLError property.
Example
This example first uses the On Error GoTo statement to specify the location of an error-handling routine within a
procedure. In the example, an attempt to divide by zero generates error number 6. The error is handled in the
error-handling routine, and control is then returned to the statement that caused the error. The On Error GoTo 0
statement turns off error trapping. Then the On Error Resume Next statement is used to defer error trapping so
that the context for the error generated by the next statement can be known for certain. Note that Err.Clear is
used to clear the Err object's properties after the error is handled.
Requirements
Namespace: Microsoft.VisualBasic
Assembly: Visual Basic Runtime Library (in Microsoft.VisualBasic.dll)
See Also
Err
Number
Description
LastDllError
End Statement
Exit Statement
Resume Statement
Error Messages
Try...Catch...Finally Statement
Operator Statement
7/29/2017 • 5 min to read • Edit Online
Declares the operator symbol, operands, and code that define an operator procedure on a class or structure.
Syntax
[ <attrlist> ] Public [ Overloads ] Shared [ Shadows ] [ Widening | Narrowing ]
Operator operatorsymbol ( operand1 [, operand2 ]) [ As [ <attrlist> ] type ]
[ statements ]
[ statements ]
Return returnvalue
[ statements ]
End Operator
Parts
attrlist
Optional. See Attribute List.
Public
Required. Indicates that this operator procedure has Public access.
Overloads
Optional. See Overloads.
Shared
Required. Indicates that this operator procedure is a Shared procedure.
Shadows
Optional. See Shadows.
Widening
Required for a conversion operator unless you specify Narrowing . Indicates that this operator procedure
defines a Widening conversion. See "Widening and Narrowing Conversions" on this Help page.
Narrowing
Required for a conversion operator unless you specify Widening . Indicates that this operator procedure
defines a Narrowing conversion. See "Widening and Narrowing Conversions" on this Help page.
operatorsymbol
Required. The symbol or identifier of the operator that this operator procedure defines.
operand1
Required. The name and type of the single operand of a unary operator (including a conversion operator) or
the left operand of a binary operator.
operand2
Required for binary operators. The name and type of the right operand of a binary operator.
operand1 and operand2 have the following syntax and parts:
[ ByVal ] operandname [ As operandtype ]
PART DESCRIPTION
type
Optional unless Option Strict is On . Data type of the value the operator procedure returns.
statements
Optional. Block of statements that the operator procedure runs.
returnvalue
Required. The value that the operator procedure returns to the calling code.
End Operator
Required. Terminates the definition of this operator procedure.
Remarks
You can use Operator only in a class or structure. This means the declaration context for an operator cannot
be a source file, namespace, module, interface, procedure, or block. For more information, see Declaration
Contexts and Default Access Levels.
All operators must be Public Shared . You cannot specify ByRef , Optional , or ParamArray for either operand.
You cannot use the operator symbol or identifier to hold a return value. You must use the Return statement,
and it must specify a value. Any number of Return statements can appear anywhere in the procedure.
Defining an operator in this way is called operator overloading, whether or not you use the Overloads
keyword. The following table lists the operators you can define.
TYPE OPERATORS
Note that the = operator in the binary list is the comparison operator, not the assignment operator.
When you define CType , you must specify either Widening or Narrowing .
Matched Pairs
You must define certain operators as matched pairs. If you define either operator of such a pair, you must
define the other as well. The matched pairs are the following:
= and <>
> and <
Similarly, you can use OrElse if you have defined Or on the same operands, with the return type of the class
or structure, and you have defined IsTrue on the class or structure.
See Also
IsFalse Operator
IsTrue Operator
Widening
Narrowing
Widening and Narrowing Conversions
Operator Procedures
How to: Define an Operator
How to: Define a Conversion Operator
How to: Call an Operator Procedure
How to: Use a Class that Defines Operators
Option <keyword> Statement
7/29/2017 • 1 min to read • Edit Online
Introduces a statement that specifies a compiler option that applies to the entire source file.
Remarks
The compiler options can control whether all variables must be explicitly declared, whether narrowing type
conversions must be explicit, or whether strings should be compared as text or as binary quantities.
The Option keyword can be used in these contexts:
Option Compare Statement
Option Explicit Statement
Option Infer Statement
Option Strict Statement
See Also
Keywords
Option Compare Statement
7/29/2017 • 3 min to read • Edit Online
Declares the default comparison method to use when comparing string data.
Syntax
Option Compare { Binary | Text }
Parts
TERM DEFINITION
Remarks
If used, the Option Compare statement must appear in a file before any other source code statements.
The Option Compare statement specifies the string comparison method ( Binary or Text ). The default text
comparison method is Binary .
A Binary comparison compares the numeric Unicode value of each character in each string. A Text
comparison compares each Unicode character based on its lexical meaning in the current culture.
In Microsoft Windows, sort order is determined by the code page. For more information, see Code Pages.
In the following example, characters in the English/European code page (ANSI 1252) are sorted by using
Option Compare Binary , which produces a typical binary sort order.
A < B < E < Z < a < b < e < z < À < Ê < Ø < à < ê < ø
When the same characters in the same code page are sorted by using Option Compare Text , the following text
sort order is produced.
(A=a) < (À = à) < (B=b) < (E=e) < (Ê = ê) < (Z=z) < (Ø = ø)
NOTE
Your computer might show different names or locations for some of the Visual Studio user interface elements in the
following instructions. The Visual Studio edition that you have and the settings that you use determine these elements.
For more information, see Personalizing the IDE.
Example
The following example uses the Option Compare statement to set the binary comparison as the default string
comparison method. To use this code, uncomment the Option Compare Binary statement, and put it at the top of
the source file.
Example
The following example uses the Option Compare statement to set the case-insensitive text sort order as the
default string comparison method. To use this code, uncomment the Option Compare Text statement, and put it
at the top of the source file.
Console.WriteLine("A" = "a")
' Output: True
See Also
InStr
InStrRev
Replace
Split
StrComp
/optioncompare
Comparison Operators
Comparison Operators in Visual Basic
Like Operator
String Functions
Option Explicit Statement
Option Strict Statement
Option Explicit Statement (Visual Basic)
7/29/2017 • 2 min to read • Edit Online
Forces explicit declaration of all variables in a file, or allows implicit declarations of variables.
Syntax
Option Explicit { On | Off }
Parts
On
Optional. Enables Option Explicit checking. If On or Off is not specified, the default is On .
Off
Optional. Disables Option Explicit checking.
Remarks
When Option Explicit On or Option Explicit appears in a file, you must explicitly declare all variables by using
the Dim or ReDim statements. If you try to use an undeclared variable name, an error occurs at compile time.
The Option Explicit Off statement allows implicit declaration of variables.
If used, the Option Explicit statement must appear in a file before any other source code statements.
NOTE
Setting Option Explicit to Off is generally not a good practice. You could misspell a variable name in one or more
locations, which would cause unexpected results when the program is run.
Example
The following example uses the Option Explicit statement to force explicit declaration of all variables.
Attempting to use an undeclared variable causes an error at compile time.
See Also
Dim Statement
ReDim Statement
Option Compare Statement
Option Strict Statement
/optioncompare
/optionexplicit
/optionstrict
Visual Basic Defaults, Projects, Options Dialog Box
Option Infer Statement
7/29/2017 • 4 min to read • Edit Online
Syntax
Option Infer { On | Off }
Parts
TERM DEFINITION
Remarks
To set Option Infer in a file, type Option Infer On or Option Infer Off at the top of the file, before any other
source code. If the value set for Option Infer in a file conflicts with the value set in the IDE or on the command
line, the value in the file has precedence.
When you set Option Infer to On , you can declare local variables without explicitly stating a data type. The
compiler infers the data type of a variable from the type of its initialization expression.
In the following illustration, Option Infer is turned on. The variable in the declaration Dim someVar = 2 is
declared as an integer by type inference.
Type inference applies at the procedure level, and does not apply outside a procedure in a class, structure,
module, or interface.
For additional information, see Local Type Inference.
Example
The following examples demonstrate how the Option Infer statement enables local type inference.
' Enable Option Infer before trying these examples.
Example
The following example demonstrates that the run-time type can differ when a variable is identified as an Object .
Dim someVar = 5
Console.WriteLine(someVar.GetType.ToString)
' Output:
' System.Int32
' System.String
See Also
Dim Statement
Local Type Inference
Option Compare Statement
Option Explicit Statement
Option Strict Statement
Visual Basic Defaults, Projects, Options Dialog Box
/optioninfer
Boxing and Unboxing
Option Strict Statement
7/29/2017 • 9 min to read • Edit Online
Restricts implicit data type conversions to only widening conversions, disallows late binding, and disallows
implicit typing that results in an Object type.
Syntax
Option Strict { On | Off }
Parts
TERM DEFINITION
Remarks
When Option Strict On or Option Strict appears in a file, the following conditions cause a compile-time
error:
Implicit narrowing conversions
Late binding
Implicit typing that results in an Object type
NOTE
In the warning configurations that you can set on the Compile Page, Project Designer (Visual Basic), there are three
settings that correspond to the three conditions that cause a compile-time error. For information about how to use
these settings, see To set warning configurations in the IDE later in this topic.
The Option Strict Off statement turns off error and warning checking for all three conditions, even if the
associated IDE settings specify to turn on these errors or warnings. The Option Strict On statement turns on
error and warning checking for all three conditions, even if the associated IDE settings specify to turn off
these errors or warnings.
If used, the Option Strict statement must appear before any other code statements in a file.
When you set Option Strict to On , Visual Basic checks that data types are specified for all programming
elements. Data types can be specified explicitly, or specified by using local type inference. Specifying data
types for all your programming elements is recommended, for the following reasons:
It enables IntelliSense support for your variables and parameters. This enables you to see their
properties and other members as you type code.
It enables the compiler to perform type checking. Type checking helps you find statements that can fail
at run time because of type conversion errors. It also identifies calls to methods on objects that do not
support those methods.
It speeds up the execution of code. One reason for this is that if you do not specify a data type for a
programming element, the Visual Basic compiler assigns it the Object type. Compiled code might
have to convert back and forth between Object and other data types, which reduces performance.
When you call a method that has an argument that has a data type different from the corresponding
parameter, a narrowing conversion causes a compile-time error if Option Strict is on. You can avoid the
compile-time error by using a widening conversion or an explicit conversion.
Implicit narrowing conversion errors are suppressed at compile-time for conversions from the elements in a
For Each…Next collection to the loop control variable. This occurs even if Option Strict is on. For more
information, see the "Narrowing Conversions" section in For Each...Next Statement.
1. In Solution Explorer, select a project. On the Project menu, click Properties. For more information,
see Introduction to the Project Designer.
2. On the Compile tab, set the value in the Option Strict box.
To set warning configurations in the IDE
When you use the Compile Page, Project Designer (Visual Basic) instead of an Option Strict statement, you
have additional control over the conditions that generate errors. The Warning configurations section of the
Compile Page has settings that correspond to the three conditions that cause a compile-time error when
Option Strict is on. Following are these settings:
Implicit conversion
Late binding; call could fail at run time
Implicit type; object assumed
When you set Option Strict to On, all three of these warning configuration settings are set to Error. When
you set Option Strict to Off, all three settings are set to None.
You can individually change each warning configuration setting to None, Warning, or Error. If all three
warning configuration settings are set to Error, On appears in the Option strict box. If all three are set to
None, Off appears in this box. For any other combination of these settings, (custom) appears.
To set the Option Strict default setting for new projects
When you create a project, the Option Strict setting on the Compile tab is set to the Option Strict setting
in the Options dialog box.
To set Option Strict in this dialog box, on the Tools menu, click Options. In the Options dialog box, expand
Projects and Solutions, and then click VB Defaults. The initial default setting in VB Defaults is Off .
To set Option Strict on the command line
Include the /optionstrict compiler option in the vbc command.
Example
The following examples demonstrate compile-time errors caused by implicit type conversions that are
narrowing conversions. This category of errors corresponds to the Implicit conversion condition on the
Compile Page.
' If Option Strict is on, this implicit narrowing
' conversion causes a compile-time error.
' The commented statements below use explicit
' conversions to avoid a compile-time error.
Dim cyclists As Long = 5
Dim bicycles As Integer = cyclists
'Dim bicycles As Integer = CType(cyclists, Integer)
'Dim bicycles As Integer = CInt(cyclists)
'Dim bicycles As Integer = Convert.ToInt32(cyclists)
Example
The following example demonstrates a compile-time error caused by late binding. This category of errors
corresponds to the Late binding; call could fail at run time condition on the Compile Page.
Example
The following examples demonstrate errors caused by variables that are declared with an implicit type of
Object . This category of errors corresponds to the Implicit type; object assumed condition on the
Compile Page.
End Sub
See Also
Widening and Narrowing Conversions
Implicit and Explicit Conversions
Compile Page, Project Designer (Visual Basic)
Option Explicit Statement
Type Conversion Functions
How to: Access Members of an Object
Embedded Expressions in XML
Relaxed Delegate Conversion
Late Binding in Office Solutions
/optionstrict
Visual Basic Defaults, Projects, Options Dialog Box
Property Statement
7/29/2017 • 5 min to read • Edit Online
Declares the name of a property, and the property procedures used to store and retrieve the value of the
property.
Syntax
[ <attributelist> ] [ Default ] [ accessmodifier ]
[ propertymodifiers ] [ Shared ] [ Shadows ] [ ReadOnly | WriteOnly ] [ Iterator ]
Property name ( [ parameterlist ] ) [ As returntype ] [ Implements implementslist ]
[ <attributelist> ] [ accessmodifier ] Get
[ statements ]
End Get
[ <attributelist> ] [ accessmodifier ] Set ( ByVal value As returntype [, parameterlist ] )
[ statements ]
End Set
End Property
- or -
[ <attributelist> ] [ Default ] [ accessmodifier ]
[ propertymodifiers ] [ Shared ] [ Shadows ] [ ReadOnly | WriteOnly ]
Property name ( [ parameterlist ] ) [ As returntype ] [ Implements implementslist ]
Parts
attributelist
Optional. List of attributes that apply to this property or Get or Set procedure. See Attribute List.
Default
Optional. Specifies that this property is the default property for the class or structure on which it is
defined. Default properties must accept parameters and can be set and retrieved without
specifying the property name. If you declare the property as Default , you cannot use Private on
the property or on either of its property procedures.
accessmodifier
Optional on the Property statement and on at most one of the Get and Set statements. Can be
one of the following:
Public
Protected
Friend
Private
Protected Friend
NotOverridable Overrides
Shared
Optional. List of local variable names representing the parameters of this property, and possible
additional parameters of the Set procedure. See Parameter List.
returntype
Optional. Indicates that this property implements one or more properties, each one defined in an
interface implemented by this property's containing class or structure. See Implements Statement.
implementslist
Get
Optional. Required if the property is marked WriteOnly . Starts a Get property procedure that is
used to return the value of the property.
statements
Optional. Required if the property is marked ReadOnly . Starts a Set property procedure that is
used to store the value of the property.
End Set
Remarks
The Property statement introduces the declaration of a property. A property can have a Get procedure
(read only), a Set procedure (write only), or both (read-write). You can omit the Get and Set
procedure when using an auto-implemented property. For more information, see Auto-Implemented
Properties.
You can use Property only at class level. This means the declaration context for a property must be a
class, structure, module, or interface, and cannot be a source file, namespace, procedure, or block. For
more information, see Declaration Contexts and Default Access Levels.
By default, properties use public access. You can adjust a property's access level with an access modifier
on the Property statement, and you can optionally adjust one of its property procedures to a more
restrictive access level.
Visual Basic passes a parameter to the Set procedure during property assignments. If you do not supply
a parameter for Set , the integrated development environment (IDE) uses an implicit parameter named
value . This parameter holds the value to be assigned to the property. You typically store this value in a
private local variable and return it whenever the Get procedure is called.
Rules
Mixed Access Levels. If you are defining a read-write property, you can optionally specify a
different access level for either the Get or the Set procedure, but not both. If you do this, the
procedure access level must be more restrictive than the property's access level. For example, if
the property is declared Friend , you can declare the Set procedure Private , but not Public .
If you are defining a ReadOnly or WriteOnly property, the single property procedure ( Get or
Set , respectively) represents all of the property. You cannot declare a different access level for
such a procedure, because that would set two access levels for the property.
Return Type. The Property statement can declare the data type of the value it returns. You can
specify any data type or the name of an enumeration, structure, class, or interface.
If you do not specify returntype , the property returns Object .
Implementation. If this property uses the Implements keyword, the containing class or structure
must have an Implements statement immediately following its Class or Structure statement.
The Implements statement must include each interface specified in implementslist . However, the
name by which an interface defines the Property (in definedname ) does not have to be the same
as the name of this property (in name ).
Behavior
Returning from a Property Procedure. When the Get or Set procedure returns to the calling
code, execution continues with the statement following the statement that invoked it.
The Exit Property and Return statements cause an immediate exit from a property procedure.
Any number of Exit Property and Return statements can appear anywhere in the procedure,
and you can mix Exit Property and Return statements.
Return Value. To return a value from a Get procedure, you can either assign the value to the
property name or include it in a Return statement. The following example assigns the return
value to the property name quoteForTheDay and then uses the Exit Property statement to return.
If you use Exit Property without assigning a value to name , the Get procedure returns the
default value for the property's data type.
The Return statement at the same time assigns the Get procedure return value and exits the
procedure. The following example shows this.
Class Class1
' Define a local variable to store the property value.
Private propertyValue As String
' Define the property.
Public Property prop1() As String
Get
' The Get property procedure is called when the value
' of a property is retrieved.
Return propertyValue
End Get
Set(ByVal value As String)
' The Set property procedure is called when the value
' of a property is modified. The value to be assigned
' is passed in the argument to Set.
propertyValue = value
End Set
End Property
End Class
See Also
Auto-Implemented Properties
Objects and Classes
Get Statement
Set Statement
Parameter List
Default
Q-Z Statements
7/29/2017 • 1 min to read • Edit Online
See Also
A-E Statements
F-P Statements
Visual Basic Language Reference
RaiseEvent Statement
7/29/2017 • 3 min to read • Edit Online
Syntax
RaiseEvent eventname[( argumentlist )]
Parts
eventname
Required. Name of the event to trigger.
argumentlist
Optional. Comma-delimited list of variables, arrays, or expressions. The argumentlist argument must be enclosed
by parentheses. If there are no arguments, the parentheses must be omitted.
Remarks
The required eventname is the name of an event declared within the module. It follows Visual Basic variable
naming conventions.
If the event has not been declared within the module in which it is raised, an error occurs. The following code
fragment illustrates an event declaration and a procedure in which the event is raised.
You cannot use RaiseEvent to raise events that are not explicitly declared in the module. For example, all forms
inherit a Click event from System.Windows.Forms.Form, it cannot be raised using RaiseEvent in a derived form. If
you declare a Click event in the form module, it shadows the form's own Click event. You can still invoke the
form's Click event by calling the OnClick method.
By default, an event defined in Visual Basic raises its event handlers in the order that the connections are
established. Because events can have ByRef parameters, a process that connects late may receive parameters that
have been changed by an earlier event handler. After the event handlers execute, control is returned to the
subroutine that raised the event.
NOTE
Non-shared events should not be raised within the constructor of the class in which they are declared. Although such
events do not cause run-time errors, they may fail to be caught by associated event handlers. Use the Shared modifier to
create a shared event if you need to raise an event from a constructor.
NOTE
You can change the default behavior of events by defining a custom event. For custom events, the RaiseEvent statement
invokes the event's RaiseEvent accessor. For more information on custom events, see Event Statement.
Example
The following example uses events to count down seconds from 10 to 0. The code illustrates several of the event-
related methods, properties, and statements, including the RaiseEvent statement.
The class that raises an event is the event source, and the methods that process the event are the event handlers.
An event source can have multiple handlers for the events it generates. When the class raises the event, that event
is raised on every class that has elected to handle events for that instance of the object.
The example also uses a form ( Form1 ) with a button ( Button1 ) and a text box ( TextBox1 ). When you click the
button, the first text box displays a countdown from 10 to 0 seconds. When the full time (10 seconds) has elapsed,
the first text box displays "Done".
The code for Form1 specifies the initial and terminal states of the form. It also contains the code executed when
events are raised.
To use this example, open a new Windows Application project, add a button named Button1 and a text box
named TextBox1 to the main form, named Form1 . Then right-click the form and click View Code to open the
Code Editor.
Add a WithEvents variable to the declarations section of the Form1 class.
Example
Add the following code to the code for Form1 . Replace any duplicate procedures that may exist, such as
Form_Load , or Button_Click .
Private Sub Form1_Load() Handles MyBase.Load
Button1.Text = "Start"
mText = New TimerState
End Sub
Private Sub Button1_Click() Handles Button1.Click
mText.StartCountdown(10.0, 0.1)
End Sub
Class TimerState
Public Event UpdateTime(ByVal Countdown As Double)
Public Event Finished()
Public Sub StartCountdown(ByVal Duration As Double,
ByVal Increment As Double)
Dim Start As Double = DateAndTime.Timer
Dim ElapsedTime As Double = 0
Press F5 to run the preceding example, and click the button labeled Start. The first text box starts to count down
the seconds. When the full time (10 seconds) has elapsed, the first text box displays "Done".
NOTE
The My.Application.DoEvents method does not process events in exactly the same way as the form does. To allow the
form to handle the events directly, you can use multithreading. For more information, see Threading.
See Also
Events
Event Statement
AddHandler Statement
RemoveHandler Statement
Handles
ReDim Statement (Visual Basic)
7/29/2017 • 4 min to read • Edit Online
Syntax
ReDim [ Preserve ] name(boundlist) [ , name(boundlist) [, ... ] ]
Parts
TERM DEFINITION
Remarks
You can use the ReDim statement to change the size of one or more dimensions of an array that has already
been declared. If you have a large array and you no longer need some of its elements, ReDim can free up
memory by reducing the array size. On the other hand, if your array needs more elements, ReDim can add
them.
The ReDim statement is intended only for arrays. It's not valid on scalars (variables that contain only a single
value), collections, or structures. Note that if you declare a variable to be of type Array , the ReDim statement
doesn't have sufficient type information to create the new array.
You can use ReDim only at procedure level. Therefore, the declaration context for the variable must be a
procedure; it can't be a source file, a namespace, an interface, a class, a structure, a module, or a block. For more
information, see Declaration Contexts and Default Access Levels.
Rules
Multiple Variables. You can resize several array variables in the same declaration statement and specify
the name and boundlist parts for each variable. Multiple variables are separated by commas.
Array Bounds. Each entry in boundlist can specify the lower and upper bounds of that dimension. The
lower bound is always 0 (zero). The upper bound is the highest possible index value for that dimension,
not the length of the dimension (which is the upper bound plus one). The index for each dimension can
vary from 0 through its upper bound value.
The number of dimensions in boundlist must match the original number of dimensions (rank) of the
array.
Data Types. The ReDim statement cannot change the data type of an array variable or its elements.
Initialization. The ReDim statement cannot provide new initialization values for the array elements.
Rank. The ReDim statement cannot change the rank (the number of dimensions) of the array.
Resizing with Preserve. If you use Preserve , you can resize only the last dimension of the array. For
every other dimension, you must specify the bound of the existing array.
For example, if your array has only one dimension, you can resize that dimension and still preserve all
the contents of the array, because you are changing the last and only dimension. However, if your array
has two or more dimensions, you can change the size of only the last dimension if you use Preserve .
Properties. You can use ReDim on a property that holds an array of values.
Behavior
Array Replacement. ReDim releases the existing array and creates a new array with the same rank. The
new array replaces the released array in the array variable.
Initialization without Preserve. If you do not specify Preserve , ReDim initializes the elements of the
new array by using the default value for their data type.
Initialization with Preserve. If you specify Preserve , Visual Basic copies the elements from the existing
array to the new array.
Example
The following example increases the size of the last dimension of a dynamic array without losing any existing
data in the array, and then decreases the size with partial data loss. Finally, it decreases the size back to its
original value and reinitializes all the array elements.
The Dim statement creates a new array with three dimensions. Each dimension is declared with a bound of 10,
so the array index for each dimension can range from 0 through 10. In the following discussion, the three
dimensions are referred to as layer, row, and column.
The first ReDim creates a new array which replaces the existing array in variable intArray . ReDim copies all the
elements from the existing array into the new array. It also adds 10 more columns to the end of every row in
every layer and initializes the elements in these new columns to 0 (the default value of Integer , which is the
element type of the array).
The second ReDim creates another new array and copies all the elements that fit. However, five columns are lost
from the end of every row in every layer. This is not a problem if you have finished using these columns.
Reducing the size of a large array can free up memory that you no longer need.
The third ReDim creates another new array and removes another five columns from the end of every row in
every layer. This time it does not copy any existing elements. This statement reverts the array to its original size.
Because the statement doesn't include the Preserve modifier, it sets all array elements to their original default
values.
For additional examples, see Arrays.
See Also
IndexOutOfRangeException
Const Statement
Dim Statement
Erase Statement
Nothing
Arrays
REM Statement (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
Syntax
REM comment
' comment
Parts
comment
Optional. The text of any comment you want to include. A space is required between the REM keyword and
comment .
Remarks
You can put a REM statement alone on a line, or you can put it on a line following another statement. The REM
statement must be the last statement on the line. If it follows another statement, the REM must be separated from
that statement by a space.
You can use a single quotation mark ( ' ) instead of REM . This is true whether your comment follows another
statement on the same line or sits alone on a line.
NOTE
You cannot continue a REM statement by using a line-continuation sequence ( _ ). Once a comment begins, the compiler
does not examine the characters for special meaning. For a multiple-line comment, use another REM statement or a
comment symbol ( ' ) on each line.
Example
The following example illustrates the REM statement, which is used to include explanatory remarks in a program. It
also shows the alternative of using the single quotation-mark character ( ' ) instead of REM .
See Also
Comments in Code
How to: Break and Combine Statements in Code
RemoveHandler Statement
7/29/2017 • 1 min to read • Edit Online
Syntax
RemoveHandler event, AddressOf eventhandler
Parts
TERM DEFINITION
Remarks
The AddHandler and RemoveHandler statements allow you to start and stop event handling for a specific event at
any time during program execution.
NOTE
For custom events, the RemoveHandler statement invokes the event's RemoveHandler accessor. For more information on
custom events, see Event Statement.
Example
Sub TestEvents()
Dim Obj As New Class1
' Associate an event handler with an event.
AddHandler Obj.Ev_Event, AddressOf EventHandler
' Call the method to raise the event.
Obj.CauseSomeEvent()
' Stop handling events.
RemoveHandler Obj.Ev_Event, AddressOf EventHandler
' This event will not be handled.
Obj.CauseSomeEvent()
End Sub
Sub EventHandler()
' Handle the event.
MsgBox("EventHandler caught event.")
End Sub
See Also
AddHandler Statement
Handles
Event Statement
Events
Resume Statement
7/29/2017 • 2 min to read • Edit Online
Syntax
Resume [ Next | line ]
Parts
Resume
Required. If the error occurred in the same procedure as the error handler, execution resumes with the statement
that caused the error. If the error occurred in a called procedure, execution resumes at the statement that last
called out of the procedure containing the error-handling routine.
Next
Optional. If the error occurred in the same procedure as the error handler, execution resumes with the statement
immediately following the statement that caused the error. If the error occurred in a called procedure, execution
resumes with the statement immediately following the statement that last called out of the procedure containing
the error-handling routine (or On Error Resume Next statement).
line
Optional. Execution resumes at the line specified in the required line argument. The line argument is a line
label or line number and must be in the same procedure as the error handler.
Remarks
NOTE
We recommend that you use structured exception handling in your code whenever possible, rather than using unstructured
exception handling and the On Error and Resume statements. For more information, see Try...Catch...Finally Statement.
If you use a Resume statement anywhere other than in an error-handling routine, an error occurs.
The Resume statement cannot be used in any procedure that contains a Try...Catch...Finally statement.
Example
This example uses the Resume statement to end error handling in a procedure and then resume execution with
the statement that caused the error. Error number 55 is generated to illustrate use of the Resume statement.
Sub ResumeStatementDemo()
On Error GoTo ErrorHandler ' Enable error-handling routine.
Dim x As Integer = 32
Dim y As Integer = 0
Dim z As Integer
z = x / y ' Creates a divide by zero error
Exit Sub ' Exit Sub to avoid error handler.
ErrorHandler: ' Error-handling routine.
Select Case Err.Number ' Evaluate error number.
Case 6 ' "Divide by zero" error.
y = 1 ' Sets the value of y to 1 and tries the calculation again.
Case Else
' Handle other situations here....
End Select
Resume ' Resume execution at same line
' that caused the error.
End Sub
Requirements
Namespace: Microsoft.VisualBasic
Assembly: Visual Basic Runtime Library (in Microsoft.VisualBasic.dll)
See Also
Try...Catch...Finally Statement
Error Statement
On Error Statement
Return Statement (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
Returns control to the code that called a Function , Sub , Get , Set , or Operator procedure.
Syntax
Return
-or-
Return expression
Part
expression
Required in a Function , Get , or Operator procedure. Expression that represents the value to be returned to
the calling code.
Remarks
In a Sub or Set procedure, the Return statement is equivalent to an Exit Sub or Exit Property statement,
and expression must not be supplied.
In a Function , Get , or Operator procedure, the Return statement must include expression , and expression
must evaluate to a data type that is convertible to the return type of the procedure. In a Function or Get
procedure, you also have the alternative of assigning an expression to the procedure name to serve as the
return value, and then executing an Exit Function or Exit Property statement. In an Operator procedure, you
must use Return``expression .
You can include as many Return statements as appropriate in the same procedure.
NOTE
The code in a Finally block runs after a Return statement in a Try or Catch block is encountered, but before that
Return statement executes. A Return statement cannot be included in a Finally block.
Example
The following example uses the Return statement several times to return to the calling code when the
procedure does not have to do anything else.
Syntax
Select [ Case ] testexpression
[ Case expressionlist
[ statements ] ]
[ Case Else
[ elsestatements ] ]
End Select
Parts
TERM DEFINITION
- expression1 To expression2
- [ Is ] comparisonoperator expression
- expression
Remarks
If testexpression matches any Case expressionlist clause, the statements following that Case statement run
up to the next Case , Case Else , or End Select statement. Control then passes to the statement following
End Select . If testexpression matches an expressionlist clause in more than one Case clause, only the
statements following the first match run.
The Case Else statement is used to introduce the elsestatements to run if no match is found between the
testexpression and an expressionlist clause in any of the other Case statements. Although not required, it is
a good idea to have a Case Else statement in your Select Case construction to handle unforeseen
testexpression values. If no Case expressionlist clause matches testexpression and there is no Case Else
statement, control passes to the statement following End Select .
You can use multiple expressions or ranges in each Case clause. For example, the following line is valid.
Case 1 To 4, 7 To 9, 11, 13, Is > maxNumber
NOTE
The Is keyword used in the Case and Case Else statements is not the same as the Is Operator, which is used for
object reference comparison.
You can specify ranges and multiple expressions for character strings. In the following example, Case matches
any string that is exactly equal to "apples", has a value between "nuts" and "soup" in alphabetical order, or
contains the exact same value as the current value of testItem .
Case "apples", "nuts" To "soup", testItem
The setting of Option Compare can affect string comparisons. Under Option Compare Text , the strings "Apples"
and "apples" compare as equal, but under Option Compare Binary , they do not.
NOTE
A Case statement with multiple clauses can exhibit behavior known as short-circuiting. Visual Basic evaluates the clauses
from left to right, and if one produces a match with testexpression , the remaining clauses are not evaluated. Short-
circuiting can improve performance, but it can produce unexpected results if you are expecting every expression in
expressionlist to be evaluated. For more information on short-circuiting, see Boolean Expressions.
If the code within a Case or Case Else statement block does not need to run any more of the statements in the
block, it can exit the block by using the Exit Select statement. This transfers control immediately to the
statement following End Select .
Select Case constructions can be nested. Each nested Select Case construction must have a matching
End Select statement and must be completely contained within a single Case or Case Else statement block of
the outer Select Case construction within which it is nested.
Example
The following example uses a Select Case construction to write a line corresponding to the value of the variable
number . The second Case statement contains the value that matches the current value of number , so the
statement that writes "Between 6 and 8, inclusive" runs.
See Also
Choose
End Statement
If...Then...Else Statement
Option Compare Statement
Exit Statement
Set Statement (Visual Basic)
7/29/2017 • 2 min to read • Edit Online
Syntax
[ <attributelist> ] [ accessmodifier ] Set (ByVal value [ As datatype ])
[ statements ]
End Set
Parts
attributelist
Optional. See Attribute List.
accessmodifier
Optional on at most one of the Get and Set statements in this property. Can be one of the following:
Protected
Friend
Private
Protected Friend
Remarks
Every property must have a Set property procedure unless the property is marked ReadOnly . The Set
procedure is used to set the value of the property.
Visual Basic automatically calls a property's Set procedure when an assignment statement provides a value to
be stored in the property.
Visual Basic passes a parameter to the Set procedure during property assignments. If you do not supply a
parameter for Set , the integrated development environment (IDE) uses an implicit parameter named value .
The parameter holds the value to be assigned to the property. You typically store this value in a private local
variable and return it whenever the Get procedure is called.
The body of the property declaration can contain only the property's Get and Set procedures between the
Property Statement and the End Property statement. It cannot store anything other than those procedures. In
particular, it cannot store the property's current value. You must store this value outside the property, because if
you store it inside either of the property procedures, the other property procedure cannot access it. The usual
approach is to store the value in a Private variable declared at the same level as the property. You must define a
Set procedure inside the property to which it applies.
The Set procedure defaults to the access level of its containing property unless you use accessmodifier in the
Set statement.
Rules
Mixed Access Levels. If you are defining a read-write property, you can optionally specify a different
access level for either the Get or the Set procedure, but not both. If you do this, the procedure access
level must be more restrictive than the property's access level. For example, if the property is declared
Friend , you can declare the Set procedure Private , but not Public .
If you are defining a WriteOnly property, the Set procedure represents the entire property. You cannot
declare a different access level for Set , because that would set two access levels for the property.
Behavior
Returning from a Property Procedure. When the Set procedure returns to the calling code, execution
continues following the statement that provided the value to be stored.
Set property procedures can return using either the Return Statement or the Exit Statement.
The Exit Property and Return statements cause an immediate exit from a property procedure. Any
number of Exit Property and Return statements can appear anywhere in the procedure, and you can
mix Exit Property and Return statements.
Example
The following example uses the Set statement to set the value of a property.
Class propClass
Private propVal As Integer
Property prop1() As Integer
Get
Return propVal
End Get
Set(ByVal value As Integer)
propVal = value
End Set
End Property
End Class
See Also
Get Statement
Property Statement
Sub Statement
Property Procedures
Stop Statement (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
Suspends execution.
Syntax
Stop
Remarks
You can place Stop statements anywhere in procedures to suspend execution. Using the Stop statement is
similar to setting a breakpoint in the code.
The Stop statement suspends execution, but unlike End , it does not close any files or clear any variables, unless it
is encountered in a compiled executable (.exe) file.
NOTE
If the Stop statement is encountered in code that is running outside of the integrated development environment (IDE), the
debugger is invoked. This is true regardless of whether the code was compiled in debug or retail mode.
Example
This example uses the Stop statement to suspend execution for each iteration through the For...Next loop.
Dim i As Integer
For i = 1 To 10
Debug.WriteLine(i)
' Stop during each iteration and wait for user to resume.
Stop
Next i
See Also
End Statement
Structure Statement
7/29/2017 • 5 min to read • Edit Online
Declares the name of a structure and introduces the definition of the variables, properties, events, and
procedures that the structure comprises.
Syntax
[ <attributelist> ] [ accessmodifier ] [ Shadows ] [ Partial ] _
Structure name [ ( Of typelist ) ]
[ Implements interfacenames ]
[ datamemberdeclarations ]
[ methodmemberdeclarations ]
End Structure
Parts
TERM DEFINITION
- Public
- Protected
- Friend
- Private
- Protected Friend
Remarks
The Structure statement defines a composite value type that you can customize. A structure is a
generalization of the user-defined type (UDT) of previous versions of Visual Basic. For more information, see
Structures.
Structures support many of the same features as classes. For example, structures can have properties and
procedures, they can implement interfaces, and they can have parameterized constructors. However, there are
significant differences between structures and classes in areas such as inheritance, declarations, and usage.
Also, classes are reference types and structures are value types. For more information, see Structures and
Classes.
You can use Structure only at namespace or module level. This means the declaration context for a structure
must be a source file, namespace, class, structure, module, or interface, and cannot be a procedure or block.
For more information, see Declaration Contexts and Default Access Levels.
Structures default to Friend access. You can adjust their access levels with the access modifiers. For more
information, see Access levels in Visual Basic.
Rules
Nesting. You can define one structure within another. The outer structure is called the containing
structure, and the inner structure is called a nested structure. However, you cannot access a nested
structure's members through the containing structure. Instead, you must declare a variable of the
nested structure's data type.
Member Declaration. You must declare every member of a structure. A structure member cannot be
Protected or Protected Friend because nothing can inherit from a structure. The structure itself,
however, can be Protected or Protected Friend .
You can declare zero or more nonshared variables or nonshared, noncustom events in a structure. You
cannot have only constants, properties, and procedures, even if some of them are nonshared.
Initialization. You cannot initialize the value of any nonshared data member of a structure as part of
its declaration. You must either initialize such a data member by means of a parameterized constructor
on the structure, or assign a value to the member after you have created an instance of the structure.
Inheritance. A structure cannot inherit from any type other than ValueType, from which all structures
inherit. In particular, one structure cannot inherit from another.
You cannot use the Inherits Statement in a structure definition, even to specify ValueType.
Implementation. If the structure uses the Implements Statement, you must implement every
member defined by every interface you specify in interfacenames .
Default Property. A structure can specify at most one property as its default property, using the
Default modifier. For more information, see Default.
Behavior
Access Level. Within a structure, you can declare each member with its own access level. All structure
members default to Public access. Note that if the structure itself has a more restricted access level, this
automatically restricts access to its members, even if you adjust their access levels with the access
modifiers.
Scope. A structure is in scope throughout its containing namespace, class, structure, or module.
The scope of every structure member is the entire structure.
Lifetime. A structure does not itself have a lifetime. Rather, each instance of that structure has a
lifetime independent of all other instances.
The lifetime of an instance begins when it is created by a New Operator clause. It ends when the
lifetime of the variable that holds it ends.
You cannot extend the lifetime of a structure instance. An approximation to static structure
functionality is provided by a module. For more information, see Module Statement.
Structure members have lifetimes depending on how and where they are declared. For more
information, see "Lifetime" in Class Statement.
Qualification. Code outside a structure must qualify a member's name with the name of that
structure.
If code inside a nested structure makes an unqualified reference to a programming element, Visual
Basic searches for the element first in the nested structure, then in its containing structure, and so on
out to the outermost containing element. For more information, see References to Declared Elements.
Memory Consumption. As with all composite data types, you cannot safely calculate the total
memory consumption of a structure by adding together the nominal storage allocations of its
members. Furthermore, you cannot safely assume that the order of storage in memory is the same as
your order of declaration. If you need to control the storage layout of a structure, you can apply the
StructLayoutAttribute attribute to the Structure statement.
Example
The following example uses the Structure statement to define a set of related data for an employee. It shows
the use of Public , Friend , and Private members to reflect the sensitivity of the data items. It also shows
procedure, property, and event members.
Public Structure employee
' Public members, accessible from throughout declaration region.
Public firstName As String
Public middleName As String
Public lastName As String
' Friend members, accessible from anywhere within the same assembly.
Friend employeeNumber As Integer
Friend workPhone As Long
' Private members, accessible only from within the structure itself.
Private homePhone As Long
Private level As Integer
Private salary As Double
Private bonus As Double
' Procedure member, which can access structure's private members.
Friend Sub calculateBonus(ByVal rate As Single)
bonus = salary * CDbl(rate)
End Sub
' Property member to return employee's eligibility.
Friend ReadOnly Property eligible() As Boolean
Get
Return level >= 25
End Get
End Property
' Event member, raised when business phone number has changed.
Public Event changedWorkPhone(ByVal newPhone As Long)
End Structure
See Also
Class Statement
Interface Statement
Module Statement
Dim Statement
Const Statement
Enum Statement
Event Statement
Operator Statement
Property Statement
Structures and Classes
Sub Statement (Visual Basic)
7/29/2017 • 6 min to read • Edit Online
Declares the name, parameters, and code that define a Sub procedure.
Syntax
[ <attributelist> ] [ Partial ] [ accessmodifier ] [ proceduremodifiers ] [ Shared ] [ Shadows ] [
Async ]
Sub name [ (Of typeparamlist) ] [ (parameterlist) ] [ Implements implementslist | Handles eventlist
]
[ statements ]
[ Exit Sub ]
[ statements ]
End Sub
Parts
attributelist
Shared
Required. Name of the procedure. See Declared Element Names. To create a constructor
procedure for a class, set the name of a Sub procedure to the New keyword. For more
information, see Object Lifetime: How Objects Are Created and Destroyed.
typeparamlist
Optional. List of type parameters for a generic procedure. See Type List.
parameterlist
Optional. List of local variable names representing the parameters of this procedure. See
Parameter List.
Implements
Optional. Indicates that this procedure implements one or more Sub procedures, each one
defined in an interface implemented by this procedure's containing class or structure. See
Implements Statement.
implementslist
PART DESCRIPTION
Handles
Optional. Indicates that this procedure can handle one or more specific events. See Handles.
eventlist
PART DESCRIPTION
statements
Remarks
All executable code must be inside a procedure. Use a Sub procedure when you don't want to return a
value to the calling code. Use a Function procedure when you want to return a value.
The Exit Sub and statements cause an immediate exit from a Sub procedure. Any number of
Return
Exit Sub and Return statements can appear anywhere in the procedure, and you can mix Exit Sub
and Return statements.
NOTE
An Async procedure returns to the caller when either the first awaited object that’s not yet complete is
encountered or the end of the Async procedure is reached, whichever occurs first.
You can also mark a Function Statement with the Async modifier. An Async function can have a return
type of Task<TResult> or Task. An example later in this topic shows an Async function that has a return
type of Task<TResult>.
Async Sub procedures are primarily used for event handlers, where a value can't be returned. An
Async``Sub procedure can't be awaited, and the caller of an Async``Sub procedure can't catch
exceptions that the Sub procedure throws.
An Async procedure can't declare any ByRef parameters.
For more information about Async procedures, see Asynchronous Programming with Async and Await,
Control Flow in Async Programs, and Async Return Types.
Example
The following example uses the Sub statement to define the name, parameters, and code that form the
body of a Sub procedure.
Sub computeArea(ByVal length As Double, ByVal width As Double)
' Declare local variable.
Dim area As Double
If length = 0 Or width = 0 Then
' If either argument = 0 then exit Sub immediately.
Exit Sub
End If
' Calculate area of rectangle.
area = length * width
' Print area to Immediate window.
Debug.WriteLine(area)
End Sub
Example
In the following example, DelayAsync is an an Async``Function that has a return type of Task<TResult>.
DelayAsync has a Return statement that returns an integer. Therefore, the function declaration of
DelayAsync must have a return type of Task(Of Integer) . Because the return type is Task(Of Integer) ,
the evaluation of the Await expression in DoSomethingAsync produces an integer, as the following
statement shows: Dim result As Integer = Await delayTask .
The startButton_Click procedure is an example of an Async Sub procedure. Because DoSomethingAsync
is an Async function, the task for the call to DoSomethingAsync must be awaited, as the following
statement shows: Await DoSomethingAsync() . The startButton_Click``Sub procedure must be defined
with the Async modifier because it has an Await expression.
' Output:
' Result: 5
See Also
Implements Statement
Function Statement
Parameter List
Dim Statement
Call Statement
Of
Parameter Arrays
How to: Use a Generic Class
Troubleshooting Procedures
Partial Methods
SyncLock Statement
7/29/2017 • 5 min to read • Edit Online
Acquires an exclusive lock for a statement block before executing the block.
Syntax
SyncLock lockobject
[ block ]
End SyncLock
Parts
lockobject
Required. Expression that evaluates to an object reference.
block
Optional. Block of statements that are to execute when the lock is acquired.
End SyncLock
Terminates a SyncLock block.
Remarks
The SyncLock statement ensures that multiple threads do not execute the statement block at the same time.
SyncLock prevents each thread from entering the block until no other thread is executing it.
The most common use of SyncLock is to protect data from being updated by more than one thread
simultaneously. If the statements that manipulate the data must go to completion without interruption, put them
inside a SyncLock block.
A statement block protected by an exclusive lock is sometimes called a critical section.
Rules
Branching. You cannot branch into a SyncLock block from outside the block.
Lock Object Value. The value of lockobject cannot be Nothing . You must create the lock object before you
use it in a SyncLock statement.
You cannot change the value of lockobject while executing a SyncLock block. The mechanism requires
that the lock object remain unchanged.
You can't use the Await operator in a SyncLock block.
Behavior
Mechanism. When a thread reaches the SyncLock statement, it evaluates the lockobject expression and
suspends execution until it acquires an exclusive lock on the object returned by the expression. When
another thread reaches the SyncLock statement, it does not acquire a lock until the first thread executes the
End SyncLock statement.
Protected Data. If lockobject is a Shared variable, the exclusive lock prevents a thread in any instance of
the class from executing the SyncLock block while any other thread is executing it. This protects data that is
shared among all the instances.
If lockobject is an instance variable (not Shared ), the lock prevents a thread running in the current
instance from executing the SyncLock block at the same time as another thread in the same instance. This
protects data maintained by the individual instance.
Acquisition and Release. A SyncLock block behaves like a Try...Finally construction in which the Try
block acquires an exclusive lock on lockobject and the Finally block releases it. Because of this, the
SyncLock block guarantees release of the lock, no matter how you exit the block. This is true even in the
case of an unhandled exception.
Framework Calls. The SyncLock block acquires and releases the exclusive lock by calling the Enter and
Exit methods of the Monitor class in the System.Threading namespace.
Programming Practices
The lockobject expression should always evaluate to an object that belongs exclusively to your class. You should
declare a Private object variable to protect data belonging to the current instance, or a Private Shared object
variable to protect data common to all instances.
You should not use the Me keyword to provide a lock object for instance data. If code external to your class has a
reference to an instance of your class, it could use that reference as a lock object for a SyncLock block completely
different from yours, protecting different data. In this way, your class and the other class could block each other
from executing their unrelated SyncLock blocks. Similarly locking on a string can be problematic since any other
code in the process using the same string will share the same lock.
You should also not use the Me.GetType method to provide a lock object for shared data. This is because GetType
always returns the same Type object for a given class name. External code could call GetType on your class and
obtain the same lock object you are using. This would result in the two classes blocking each other from their
SyncLock blocks.
Examples
Description
The following example shows a class that maintains a simple list of messages. It holds the messages in an array
and the last used element of that array in a variable. The addAnotherMessage procedure increments the last
element and stores the new message. Those two operations are protected by the SyncLock and End SyncLock
statements, because once the last element has been incremented, the new message must be stored before any
other thread can increment the last element again.
If the class shared one list of messages among all its instances, the variables messagesList and
simpleMessageList
messagesLast would be declared as Shared . In this case, the variable messagesLock should also be Shared , so
that there would be a single lock object used by every instance.
Code
Class simpleMessageList
Public messagesList() As String = New String(50) {}
Public messagesLast As Integer = -1
Private messagesLock As New Object
Public Sub addAnotherMessage(ByVal newMessage As String)
SyncLock messagesLock
messagesLast += 1
If messagesLast < messagesList.Length Then
messagesList(messagesLast) = newMessage
End If
End SyncLock
End Sub
End Class
Description
The following example uses threads and SyncLock . As long as the SyncLock statement is present, the statement
block is a critical section and balance never becomes a negative number. You can comment out the SyncLock
and End SyncLock statements to see the effect of leaving out the SyncLock keyword.
Code
Imports System.Threading
Module Module1
Class Account
Dim thisLock As New Object
Dim balance As Integer
' Comment out the SyncLock and End SyncLock lines to see
' the effect of leaving out the SyncLock keyword.
SyncLock thisLock
If balance >= amount Then
Console.WriteLine("Balance before Withdrawal : " & balance)
Console.WriteLine("Amount to Withdraw : -" & amount)
balance = balance - amount
Console.WriteLine("Balance after Withdrawal : " & balance)
Return amount
Else
' Transaction rejected.
Return 0
End If
End SyncLock
End Function
Sub Main()
Dim threads(10) As Thread
Dim acc As New Account(1000)
For i As Integer = 0 To 9
Dim t As New Thread(New ThreadStart(AddressOf acc.DoTransactions))
threads(i) = t
Next
For i As Integer = 0 To 9
threads(i).Start()
Next
End Sub
End Module
Comments
See Also
System.Threading
Monitor
Thread Synchronization
Threading
Then Statement
7/29/2017 • 1 min to read • Edit Online
Remarks
The Then keyword can be used in these contexts:
#If...Then...#Else Directive
If...Then...Else Statement
See Also
Keywords
Throw Statement (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
Syntax
Throw [ expression ]
Part
expression
Provides information about the exception to be thrown. Optional when residing in a Catch statement, otherwise
required.
Remarks
The Throw statement throws an exception that you can handle with structured exception-handling code ( Try ...
Catch ... Finally ) or unstructured exception-handling code ( On Error GoTo ). You can use the Throw statement to
trap errors within your code because Visual Basic moves up the call stack until it finds the appropriate exception-
handling code.
A Throw statement with no expression can only be used in a Catch statement, in which case the statement
rethrows the exception currently being handled by the Catch statement.
The Throw statement resets the call stack for the expression exception. If expression is not provided, the call
stack is left unchanged. You can access the call stack for the exception through the StackTrace property.
Example
The following code uses the Throw statement to throw an exception:
Requirements
Namespace: Microsoft.VisualBasic
Module: Interaction
See Also
Try...Catch...Finally Statement
On Error Statement
Try...Catch...Finally Statement (Visual Basic)
7/29/2017 • 13 min to read • Edit Online
Provides a way to handle some or all possible errors that may occur in a given block of code, while still
running code.
Syntax
Try
[ tryStatements ]
[ Exit Try ]
[ Catch [ exception [ As type ] ] [ When expression ]
[ catchStatements ]
[ Exit Try ] ]
[ Catch ... ]
[ Finally
[ finallyStatements ] ]
End Try
Parts
TERM DEFINITION
Remarks
If you expect that a particular exception might occur during a particular section of code, put the code in a
Try block and use a Catch block to retain control and handle the exception if it occurs.
A Try…Catch statement consists of a Try block followed by one or more Catch clauses, which specify
handlers for various exceptions. When an exception is thrown in a Try block, Visual Basic looks for the
Catch statement that handles the exception. If a matching Catch statement is not found, Visual Basic
examines the method that called the current method, and so on up the call stack. If no Catch block is found,
Visual Basic displays an unhandled exception message to the user and stops execution of the program.
You can use more than one Catch statement in a Try…Catch statement. If you do this, the order of the
Catch clauses is significant because they are examined in order. Catch the more specific exceptions before
the less specific ones.
The following Catch statement conditions are the least specific, and will catch all exceptions that derive from
the Exception class. You should ordinarily use one of these variations as the last Catch block in the
Try...Catch...Finally structure, after catching all the specific exceptions you expect. Control flow can never
reach a Catch block that follows either of these variations.
The type is Exception , for example: Catch ex As Exception
When a Try…Catch…Finally statement is nested in another Try block, Visual Basic first examines each
Catch statement in the innermost Try block. If no matching Catch statement is found, the search proceeds
to the Catch statements of the outer Try…Catch…Finally block.
Local variables from a Try block are not available in a Catch block because they are separate blocks. If you
want to use a variable in more than one block, declare the variable outside the Try...Catch...Finally
structure.
TIP
The Try…Catch…Finally statement is available as an IntelliSense code snippet. In the Code Snippets Manager,
expand Code Patterns - If, For Each, Try Catch, Property, etc, and then Error Handling (Exceptions). For more
information, see Code Snippets.
Finally Block
If you have one or more statements that must run before you exit the Try structure, use a Finally block.
Control passes to the Finally block just before it passes out of the Try…Catch structure. This is true even if
an exception occurs anywhere inside the Try structure.
A Finally block is useful for running any code that must execute even if there is an exception. Control is
passed to the Finally block regardless of how the Try...Catch block exits.
The code in a Finally block runs even if your code encounters a Return statement in a Try or Catch
block. Control does not pass from a Try or Catch block to the corresponding Finally block in the
following cases:
An End Statement is encountered in the Try or Catch block.
A StackOverflowException is thrown in the Try or Catch block.
It is not valid to explicitly transfer execution into a Finally block. Transferring execution out of a Finally
block is not valid, except through an exception.
If a Try statement does not contain at least one Catch block, it must contain a Finally block.
TIP
If you do not have to catch specific exceptions, the Using statement behaves like a Try…Finally block, and
guarantees disposal of the resources, regardless of how you exit the block. This is true even with an unhandled
exception. For more information, see Using Statement.
Exception Argument
The Catch block exception argument is an instance of the Exception class or a class that derives from the
Exception class. The Exception class instance corresponds to the error that occurred in the Try block.
The properties of the Exception object help to identify the cause and location of an exception. For example,
the StackTrace property lists the called methods that led to the exception, helping you find where the error
occurred in the code. Message returns a message that describes the exception. HelpLink returns a link to an
associated Help file. InnerException returns the Exception object that caused the current exception, or it
returns Nothing if there is no original Exception .
Console.Write(sr.ReadToEnd)
sr.Close()
End If
End Sub
Ensure that code in Catch blocks can properly report exceptions to users, whether through thread-safe
logging or appropriate messages. Otherwise, exceptions might remain unknown.
Async Methods
If you mark a method with the Async modifier, you can use the Await operator in the method. A statement
with the Await operator suspends execution of the method until the awaited task completes. The task
represents ongoing work. When the task that's associated with the Await operator finishes, execution
resumes in the same method. For more information, see Control Flow in Async Programs.
A task returned by an Async method may end in a faulted state, indicating that it completed due to an
unhandled exception. A task may also end in a canceled state, which results in an
OperationCanceledException being thrown out of the await expression. To catch either type of exception,
place the Await expression that's associated with the task in a Try block, and catch the exception in the
Catch block. An example is provided later in this topic.
A task can be in a faulted state because multiple exceptions were responsible for its faulting. For example, the
task might be the result of a call to System.Threading.Tasks.Task.WhenAll. When you await such a task, the
caught exception is only one of the exceptions, and you can't predict which exception will be caught. An
example is provided later in this topic.
An Await expression can't be inside a Catch block or Finally block.
Iterators
An iterator function or Get accessor performs a custom iteration over a collection. An iterator uses a Yield
statement to return each element of the collection one at a time. You call an iterator function by using a For
Each...Next Statement.
A statement can be inside a Try block. A Try block that contains a Yield statement can have
Yield
Catchblocks, and can have a Finally block. See the "Try Blocks in Visual Basic" section of Iterators for an
example.
A Yield statement cannot be inside a Catch block or a Finally block.
If the For Each body (outside of the iterator function) throws an exception, a Catch block in the iterator
function is not executed, but a Finally block in the iterator function is executed. A Catch block inside an
iterator function catches only exceptions that occur inside the iterator function.
Partial-Trust Situations
In partial-trust situations, such as an application hosted on a network share, Try...Catch...Finally does not
catch security exceptions that occur before the method that contains the call is invoked. The following
example, when you put it on a server share and run from there, produces the error
"System.Security.SecurityException: Request Failed." For more information about security exceptions, see the
SecurityException class.
Try
Process.Start("http://www.microsoft.com")
Catch ex As Exception
MsgBox("Can't load Web page" & vbCrLf & ex.Message)
End Try
In such a partial-trust situation, you have to put the Process.Start statement in a separate Sub . The initial
call to the Sub will fail. This enables Try...Catch to catch it before the Sub that contains Process.Start is
started and the security exception produced.
Example
The following example illustrates the structure of the Try...Catch...Finally statement.
Example
In the following example, the CreateException method throws a NullReferenceException . The code that
generates the exception is not in a Try block. Therefore, the CreateException method does not handle the
exception. The RunSample method does handle the exception because the call to the CreateException
method is in a Try block.
The example includes Catch statements for several types of exceptions, ordered from the most specific to
the most general.
Example
The following example shows how to use a Catch When statement to filter on a conditional expression. If the
conditional expression evaluates to True , the code in the Catch block runs.
Try
Throw New ArgumentException()
Catch e As OverflowException When i = 5
Console.WriteLine("First handler")
Catch e As ArgumentException When i = 4
Console.WriteLine("Second handler")
Catch When i = 5
Console.WriteLine("Third handler")
End Try
End Sub
' Output: Third handler
Example
The following example has a Try…Catch statement that is contained in a Try block. The inner Catch block
throws an exception that has its InnerException property set to the original exception. The outer Catch
block reports its own exception and the inner exception.
Private Sub InnerExceptionExample()
Try
Try
' Set a reference to a StringBuilder.
' The exception below does not occur if the commented
' out statement is used instead.
Dim sb As System.Text.StringBuilder
'Dim sb As New System.Text.StringBuilder
Example
The following example illustrates exception handling for async methods. To catch an exception that applies to
an async task, the Await expression is in a Try block of the caller, and the exception is caught in the Catch
block.
Uncomment the Throw New Exception line in the example to demonstrate exception handling. The exception
is caught in the Catch block, the task's IsFaulted property is set to True , and the task's
Exception.InnerException property is set to the exception.
Uncomment the Throw New OperationCancelledException line to demonstrate what happens when you cancel
an asynchronous process. The exception is caught in the Catch block, and the task's IsCanceled property is
set to True . However, under some conditions that don't apply to this example, IsFaulted is set to True and
IsCanceled is set to False .
Public Async Function DoSomethingAsync() As Task
Dim theTask As Task(Of String) = DelayAsync()
Try
Dim result As String = Await theTask
Debug.WriteLine("Result: " & result)
Catch ex As Exception
Debug.WriteLine("Exception Message: " & ex.Message)
End Try
Example
The following example illustrates exception handling where multiple tasks can result in multiple exceptions.
The Try block has the Await expression for the task that System.Threading.Tasks.Task.WhenAll returned.
The task is complete when the three tasks to which System.Threading.Tasks.Task.WhenAll is applied are
complete.
Each of the three tasks causes an exception. The Catch block iterates through the exceptions, which are
found in the Exception.InnerExceptions property of the task that Task.WhenAll returned.
Public Async Function DoMultipleAsync() As Task
Dim theTask1 As Task = ExcAsync(info:="First Task")
Dim theTask2 As Task = ExcAsync(info:="Second Task")
Dim theTask3 As Task = ExcAsync(info:="Third Task")
Try
Await allTasks
Catch ex As Exception
Debug.WriteLine("Exception: " & ex.Message)
Debug.WriteLine("Task IsFaulted: " & allTasks.IsFaulted)
For Each inEx In allTasks.Exception.InnerExceptions
Debug.WriteLine("Task Inner Exception: " + inEx.Message)
Next
End Try
End Function
' Output:
' Exception: Error-First Task
' Task IsFaulted: True
' Task Inner Exception: Error-First Task
' Task Inner Exception: Error-Second Task
' Task Inner Exception: Error-Third Task
See Also
Err
Exception
Exit Statement
On Error Statement
Best Practices for Using Code Snippets
Exception Handling
Throw Statement
Using Statement (Visual Basic)
7/29/2017 • 4 min to read • Edit Online
Declares the beginning of a Using block and optionally acquires the system resources that the block controls.
Syntax
Using { resourcelist | resourceexpression }
[ statements ]
End Using
Parts
TERM DEFINITION
End Using Required. Terminates the definition of the Using block and
disposes of all the resources that it controls.
Each resource in the resourcelist part has the following syntax and parts:
resourcename As New resourcetype [ ( [ arglist ] ) ]
-or-
resourcename As resourcetype = resourceexpression
resourcelist Parts
TERM DEFINITION
resourcetype Required. The class of the resource. The class must implement
the IDisposable interface.
TERM DEFINITION
Remarks
Sometimes your code requires an unmanaged resource, such as a file handle, a COM wrapper, or a SQL
connection. A Using block guarantees the disposal of one or more such resources when your code is finished
with them. This makes them available for other code to use.
Managed resources are disposed of by the .NET Framework garbage collector (GC) without any extra coding on
your part. You do not need a Using block for managed resources. However, you can still use a Using block to
force the disposal of a managed resource instead of waiting for the garbage collector.
A Using block has three parts: acquisition, usage, and disposal.
Acquisition means creating a variable and initializing it to refer to the system resource. The Using
statement can acquire one or more resources, or you can acquire exactly one resource before entering the
block and supply it to the Using statement. If you supply resourceexpression , you must acquire the
resource before passing control to the Using statement.
Usage means accessing the resources and performing actions with them. The statements between Using
and End Using represent the usage of the resources.
Disposal means calling the Dispose method on the object in resourcename . This allows the object to cleanly
terminate its resources. The End Using statement disposes of the resources under the Using block's
control.
Behavior
A block behaves like a Try ... Finally construction in which the Try block uses the resources and the
Using
Finally block disposes of them. Because of this, the Using block guarantees disposal of the resources, no matter
how you exit the block. This is true even in the case of an unhandled exception, except for a
StackOverflowException.
The scope of every resource variable acquired by the Using statement is limited to the Using block.
If you specify more than one system resource in the Using statement, the effect is the same as if you nested
Using blocks one within another.
NOTE
The code inside the Using block should not assign the object in resourcename to another variable. When you exit the
Using block, the resource is disposed, and the other variable cannot access the resource to which it points.
Example
The following example creates a file that is named log.txt and writes two lines of text to the file. The example also
reads that same file and displays the lines of text.
Because the TextWriter and TextReader classes implement the IDisposable interface, the code can use Using
statements to ensure that the file is correctly closed after the write and read operations.
line = reader.ReadLine()
Do Until line Is Nothing
Console.WriteLine(line)
line = reader.ReadLine()
Loop
End Using
End Sub
See Also
IDisposable
Try...Catch...Finally Statement
How to: Dispose of a System Resource
While...End While Statement (Visual Basic)
7/29/2017 • 3 min to read • Edit Online
Syntax
While condition
[ statements ]
[ Continue While ]
[ statements ]
[ Exit While ]
[ statements ]
End While
Parts
TERM DEFINITION
Remarks
Use a While...End While structure when you want to repeat a set of statements an indefinite number of times,
as long as a condition remains True . If you want more flexibility with where you test the condition or what
result you test it for, you might prefer the Do...Loop Statement. If you want to repeat the statements a set number
of times, the For...Next Statement is usually a better choice.
NOTE
The While keyword is also used in the Do...Loop Statement, the Skip While Clause and the Take While Clause.
If condition is True , all of the statements run until the End While statement is encountered. Control then
returns to the While statement, and condition is again checked. If condition is still True , the process is
repeated. If it’s False , control passes to the statement that follows the End While statement.
The While statement always checks the condition before it starts the loop. Looping continues while the
condition remains True . If condition is False when you first enter the loop, it doesn’t run even once.
The condition usually results from a comparison of two values, but it can be any expression that evaluates to a
Boolean Data Type value ( True or False ). This expression can include a value of another data type, such as a
numeric type, that has been converted to Boolean .
You can nest While loops by placing one loop within another. You can also nest different kinds of control
structures within one another. For more information, see Nested Control Structures.
Exit While
The Exit While statement can provide another way to exit a While loop. Exit While immediately transfers
control to the statement that follows the End While statement.
You typically use Exit While after some condition is evaluated (for example, in an If...Then...Else structure).
You might want to exit a loop if you detect a condition that makes it unnecessary or impossible to continue
iterating, such as an erroneous value or a termination request. You can use Exit While when you test for a
condition that could cause an endless loop, which is a loop that could run an extremely large or even infinite
number of times. You can then use Exit While to escape the loop.
You can place any number of Exit While statements anywhere in the While loop.
When used within nested While loops, Exit While transfers control out of the innermost loop and into the next
higher level of nesting.
The Continue While statement immediately transfers control to the next iteration of the loop. For more
information, see Continue Statement.
Example
In the following example, the statements in the loop continue to run until the index variable is greater than 10.
Debug.WriteLine("")
' Output: 0 1 2 3 4 5 6 7 8 9 10
Example
The following example illustrates the use of the Continue While and Exit While statements.
Dim index As Integer = 0
While index < 100000
index += 1
Debug.WriteLine("")
' Output: 1 2 3 4 9 10
Example
The following example reads all lines in a text file. The OpenText method opens the file and returns a
StreamReader that reads the characters. In the While condition, the Peek method of the StreamReader
determines whether the file contains additional characters.
sr.Close()
End If
End Sub
See Also
Loop Structures
Do...Loop Statement
For...Next Statement
Boolean Data Type
Nested Control Structures
Exit Statement
Continue Statement
With...End With Statement (Visual Basic)
7/29/2017 • 3 min to read • Edit Online
Executes a series of statements that repeatedly refer to a single object or structure so that the statements can use
a simplified syntax when accessing members of the object or structure. When using a structure, you can only read
the values of members or invoke methods, and you get an error if you try to assign values to members of a
structure used in a With...End With statement.
Syntax
With objectExpression
[ statements ]
End With
Parts
TERM DEFINITION
Remarks
By using With...End With , you can perform a series of statements on a specified object without specifying the
name of the object multiple times. Within a With statement block, you can specify a member of the object
starting with a period, as if the With statement object preceded it.
For example, to change multiple properties on a single object, place the property assignment statements inside
the With...End With block, referring to the object only once instead of once for each property assignment.
If your code accesses the same object in multiple statements, you gain the following benefits by using the With
statement:
You don't need to evaluate a complex expression multiple times or assign the result to a temporary
variable to refer to its members multiple times.
You make your code more readable by eliminating repetitive qualifying expressions.
The data type of objectExpression can be any class or structure type or even a Visual Basic elementary type such
as Integer . If objectExpression results in anything other than an object, you can only read the values of its
members or invoke methods, and you get an error if you try to assign values to members of a structure used in a
With...End With statement. This is the same error you would get if you invoked a method that returned a
structure and immediately accessed and assigned a value to a member of the function’s result, such as
GetAPoint().x = 1 . The problem in both cases is that the structure exists only on the call stack, and there is no
way a modified structure member in these situations can write to a location such that any other code in the
program can observe the change.
The objectExpression is evaluated once, upon entry into the block. You can't reassign the objectExpression from
within the With block.
Within a With block, you can access the methods and properties of only the specified object without qualifying
them. You can use methods and properties of other objects, but you must qualify them with their object names.
You can place one With...End With statement within another. Nested With...End With statements may be
confusing if the objects that are being referred to aren't clear from context. You must provide a fully qualified
reference to an object that's in an outer With block when the object is referenced from within an inner With
block.
You can't branch into a With statement block from outside the block.
Unless the block contains a loop, the statements run only once. You can nest different kinds of control structures.
For more information, see Nested Control Structures.
NOTE
You can use the With keyword in object initializers also. For more information and examples, see Object Initializers: Named
and Anonymous Types and Anonymous Types.
If you're using a With block only to initialize the properties or fields of an object that you've just instantiated, consider
using an object initializer instead.
Example
In the following example, each With block executes a series of statements on a single object.
With theCustomer
.Name = "Coho Vineyard"
.URL = "http://www.cohovineyard.com/"
.City = "Redmond"
End With
With theCustomer.Comments
.Add("First comment.")
.Add("Second comment.")
End With
End Sub
Example
The following example nests With…End With statements. Within the nested With statement, the syntax refers to
the inner object.
With theWindow
With .InfoLabel
.Content = "This is a message."
.Foreground = Brushes.DarkSeaGreen
.Background = Brushes.LightYellow
End With
See Also
List<T>
Nested Control Structures
Object Initializers: Named and Anonymous Types
Anonymous Types
Yield Statement (Visual Basic)
7/29/2017 • 4 min to read • Edit Online
Syntax
Yield expression
Parameters
TERM DEFINITION
Remarks
The Yield statement returns one element of a collection at a time. The Yield statement is included in an
iterator function or Get accessor, which perform custom iterations over a collection.
You consume an iterator function by using a For Each...Next Statement or a LINQ query. Each iteration of the
For Each loop calls the iterator function. When a Yield statement is reached in the iterator function,
expression is returned, and the current location in code is retained. Execution is restarted from that location the
next time that the iterator function is called.
An implicit conversion must exist from the type of expression in the Yield statement to the return type of the
iterator.
You can use an Exit Function or Return statement to end the iteration.
"Yield" is not a reserved word and has special meaning only when it is used in an Iterator function or Get
accessor.
For more information about iterator functions and Get accessors, see Iterators.
Exception Handling
A Yield statement can be inside a Try block of a Try...Catch...Finally Statement. A Try block that has a Yield
statement can have Catch blocks, and can have a Finally block.
A Yield statement cannot be inside a Catch block or a Finally block.
If the For Each body (outside of the iterator function) throws an exception, a Catch block in the iterator function
is not executed, but a Finally block in the iterator function is executed. A Catch block inside an iterator
function catches only exceptions that occur inside the iterator function.
Technical Implementation
The following code returns an IEnumerable (Of String) from an iterator function and then iterates through the
elements of the IEnumerable (Of String) .
The call to MyIteratorFunction doesn't execute the body of the function. Instead the call returns an
IEnumerable(Of String) into the elements variable.
On an iteration of the For Each loop, the MoveNext method is called for elements . This call executes the body of
MyIteratorFunction until the next Yield statement is reached. The Yield statement returns an expression that
determines not only the value of the element variable for consumption by the loop body but also the Current
property of elements, which is an IEnumerable (Of String) .
On each subsequent iteration of the For Each loop, the execution of the iterator body continues from where it
left off, again stopping when it reaches a Yield statement. The For Each loop completes when the end of the
iterator function or a Return or Exit Function statement is reached.
Example
The following example has a Yield statement that is inside a For…Next loop. Each iteration of the For Each
statement body in Main creates a call to the Power iterator function. Each call to the iterator function proceeds
to the next execution of the Yield statement, which occurs during the next iteration of the For…Next loop.
The return type of the iterator method is IEnumerable<T>, an iterator interface type. When the iterator method is
called, it returns an enumerable object that contains the powers of a number.
Sub Main()
For Each number In Power(2, 8)
Console.Write(number & " ")
Next
' Output: 2 4 8 16 32 64 128 256
Console.ReadKey()
End Sub
Dim result = 1
Example
The following example demonstrates a Get accessor that is an iterator. The property declaration includes an
Iterator modifier.
Sub Main()
Dim theGalaxies As New Galaxies
For Each theGalaxy In theGalaxies.NextGalaxy
With theGalaxy
Console.WriteLine(.Name & " " & .MegaLightYears)
End With
Next
Console.ReadKey()
End Sub
See Also
Iterators
Statements
Clauses (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
In This Section
Alias
As
Handles
Implements
In
Into
Of
Related Sections
Visual Basic Language Reference
Visual Basic
Alias Clause (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
Remarks
The Alias keyword can be used in this context:
Declare Statement
In the following example, the Alias keyword is used to provide the name of the function in advapi32.dll,
GetUserNameA , that getUserName is used in place of in this example. Function getUserName is called in sub getUser ,
which displays the name of the current user.
See Also
Keywords
As Clause (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
Introduces an As clause, which identifies a data type in a declaration statement or a constraint list on a generic
type parameter.
Remarks
The As keyword can be used in these contexts:
Aggregate Clause
Class Statement
Const Statement
Declare Statement
Delegate Statement
Dim Statement
Enum Statement
Event Statement
For...Next Statements
For Each...Next Statements
From Clause
Function Statement
Group Join Clause
Interface Statement
Operator Statement
Property Statement
Structure Statement
Sub Statement
Try...Catch...Finally Statements
See Also
How to: Create a New Variable
Data Types
Variable Declaration
Type List
Generic Types in Visual Basic
Keywords
Handles Clause (Visual Basic)
7/29/2017 • 2 min to read • Edit Online
Syntax
proceduredeclaration Handles eventlist
Parts
proceduredeclaration
The Sub procedure declaration for the procedure that will handle the event.
eventlist
List of the events for proceduredeclaration to handle, separated by commas. The events must be raised by either
the base class for the current class, or by an object declared using the WithEvents keyword.
Remarks
Use the Handles keyword at the end of a procedure declaration to cause it to handle events raised by an object
variable declared using the WithEvents keyword. The Handles keyword can also be used in a derived class to
handle events from a base class.
The Handles keyword and the AddHandler statement both allow you to specify that particular procedures
handle particular events, but there are differences. Use the Handles keyword when defining a procedure to
specify that it handles a particular event. The AddHandler statement connects procedures to events at run time.
For more information, see AddHandler Statement.
For custom events, the application invokes the event's AddHandler accessor when it adds the procedure as an
event handler. For more information on custom events, see Event Statement.
Example
Public Class ContainerClass
' Module or class level declaration.
WithEvents Obj As New Class1
The following example demonstrates how a derived class can use the Handles statement to handle an event
from a base class.
Example
The following example contains two button event handlers for a WPF Application project.
Example
The following example is equivalent to the previous example. The eventlist in the Handles clause contains the
events for both buttons.
Private Sub Button_Click(sender As System.Object, e As System.Windows.RoutedEventArgs) Handles
Button1.Click, Button2.Click
MessageBox.Show(sender.Name & " clicked")
End Sub
See Also
WithEvents
AddHandler Statement
RemoveHandler Statement
Event Statement
RaiseEvent Statement
Events
Implements Clause (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
Indicates that a class or structure member is providing the implementation for a member defined in an interface.
Remarks
The Implements keyword is not the same as the Implements Statement. You use the Implements statement to
specify that a class or structure implements one or more interfaces, and then for each member you use the
Implements keyword to specify which interface and which member it implements.
If a class or structure implements an interface, it must include the Implements statement immediately after the
Class Statement or Structure Statement, and it must implement all the members defined by the interface.
Reimplementation
In a derived class, you can reimplement an interface member that the base class has already implemented. This is
different from overriding the base class member in the following respects:
The base class member does not need to be Overridable to be reimplemented.
You can reimplement the member with a different name.
The Implements keyword can be used in the following contexts:
Event Statement
Function Statement
Property Statement
Sub Statement
See Also
Implements Statement
Interface Statement
Class Statement
Structure Statement
In Clause (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
Specifies the group that the loop variable is to traverse in a For Each loop, or specifies the collection to query in a
From , Join , or Group Join clause.
Remarks
The In keyword can be used in the following contexts:
For Each...Next Statement
From Clause
Join Clause
Group Join Clause
See Also
Keywords
Into Clause (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
Remarks
The Each keyword is used in the following contexts:
Aggregate Clause
Group By Clause
Group Join Clause
See Also
Keywords
Of Clause (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
Introduces an Of clause, which identifies a type parameter on a generic class, structure, interface, delegate, or
procedure. For information on generic types, see Generic Types in Visual Basic.
If you complete the preceding class definition, you can construct a variety of dictionary classes from it. The
types you supply to entryType and keyType determine what type of entry the class holds and what type of key
it associates with each entry. Because of the constraint, you must supply to keyType a type that implements
IComparable.
The following code example creates an object that holds String entries and associates an Integer key with
each one. Integer implements IComparable and therefore satisfies the constraint on keyType .
See Also
IComparable
Type List
Generic Types in Visual Basic
In
Out
Declaration Contexts and Default Access Levels
(Visual Basic)
7/29/2017 • 1 min to read • Edit Online
This topic describes which Visual Basic types can be declared within which other types, and what their access
levels default to if not specified.
External reference (Declare Not allowed Public (not allowed in Not allowed
Statement) Interface )
Default property (Default) Not allowed Public (not allowed in Not allowed
Module )
See Also
Friend
Private
Public
Attribute List (Visual Basic)
7/29/2017 • 2 min to read • Edit Online
Specifies the attributes to be applied to a declared programming element. Multiple attributes are separated by
commas. Following is the syntax for one attribute.
Syntax
[ attributemodifier ] attributename [ ( attributearguments | attributeinitializer ) ]
Parts
attributemodifier
Required for attributes applied at the beginning of a source file. Can be Assembly or Module.
attributename
Required. Name of the attribute.
attributearguments
Optional. List of positional arguments for this attribute. Multiple arguments are separated by commas.
attributeinitializer
Optional. List of variable or property initializers for this attribute. Multiple initializers are separated by commas.
Remarks
You can apply one or more attributes to nearly any programming element (types, procedures, properties, and
so forth). Attributes appear in your assembly's metadata, and they can help you annotate your code or specify
how to use a particular programming element. You can apply attributes defined by Visual Basic and the .NET
Framework, and you can define your own attributes.
For more information on when to use attributes, see Attributes overview. For information on attribute names,
see Declared Element Names.
Rules
Placement. You can apply attributes to most declared programming elements. To apply one or more
attributes, you place an attribute block at the beginning of the element declaration. Each entry in the
attribute list specifies an attribute you wish to apply, and the modifier and arguments you are using for
this invocation of the attribute.
Angle Brackets. If you supply an attribute list, you must enclose it in angle brackets (" < " and " > ").
Part of the Declaration. The attribute must be part of the element declaration, not a separate
statement. You can use the line-continuation sequence (" _ ") to extend the declaration statement onto
multiple source-code lines.
Modifiers. An attribute modifier ( Assembly or Module ) is required on every attribute applied to a
programming element at the beginning of a source file. Attribute modifiers are not allowed on
attributes applied to elements that are not at the beginning of a source file.
Arguments. All positional arguments for an attribute must precede any variable or property initializers.
Example
The following example applies the DllImportAttribute attribute to a skeleton definition of a Function
procedure.
<DllImportAttribute("kernel32.dll", EntryPoint:="MoveFileW",
SetLastError:=True, CharSet:=CharSet.Unicode,
ExactSpelling:=True,
CallingConvention:=CallingConvention.StdCall)>
Public Shared Function moveFile(ByVal src As String,
ByVal dst As String) As Boolean
' This function copies a file from the path src to the path dst.
' Leave this function empty. The DLLImport attribute forces calls
' to moveFile to be forwarded to MoveFileW in KERNEL32.DLL.
End Function
DllImportAttribute indicates that the attributed procedure represents an entry point in an unmanaged
dynamic-link library (DLL). The attribute supplies the DLL name as a positional argument and the other
information as variable initializers.
See Also
Assembly
Module <keyword>
Attributes overview
How to: Break and Combine Statements in Code
Parameter List (Visual Basic)
7/29/2017 • 3 min to read • Edit Online
Specifies the parameters a procedure expects when it is called. Multiple parameters are separated by commas.
The following is the syntax for one parameter.
Syntax
[ <attributelist> ] [ Optional ] [{ ByVal | ByRef }] [ ParamArray ]
parametername[( )] [ As parametertype ] [ = defaultvalue ]
Parts
attributelist
Optional. List of attributes that apply to this parameter. You must enclose the Attribute List in angle brackets ("
< " and " > ").
Optional
Optional. Specifies that this parameter is not required when the procedure is called.
ByVal
Optional. Specifies that the procedure cannot replace or reassign the variable element underlying the
corresponding argument in the calling code.
ByRef
Optional. Specifies that the procedure can modify the underlying variable element in the calling code the same
way the calling code itself can.
ParamArray
Optional. Specifies that the last parameter in the parameter list is an optional array of elements of the specified
data type. This lets the calling code pass an arbitrary number of arguments to the procedure.
parametername
Required. Name of the local variable representing the parameter.
parametertype
Required if Option Strict is On . Data type of the local variable representing the parameter.
defaultvalue
Required for Optional parameters. Any constant or constant expression that evaluates to the data type of the
parameter. If the type is Object , or a class, interface, array, or structure, the default value can only be Nothing .
Remarks
Parameters are surrounded by parentheses and separated by commas. A parameter can be declared with any
data type. If you do not specify parametertype , it defaults to Object .
When the calling code calls the procedure, it passes an argument to each required parameter. For more
information, see Differences Between Parameters and Arguments.
The argument the calling code passes to each parameter is a pointer to an underlying element in the calling
code. If this element is nonvariable (a constant, literal, enumeration, or expression), it is impossible for any code
to change it. If it is a variable element (a declared variable, field, property, array element, or structure element),
the calling code can change it. For more information, see Differences Between Modifiable and Nonmodifiable
Arguments.
If a variable element is passed ByRef , the procedure can change it as well. For more information, see
Differences Between Passing an Argument By Value and By Reference.
Rules
Parentheses. If you specify a parameter list, you must enclose it in parentheses. If there are no
parameters, you can still use parentheses enclosing an empty list. This improves the readability of your
code by clarifying that the element is a procedure.
Optional Parameters. If you use the Optional modifier on a parameter, all subsequent parameters in
the list must also be optional and be declared by using the Optional modifier.
Every optional parameter declaration must supply the defaultvalue clause.
For more information, see Optional Parameters.
Parameter Arrays. You must specify ByVal for a ParamArray parameter.
You cannot use both Optional and ParamArray in the same parameter list.
For more information, see Parameter Arrays.
Passing Mechanism. The default mechanism for every argument is ByVal , which means the procedure
cannot change the underlying variable element. However, if the element is a reference type, the
procedure can modify the contents or members of the underlying object, even though it cannot replace
or reassign the object itself.
Parameter Names. If the parameter's data type is an array, follow parametername immediately by
parentheses. For more information on parameter names, see Declared Element Names.
Example
The following example shows a Function procedure that defines two parameters.
See Also
DllImportAttribute
Function Statement
Sub Statement
Declare Statement
Structure Statement
Option Strict Statement
Attributes overview
How to: Break and Combine Statements in Code
Type List (Visual Basic)
8/11/2017 • 3 min to read • Edit Online
Specifies the type parameters for a generic programming element. Multiple parameters are separated by
commas. Following is the syntax for one type parameter.
Syntax
[genericmodifier] typename [ As constraintlist ]
Parts
TERM DEFINITION
Remarks
Every generic programming element must take at least one type parameter. A type parameter is a placeholder
for a specific type (a constructed element) that client code specifies when it creates an instance of the generic
type. You can define a generic class, structure, interface, procedure, or delegate.
For more information on when to define a generic type, see Generic Types in Visual Basic. For more
information on type parameter names, see Declared Element Names.
Rules
Parentheses. If you supply a type parameter list, you must enclose it in parentheses, and you must
introduce the list with the Of keyword. You use Of only once, at the beginning of the list.
Constraints. A list of constraints on a type parameter can include the following items in any
combination:
Any number of interfaces. The supplied type must implement every interface in this list.
At most one class. The supplied type must inherit from that class.
The New keyword. The supplied type must expose a parameterless constructor that your generic
type can access. This is useful if you constrain a type parameter by one or more interfaces. A type
that implements interfaces does not necessarily expose a constructor, and depending on the
access level of a constructor, the code within the generic type might not be able to access it.
Either the Class keyword or the Structure keyword. The Class keyword constrains a generic
type parameter to require that any type argument passed to it be a reference type, for example a
string, array, or delegate, or an object created from a class. The Structure keyword constrains a
generic type parameter to require that any type argument passed to it be a value type, for
example a structure, enumeration, or elementary data type. You cannot include both Class and
Structure in the same constraintlist .
The supplied type must satisfy every requirement you include in constraintlist .
Constraints on each type parameter are independent of constraints on other type parameters.
Behavior
Compile-Time Substitution. When you create a constructed type from a generic programming
element, you supply a defined type for each type parameter. The Visual Basic compiler substitutes that
supplied type for every occurrence of typename within the generic element.
Absence of Constraints. If you do not specify any constraints on a type parameter, your code is limited
to the operations and members supported by the Object Data Type for that type parameter.
Example
The following example shows a skeleton definition of a generic dictionary class, including a skeleton function
to add a new entry to the dictionary.
Example
Because dictionary is generic, the code that uses it can create a variety of objects from it, each having the
same functionality but acting on a different data type. The following example shows a line of code that creates
a dictionary object with String entries and Integer keys.
Example
The following example shows the equivalent skeleton definition generated by the preceding example.
Public Class dictionary
Public Sub add(ByVal et As String, ByVal kt As Integer)
Dim dk As Integer
If kt.CompareTo(dk) = 0 Then
End If
End Sub
End Class
See Also
Of
New Operator
Access levels in Visual Basic
Object Data Type
Function Statement
Structure Statement
Sub Statement
How to: Use a Generic Class
Covariance and Contravariance
In
Out
Recommended XML Tags for Documentation
Comments (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
The Visual Basic compiler can process documentation comments in your code to an XML file. You can use
additional tools to process the XML file into documentation.
XML comments are allowed on code constructs such as types and type members. For partial types, only one part
of the type can have XML comments, although there is no restriction on commenting its members.
NOTE
Documentation comments cannot be applied to namespaces. The reason is that one namespace can span several
assemblies, and not all assemblies have to be loaded at the same time.
The compiler processes any tag that is valid XML. The following tags provide commonly used functionality in
user documentation.
<typeparam> 1 <value>
NOTE
If you want angle brackets to appear in the text of a documentation comment, use < and > . For example, the string
"<text in angle brackets>" will appear as <text in angle``brackets> .
See Also
Documenting Your Code with XML
/doc
How to: Create XML Documentation
<c> (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
Syntax
<c>text</c>
Parameters
PARAMETER DESCRIPTION
Remarks
The <c> tag gives you a way to indicate that text within a description should be marked as code. Use <code> to
indicate multiple lines as code.
Compile with /doc to process documentation comments to a file.
Example
This example uses the <c> tag in the summary section to indicate that Counter is code.
''' <summary>
''' Resets the value the <c>Counter</c> field.
''' </summary>
Public Sub ResetCounter()
counterValue = 0
End Sub
Private counterValue As Integer = 0
''' <summary>
''' Returns the number of times Counter was called.
''' </summary>
''' <value>Number of times Counter was called.</value>
Public ReadOnly Property Counter() As Integer
Get
counterValue += 1
Return counterValue
End Get
End Property
See Also
XML Comment Tags
<code> (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
Syntax
<code>content</code>
Parameters
content
The text to mark as code.
Remarks
Use the <code> tag to indicate multiple lines as code. Use <c> to indicate that text within a description should be
marked as code.
Compile with /doc to process documentation comments to a file.
Example
This example uses the <code> tag to include example code for using the ID field.
See Also
XML Comment Tags
<example> (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
Syntax
<example>description</example>
Parameters
description
A description of the code sample.
Remarks
The <example> tag lets you specify an example of how to use a method or other library member. This commonly
involves using the <code> tag.
Compile with /doc to process documentation comments to a file.
Example
This example uses the <example> tag to include an example for using the ID field.
See Also
XML Comment Tags
<exception> (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
Syntax
<exception cref="member">description</exception>
Parameters
member
A reference to an exception that is available from the current compilation environment. The compiler checks that
the given exception exists and translates member to the canonical element name in the output XML. member must
appear within double quotation marks (" ").
description
A description.
Remarks
Use the <exception> tag to specify which exceptions can be thrown. This tag is applied to a method definition.
Compile with /doc to process documentation comments to a file.
Example
This example uses the <exception> tag to describe an exception that the IntDivide function can throw.
See Also
XML Comment Tags
<include> (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
Refers to another file that describes the types and members in your source code.
Syntax
<include file="filename" path="tagpath[@name='id']" />
Parameters
filename
Required. The name of the file containing the documentation. The file name can be qualified with a path. Enclose
filename in double quotation marks (" ").
tagpath
Required. The path of the tags in filename that leads to the tag name . Enclose the path in double quotation marks
(" ").
name
Required. The name specifier in the tag that precedes the comments. Name will have an id .
id
Required. The ID for the tag that precedes the comments. Enclose the ID in single quotation marks (' ').
Remarks
Use the <include> tag to refer to comments in another file that describe the types and members in your source
code. This is an alternative to placing documentation comments directly in your source code file.
The <include> tag uses the W3C XML Path Language (XPath) Version 1.0 Recommendation. More information for
ways to customize your <include> use is available at http://www.w3.org/TR/xpath.
Example
This example uses the <include> tag to import member documentation comments from a file called
commentFile.xml .
See Also
XML Comment Tags
<list> (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
Syntax
<list type="type">
<listheader>
<term>term</term>
<description>description</description>
</listheader>
<item>
<term>term</term>
<description>description</description>
</item>
</list>
Parameters
type
The type of the list. Must be a "bullet" for a bulleted list, "number" for a numbered list, or "table" for a two-column
table.
term
Only used when type is "table." A term to define, which is defined in the description tag.
description
When type is "bullet" or "number," description is an item in the list When type is "table," description is the
definition of term .
Remarks
The <listheader> block defines the heading of either a table or definition list. When defining a table, you only have
to supply an entry for term in the heading.
Each item in the list is specified with an <item> block. When creating a definition list, you must specify both term
and description . However, for a table, bulleted list, or numbered list, you only have to supply an entry for
description .
Example
This example uses the <list> tag to define a bulleted list in the remarks section.
''' <remarks>Before calling the <c>Reset</c> method, be sure to:
''' <list type="bullet">
''' <item><description>Close all connections.</description></item>
''' <item><description>Save the object state.</description></item>
''' </list>
''' </remarks>
Public Sub Reset()
' Code goes here.
End Sub
See Also
XML Comment Tags
<para> (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
Syntax
<para>content</para>
Parameters
content
The text of the paragraph.
Remarks
The <para> tag is for use inside a tag, such as <summary>, <remarks>, or <returns>, and lets you add structure
to the text.
Compile with /doc to process documentation comments to a file.
Example
This example uses the <para> tag to split the remarks section for the UpdateRecord method into two paragraphs.
See Also
XML Comment Tags
<param> (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
Syntax
<param name="name">description</param>
Parameters
name
The name of a method parameter. Enclose the name in double quotation marks (" ").
description
A description for the parameter.
Remarks
The <param> tag should be used in the comment for a method declaration to describe one of the parameters for
the method.
The text for the <param> tag will appear in the following locations:
Parameter Info of IntelliSense. For more information, see Using IntelliSense.
Object Browser. For more information, see Viewing the Structure of Code.
Compile with /doc to process documentation comments to a file.
Example
This example uses the <param> tag to describe the id parameter.
See Also
XML Comment Tags
<paramref> (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
Syntax
<paramref name="name"/>
Parameters
name
The name of the parameter to refer to. Enclose the name in double quotation marks (" ").
Remarks
The <paramref> tag gives you a way to indicate that a word is a parameter. The XML file can be processed to format
this parameter in some distinct way.
Compile with /doc to process documentation comments to a file.
Example
This example uses the <paramref> tag to refer to the id parameter.
See Also
XML Comment Tags
<permission> (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
Syntax
<permission cref="member">description</permission>
Parameters
member
A reference to a member or field that is available to be called from the current compilation environment. The
compiler checks that the given code element exists and translates member to the canonical element name in the
output XML. Enclose member in quotation marks (" ").
description
A description of the access to the member.
Remarks
Use the <permission> tag to document the access of a member. Use the PermissionSet class to specify access to a
member.
Compile with /doc to process documentation comments to a file.
Example
This example uses the <permission> tag to describe that the FileIOPermission is required by the ReadFile method.
See Also
XML Comment Tags
<remarks> (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
Syntax
<remarks>description</remarks>
Parameters
description
A description of the member.
Remarks
Use the <remarks> tag to add information about a type, supplementing the information specified with
<summary>.
This information appears in the Object Browser. For information about the Object Browser, see Viewing the
Structure of Code.
Compile with /doc to process documentation comments to a file.
Example
This example uses the <remarks> tag to explain what the UpdateRecord method does.
See Also
XML Comment Tags
<returns> (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
Syntax
<returns>description</returns>
Parameters
description
A description of the return value.
Remarks
Use the <returns> tag in the comment for a method declaration to describe the return value.
Compile with /doc to process documentation comments to a file.
Example
This example uses the <returns> tag to explain what the DoesRecordExist function returns.
See Also
XML Comment Tags
<see> (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
Syntax
<see cref="member"/>
Parameters
member
A reference to a member or field that is available to be called from the current compilation environment. The
compiler checks that the given code element exists and passes member to the element name in the output XML.
member must appear within double quotation marks (" ").
Remarks
Use the <see> tag to specify a link from within text. Use <seealso> to indicate text that you might want to appear
in a "See Also" section.
Compile with /doc to process documentation comments to a file.
Example
This example uses the <see> tag in the UpdateRecord remarks section to refer to the DoesRecordExist method.
See Also
XML Comment Tags
<seealso> (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
Syntax
<seealso cref="member"/>
Parameters
member
A reference to a member or field that is available to be called from the current compilation environment. The
compiler checks that the given code element exists and passes member to the element name in the output XML.
member must appear within double quotation marks (" ").
Remarks
Use the <seealso> tag to specify the text that you want to appear in a See Also section. Use <see> to specify a link
from within text.
Compile with /doc to process documentation comments to a file.
Example
This example uses the <seealso> tag in the DoesRecordExist remarks section to refer to the UpdateRecord method.
See Also
XML Comment Tags
<summary> (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
Syntax
<summary>description</summary>
Parameters
description
A summary of the object.
Remarks
Use the <summary> tag to describe a type or a type member. Use <remarks> to add supplemental information to a
type description.
The text for the <summary> tag is the only source of information about the type in IntelliSense, and is also displayed
in the Object Browser. For information about the Object Browser, see Viewing the Structure of Code.
Compile with /doc to process documentation comments to a file.
Example
This example uses the <summary> tag to describe the ResetCounter method and Counter property.
''' <summary>
''' Resets the value the <c>Counter</c> field.
''' </summary>
Public Sub ResetCounter()
counterValue = 0
End Sub
Private counterValue As Integer = 0
''' <summary>
''' Returns the number of times Counter was called.
''' </summary>
''' <value>Number of times Counter was called.</value>
Public ReadOnly Property Counter() As Integer
Get
counterValue += 1
Return counterValue
End Get
End Property
See Also
XML Comment Tags
<typeparam> (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
Syntax
<typeparam name="name">description</typeparam>
Parameters
name
The name of the type parameter. Enclose the name in double quotation marks (" ").
description
A description of the type parameter.
Remarks
Use the <typeparam> tag in the comment for a generic type or generic member declaration to describe one of the
type parameters.
Compile with /doc to process documentation comments to a file.
Example
This example uses the <typeparam> tag to describe the id parameter.
See Also
XML Comment Tags
<value> (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
Syntax
<value>property-description</value>
Parameters
property-description
A description for the property.
Remarks
Use the <value> tag to describe a property. Note that when you add a property using the code wizard in the Visual
Studio development environment, it will add a <summary> tag for the new property. You should then manually
add a <value> tag to describe the value that the property represents.
Compile with /doc to process documentation comments to a file.
Example
This example uses the <value> tag to describe what value the Counter property holds.
''' <summary>
''' Resets the value the <c>Counter</c> field.
''' </summary>
Public Sub ResetCounter()
counterValue = 0
End Sub
Private counterValue As Integer = 0
''' <summary>
''' Returns the number of times Counter was called.
''' </summary>
''' <value>Number of times Counter was called.</value>
Public ReadOnly Property Counter() As Integer
Get
counterValue += 1
Return counterValue
End Get
End Property
See Also
XML Comment Tags
XML Axis Properties (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
The topics in this section document the syntax of XML axis properties in Visual Basic. The XML axis properties
make it easy to access XML directly in your code.
In This Section
TOPIC DESCRIPTION
XML Attribute Axis Property Describes how to access the attributes of an XElement object.
XML Child Axis Property Describes how to access the children of an XElement object.
XML Descendant Axis Property Describes how to access the descendants of an XElement
object.
XML Value Property Describes how to access the value of the first element of a
collection of XElement or XAttribute objects.
See Also
XML
XML Attribute Axis Property (Visual Basic)
7/29/2017 • 2 min to read • Edit Online
Provides access to the value of an attribute for an XElement object or to the first element in a collection of XElement
objects.
Syntax
object.@attribute
-or-
object.@<attribute>
Parts
object
Required. An XElement object or a collection of XElement objects.
.@
Required. Denotes the start of an attribute axis property.
<
Optional. Denotes the beginning of the name of the attribute when attribute is not a valid identifier in Visual
Basic.
attribute
Required. Name of the attribute to access, of the form [ prefix :] name .
PART DESCRIPTION
>
Optional. Denotes the end of the name of the attribute when attribute is not a valid identifier in Visual Basic.
Return Value
A string that contains the value of attribute . If the attribute name does not exist, Nothing is returned.
Remarks
You can use an XML attribute axis property to access the value of an attribute by name from an XElement object or
from the first element in a collection of XElement objects. You can retrieve an attribute value by name, or add a new
attribute to an element by specifying a new name preceded by the @ identifier.
When you refer to an XML attribute using the @ identifier, the attribute value is returned as a string and you do not
need to explicitly specify the Value property.
The naming rules for XML attributes differ from the naming rules for Visual Basic identifiers. To access an XML
attribute that has a name that is not a valid Visual Basic identifier, enclose the name in angle brackets (< and >).
XML Namespaces
The name in an attribute axis property can use only XML namespace prefixes declared globally by using the
Imports statement. It cannot use XML namespace prefixes declared locally within XML element literals. For more
information, see Imports Statement (XML Namespace).
Example
The following example shows how to get the values of the XML attributes named type from a collection of XML
elements that are named phone .
Console.WriteLine(phoneTypes)
<type>home</type>
<type>work</type>
</phoneTypes>
Example
The following example shows how to create attributes for an XML element both declaratively, as part of the XML,
and dynamically by adding an attribute to an instance of an XElement object. The type attribute is created
declaratively and the owner attribute is created dynamically.
Console.WriteLine(phone2)
Example
The following example uses the angle bracket syntax to get the value of the XML attribute named number-type ,
which is not a valid identifier in Visual Basic.
Example
The following example declares ns as an XML namespace prefix. It then uses the prefix of the namespace to create
an XML literal and access the first child node with the qualified name " ns:name ".
Class TestClass3
End Class
See Also
XElement
XML Axis Properties
XML Literals
Creating XML in Visual Basic
Names of Declared XML Elements and Attributes
XML Child Axis Property (Visual Basic)
7/29/2017 • 2 min to read • Edit Online
Provides access to the children of one of the following: an XElement object, an XDocument object, a collection of
XElement objects, or a collection of XDocument objects.
Syntax
object.<child>
Parts
TERM DEFINITION
Return Value
A collection of XElement objects.
Remarks
You can use an XML child axis property to access child nodes by name from an XElement or XDocument object, or
from a collection of XElement or XDocument objects. Use the XML Value property to access the value of the first
child node in the returned collection. For more information, see XML Value Property.
The Visual Basic compiler converts child axis properties to calls to the Elements method.
XML Namespaces
The name in a child axis property can use only XML namespace prefixes declared globally with the Imports
statement. It cannot use XML namespace prefixes declared locally within XML element literals. For more
information, see Imports Statement (XML Namespace).
Example
The following example shows how to access the child nodes named phone from the contact object.
Example
The following example shows how to access the child nodes named phone from the collection returned by the
contact child axis property of the contacts object.
Example
The following example declares ns as an XML namespace prefix. It then uses the prefix of the namespace to create
an XML literal and access the first child node with the qualified name ns:name .
Imports <xmlns:ns = "http://SomeNamespace">
Class TestClass4
End Class
See Also
XElement
XML Axis Properties
XML Literals
Creating XML in Visual Basic
Names of Declared XML Elements and Attributes
XML Descendant Axis Property (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
Provides access to the descendants of the following: an XElement object, an XDocument object, a collection of
XElement objects, or a collection of XDocument objects.
Syntax
object...<descendant>
Parts
object
Required. An XElement object, an XDocument object, a collection of XElement objects, or a collection of XDocument
objects.
...<
Required. Denotes the start of a descendant axis property.
descendant
Required. Name of the descendant nodes to access, of the form [ prefix``: ] name .
PART DESCRIPTION
>
Required. Denotes the end of a descendant axis property.
Return Value
A collection of XElement objects.
Remarks
You can use an XML descendant axis property to access descendant nodes by name from an XElement or
XDocument object, or from a collection of XElement or XDocument objects. Use the XML Value property to access
the value of the first descendant node in the returned collection. For more information, see XML Value Property.
The Visual Basic compiler converts descendant axis properties into calls to the Descendants method.
XML Namespaces
The name in a descendant axis property can use only XML namespaces declared globally with the Imports
statement. It cannot use XML namespaces declared locally within XML element literals. For more information, see
Imports Statement (XML Namespace).
Example
The following example shows how to access the value of the first descendant node named name and the values of
all descendant nodes named phone from the contacts object.
Example
The following example declares ns as an XML namespace prefix. It then uses the prefix of the namespace to create
an XML literal and access the value of the first child node with the qualified name ns:name .
Class TestClass2
End Class
See Also
XElement
XML Axis Properties
XML Literals
Creating XML in Visual Basic
Names of Declared XML Elements and Attributes
Extension Indexer Property (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
Syntax
object(index)
Parts
TERM DEFINITION
Return Value
The object from the specified location in the collection, or Nothing if the index is out of range.
Remarks
You can use the extension indexer property to access individual elements in a collection. This indexer property is
typically used on the output of XML axis properties. The XML child and XML descendent axis properties return
collections of XElement objects or an attribute value.
The Visual Basic compiler converts extension indexer properties to calls to the ElementAtOrDefault method. Unlike
an array indexer, the ElementAtOrDefault method returns Nothing if the index is out of range. This behavior is
useful when you cannot easily determine the number of elements in a collection.
This indexer property is like an extension property for collections that implement IEnumerable<T> or
IQueryable<T>: it is used only if the collection does not have an indexer or a default property.
To access the value of the first element in a collection of XElement or XAttribute objects, you can use the XML
Value property. For more information, see XML Value Property.
Example
The following example shows how to use the extension indexer to access the second child node in a collection of
XElement objects. The collection is accessed by using the child axis property, which gets all child elements named
phone in the contact object.
Dim contact As XElement =
<contact>
<name>Patrick Hines</name>
<phone type="home">206-555-0144</phone>
<phone type="work">425-555-0145</phone>
</contact>
See Also
XElement
XML Axis Properties
XML Literals
Creating XML in Visual Basic
XML Value Property
XML Value Property (Visual Basic)
7/29/2017 • 2 min to read • Edit Online
Provides access to the value of the first element of a collection of XElement objects.
Syntax
object.Value
Parts
TERM DEFINITION
Return Value
A String that contains the value of the first element of the collection, or Nothing if the collection is empty.
Remarks
The Value property makes it easy to access the value of the first element in a collection of XElement objects. This
property first checks whether the collection contains at least one object. If the collection is empty, this property
returns Nothing . Otherwise, this property returns the value of the Value property of the first element in the
collection.
NOTE
When you access the value of an XML attribute using the '@' identifier, the attribute value is returned as a String and you
do not need to explicitly specify the Value property.
To access other elements in a collection, you can use the XML extension indexer property. For more information,
see Extension Indexer Property.
Inheritance
Most users will not have to implement IEnumerable<T>, and can therefore ignore this section.
The Value property is an extension property for types that implement IEnumerable(Of XElement) . The binding of
this extension property is like the binding of extension methods: if a type implements one of the interfaces and
defines a property that has the name "Value", that property has precedence over the extension property. In other
words, this Value property can be overridden by defining a new property in a class that implements
IEnumerable(Of XElement) .
Example
The following example shows how to use the Value property to access the first node in a collection of XElement
objects. The example uses the child axis property to get the collection of all child nodes named phone that are in
the contact object.
Example
The following example shows how to get the value of an XML attribute from a collection of XAttribute objects. The
example uses the attribute axis property to display the value of the type attribute for all of the the phone
elements.
work
See Also
XElement
IEnumerable<T>
XML Axis Properties
XML Literals
Creating XML in Visual Basic
Extension Methods
Extension Indexer Property
XML Child Axis Property
XML Attribute Axis Property
XML Literals (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
The topics in this section document the syntax of XML literals in Visual Basic. The XML literal syntax enables you
to incorporate XML directly in your code.
In This Section
TOPIC DESCRIPTION
XML Element Literal Describes the syntax for literals that represent XElement
objects.
XML Document Literal Describes the syntax for literals that represent XDocument
objects.
XML CDATA Literal Describes the syntax for literals that represent XCData
objects.
XML Comment Literal Describes the syntax for literals that represent XComment
objects.
XML Processing Instruction Literal Describes the syntax for literals that represent
XProcessingInstruction objects.
See Also
XML
XML Element Literal (Visual Basic)
8/1/2017 • 4 min to read • Edit Online
Syntax
<name [ attributeList ] />
-or-
<name [ attributeList ] > [ elementContents ] </[ name ]>
Parts
<
PART DESCRIPTION
Embedded expression of the form <%= nameExp %> . The type of nameExp must be String or a type
implicitly convertible to XName. An embedded expression is not allowed in a closing tag of an
element.
attributeList
Optional. Represents the closing tag for the element. The optional name parameter is not allowed when it is
the result of an embedded expression.
Return Value
An XElement object.
Remarks
You can use the XML element literal syntax to create XElement objects in your code.
NOTE
An XML literal can span multiple lines without using line continuation characters. This feature enables you to copy content
from an XML document and paste it directly into a Visual Basic program.
Embedded expressions of the form <%= exp %> enable you to add dynamic information to an XML element literal.
For more information, see Embedded Expressions in XML.
The Visual Basic compiler converts the XML element literal into calls to the XElement constructor and, if it is
required, the XAttribute constructor.
XML Namespaces
XML namespace prefixes are useful when you have to create XML literals with elements from the same namespace
many times in code. You can use global XML namespace prefixes, which you define by using the Imports
statement, or local prefixes, which you define by using the xmlns:xmlPrefix="xmlNamespace" attribute syntax. For
more information, see Imports Statement (XML Namespace).
In accordance with the scoping rules for XML namespaces, local prefixes take precedence over global prefixes.
However, if an XML literal defines an XML namespace, that namespace is not available to expressions that appear
in an embedded expression. The embedded expression can access only the global XML namespace.
The Visual Basic compiler converts each global XML namespace that is used by an XML literal into a one local
namespace definition in the generated code. Global XML namespaces that are not used do not appear in the
generated code.
Example
The following example shows how to create a simple XML element that has two nested empty elements.
Console.WriteLine(test1)
The example displays the following text. Notice that the literal preserves the structure of the empty elements.
<outer>
<inner1></inner1>
<inner2 />
</outer>
Example
The following example shows how to use embedded expressions to name an element and create attributes.
Dim elementType = "book"
Dim authorName = "My Author"
Dim attributeName1 = "year"
Dim attributeValue1 = 1999
Dim attributeName2 = "title"
Dim attributeValue2 = "My Book"
Console.WriteLine(book)
Example
The following example declares ns as an XML namespace prefix. It then uses the prefix of the namespace to
create an XML literal and displays the element's final form.
Class TestClass1
Dim test =
<ns:outer>
<ns:middle xmlns:ns="http://NewNamespace">
<ns:inner1/>
<%= inner2 %>
</ns:middle>
</ns:outer>
End Class
<ns:outer xmlns:ns="http://SomeNamespace">
<ns:middle xmlns:ns="http://NewNamespace">
<ns:inner1 />
<inner2 xmlns="http://SomeNamespace" />
</ns:middle>
</ns:outer>
Notice that the compiler converted the prefix of the global XML namespace into a prefix definition for the XML
namespace. The <ns:middle> element redefines the XML namespace prefix for the <ns:inner1> element. However,
the <ns:inner2> element uses the namespace defined by the Imports statement.
See Also
XElement
Names of Declared XML Elements and Attributes
XML Comment Literal
XML CDATA Literal
XML Literals
Creating XML in Visual Basic
Embedded Expressions in XML
Imports Statement (XML Namespace)
XML Document Literal (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
Syntax
<?xml version="1.0" [encoding="encoding"] [standalone="standalone"] ?>
[ piCommentList ]
rootElement
[ piCommentList ]
Parts
TERM DEFINITION
An XElement object.
A collection that contains one XElement object
and any number of XProcessingInstruction and
XComment objects.
Return Value
An XDocument object.
Remarks
An XML document literal is identified by the XML declaration at the start of the literal. Although each XML
document literal must have exactly one root XML element, it can have any number of XML processing instructions
and XML comments.
An XML document literal cannot appear in an XML element.
NOTE
An XML literal can span multiple lines without using line continuation characters. This enables you to copy content from an
XML document and paste it directly into a Visual Basic program.
The Visual Basic compiler converts the XML document literal into calls to the XDocument and XDeclaration
constructors.
Example
The following example creates an XML document that has an XML declaration, a processing instruction, a comment,
and an element that contains another element.
See Also
XElement
XProcessingInstruction
XComment
XDocument
XML Processing Instruction Literal
XML Comment Literal
XML Element Literal
XML Literals
Creating XML in Visual Basic
Embedded Expressions in XML
XML CDATA Literal (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
Syntax
<![CDATA[content]]>
Parts
<![CDATA[
Required. Denotes the start of the XML CDATA section.
content
Required. Text content to appear in the XML CDATA section.
]]>
Required. Denotes the end of the section.
Return Value
An XCData object.
Remarks
XML CDATA sections contain raw text that should be included, but not parsed, with the XML that contains it. A XML
CDATA section can contain any text. This includes reserved XML characters. The XML CDATA section ends with the
sequence "]]>". This implies the following points:
You cannot use an embedded expression in an XML CDATA literal because the embedded expression
delimiters are valid XML CDATA content.
XML CDATA sections cannot be nested, because content cannot contain the value "]]>".
You can assign an XML CDATA literal to a variable, or include it in an XML element literal.
NOTE
An XML literal can span multiple lines but does not use line continuation characters. This enables you to copy content from
an XML document and paste it directly into a Visual Basic program.
The Visual Basic compiler converts the XML CDATA literal to a call to the XCData constructor.
Example
The following example creates a CDATA section that contains the text "Can contain literal <XML> tags".
Syntax
<!-- content -->
Parts
TERM DEFINITION
Return Value
An XComment object.
Remarks
XML comment literals do not contain document content; they contain information about the document. The XML
comment section ends with the sequence "-->". This implies the following points:
You cannot use an embedded expression in an XML comment literal because the embedded expression
delimiters are valid XML comment content.
XML comment sections cannot be nested, because content cannot contain the value "-->".
You can assign an XML comment literal to a variable, or you can include it in an XML element literal.
NOTE
An XML literal can span multiple lines without using line continuation characters. This feature enables you to copy content
from an XML document and paste it directly into a Visual Basic program.
The Visual Basic compiler converts the XML comment literal to a call to the XComment constructor.
Example
The following example creates an XML comment that contains the text "This is a comment".
Dim com As XComment = <!-- This is a comment -->
See Also
XComment
XML Element Literal
XML Literals
Creating XML in Visual Basic
XML Processing Instruction Literal (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
Syntax
<?piName [ = piData ] ?>
Parts
<?
Required. Denotes the start of the XML processing instruction literal.
piName
Required. Name indicating which application the processing instruction targets. Cannot begin with "xml" or "XML".
piData
Optional. String indicating how the application targeted by piName should process the XML document.
?>
Required. Denotes the end of the processing instruction.
Return Value
An XProcessingInstruction object.
Remarks
XML processing instruction literals indicate how applications should process an XML document. When an
application loads an XML document, the application can check the XML processing instructions to determine how
to process the document. The application interprets the meaning of piName and piData .
The XML document literal uses syntax that is similar to that of the XML processing instruction. For more
information, see XML Document Literal.
NOTE
The piName element cannot begin with the strings "xml" or "XML", because the XML 1.0 specification reserves those
identifiers.
You can assign an XML processing instruction literal to a variable or include it in an XML document literal.
NOTE
An XML literal can span multiple lines without needing line continuation characters. This enables you to copy content from
an XML document and paste it directly into a Visual Basic program.
The Visual Basic compiler converts the XML processing instruction literal to a call to the XProcessingInstruction
constructor.
Example
The following example creates a processing instruction identifying a style-sheet for an XML document.
Dim pi As XProcessingInstruction =
<?xml-stylesheet type="text/xsl" href="show_book.xsl"?>
See Also
XProcessingInstruction
XML Document Literal
XML Literals
Creating XML in Visual Basic
Error Messages (Visual Basic)
7/29/2017 • 2 min to read • Edit Online
When you write, compile, or run a Visual Basic application, the following types of errors can occur:
1. Design-time errors, which occur when you write an application in Visual Studio.
2. Compile-time errors, which occur when you compile an application in Visual Studio or at a command
prompt.
3. Run-time errors, which occur when you run an application in Visual Studio or as a stand-alone executable
file.
For information about how to troubleshoot a specific error, see Additional Resources for Visual Basic
Programmers.
#ElseIf is a conditional compilation directive. An #ElseIf clause must be preceded by a matching #If or
#ElseIf clause.
Error ID: BC30014
See Also
#If...Then...#Else Directives
'#Region' and '#End Region' statements are not valid
within method bodies/multiline lambdas
7/29/2017 • 1 min to read • Edit Online
The #Region block must be declared at a class, module, or namespace level. A collapsible region can include one or
more procedures, but it cannot begin or end inside of a procedure.
Error ID: BC32025
See Also
#Region Directive
'<attribute>' cannot be applied because the format of
the GUID '<number>' is not correct
7/29/2017 • 1 min to read • Edit Online
A COMClassAttribute attribute block specifies a globally unique identifier (GUID) that does not conform to the
proper format for a GUID. COMClassAttribute uses GUIDs to uniquely identify the class, the interface, and the
creation event.
A GUID consists of 16 bytes, of which the first eight are numeric and the last eight are binary. It is generated by
Microsoft utilities such as uuidgen.exe and is guaranteed to be unique in space and time.
Error ID: BC32500
See Also
Guid
Attributes overview
'<classname>' is not CLS-compliant because the
interface '<interfacename>' it implements is not CLS-
compliant
7/29/2017 • 1 min to read • Edit Online
A class or interface is marked as <CLSCompliant(True)> when it derives from or implements a type that is marked as
<CLSCompliant(False)> or is not marked.
For a class or interface to be compliant with the Language Independence and Language-Independent Components
(CLS), its entire inheritance hierarchy must be compliant. That means every type from which it inherits, directly or
indirectly, must be compliant. Similarly, if a class implements one or more interfaces, they must all be compliant
throughout their inheritance hierarchies.
When you apply the CLSCompliantAttribute to a programming element, you set the attribute's isCompliant
parameter to either True or False to indicate compliance or noncompliance. There is no default for this
parameter, and you must supply a value.
If you do not apply the CLSCompliantAttribute to an element, it is considered to be noncompliant.
By default, this message is a warning. For information on hiding warnings or treating warnings as errors, see
Configuring Warnings in Visual Basic.
Error ID: BC40029
See Also
<PAVE OVER> Writing CLS-Compliant Code
'<elementname>' is obsolete (Visual Basic Warning)
7/29/2017 • 1 min to read • Edit Online
A statement attempts to access a programming element which has been marked with the ObsoleteAttribute
attribute and the directive to treat it as a warning.
You can mark any programming element as being no longer in use by applying ObsoleteAttribute to it. If you do
this, you can set the attribute's IsError property to either True or False . If you set it to True , the compiler treats
an attempt to use the element as an error. If you set it to False , or let it default to False , the compiler issues a
warning if there is an attempt to use the element.
By default, this message is a warning, because the IsError property of ObsoleteAttribute is False . For more
information about hiding warnings or treating warnings as errors, see Configuring Warnings in Visual Basic.
Error ID: BC40008
See Also
Attributes overview
'<eventname>' is an event, and cannot be called
directly
7/29/2017 • 1 min to read • Edit Online
'< eventname >' is an event, and so cannot be called directly. Use a RaiseEvent statement to raise an event.
A procedure call specifies an event for the procedure name. An event handler is a procedure, but the event itself is a
signaling device, which must be raised and handled.
Error ID: BC32022
See Also
RaiseEvent Statement
'<expression>' cannot be used as a type constraint
7/29/2017 • 1 min to read • Edit Online
A constraint list includes an expression that does not represent a valid constraint on a type parameter.
A constraint list imposes requirements on the type argument passed to the type parameter. You can specify the
following requirements in any combination:
The type argument must implement one or more interfaces
The type argument must inherit from at most one class
The type argument must expose a parameterless constructor that the creating code can access (include the
New constraint)
If you do not include any specific class or interface in the constraint list, you can impose a more general
requirement by specifying one of the following:
The type argument must be a value type (include the Structure constraint)
The type argument must be a reference type (include the Class constraint)
You cannot specify both Structure and Class for the same type parameter, and you cannot specify either one
more than once.
Error ID: BC32061
See Also
Generic Types in Visual Basic
Value Types and Reference Types
References to Declared Elements
NIB How to: Add or Remove References By Using the Add Reference Dialog Box
'<functionname>' is not declared (Smart
Device/Visual Basic Compiler Error)
7/29/2017 • 1 min to read • Edit Online
< functionname > is not declared. File I/O functionality is normally available in the Microsoft.VisualBasic
namespace, but the targeted version of the .NET Compact Framework does not support it.
Error ID: BC30766
See Also
System.IO
File Access with Visual Basic
'<interfacename>.<membername>' is already
implemented by the base class '<baseclassname>'.
Re-implementation of <type> assumed
7/29/2017 • 1 min to read • Edit Online
A property, procedure, or event in a derived class uses an Implements clause specifying an interface member that is
already implemented in the base class.
A derived class can reimplement an interface member that is implemented by its base class. This is not the same as
overriding the base class implementation. For more information, see Implements.
By default, this message is a warning. For information on hiding warnings or treating warnings as errors, see
Configuring Warnings in Visual Basic.
Error ID: BC42015
See Also
Interfaces
'<keyword>' is valid only within an instance method
7/29/2017 • 1 min to read • Edit Online
The Me , MyClass, and MyBase keywords refer to specific class instances. You cannot use them inside a shared
Function or Sub procedure.
Error ID: BC30043
See Also
Object Variable Assignment
Me, My, MyBase, and MyClass
Inheritance Basics
'<membername>' cannot expose type '<typename>'
outside the project through <containertype>
'<containertypename>'
7/29/2017 • 1 min to read • Edit Online
A variable, procedure parameter, or function return is exposed outside its container, but it is declared as a type that
must not be exposed outside the container.
The following skeleton code shows a situation that generates this error.
A type that is declared Protected , Friend , Protected Friend , or Private is intended to have limited access
outside its declaration context. Using it as the data type of a variable with less restricted access would defeat this
purpose. In the preceding skeleton code, exposedVar is Public and would expose privateClass to code that
should not have access to it.
Error ID: BC30909
See Also
Access levels in Visual Basic
'<membername>' is ambiguous across the inherited
interfaces '<interfacename1>' and
'<interfacename2>'
7/29/2017 • 1 min to read • Edit Online
The interface inherits two or more members with the same name from multiple interfaces.
Error ID: BC30685
Interface Left
Sub MySub()
End Interface
Interface Right
Sub MySub()
End Interface
Interface LeftRight
Inherits Left, Right
End Interface
Module test
Sub Main()
Dim x As LeftRight
' x.MySub() 'x is ambiguous.
CType(x, Left).MySub() ' Cast to base type.
CType(x, Right).MySub() ' Call the other base type.
End Sub
End Module
See Also
Interfaces
<message> This error could also be due to mixing a
file reference with a project reference to assembly
'<assemblyname>'
7/29/2017 • 1 min to read • Edit Online
<message> This error could also be due to mixing a file reference with a project reference to assembly
'<assemblyname>. In this case, try replacing the file reference to '<assemblyfilename>' in project
'<projectname1>' with a project reference to '<projectname2>'.
Code in your project accesses a member of another project, but the configuration of your solution does not allow
the Visual Basic compiler to resolve the reference.
To access a type defined in another assembly, the Visual Basic compiler must have a reference to that assembly.
This must be a single, unambiguous reference that does not cause circular references among projects.
Error ID: BC30971
See Also
Managing references in a project
References to Declared Elements
NIB How to: Add or Remove References By Using the Add Reference Dialog Box
Managing Project and Solution Properties
Troubleshooting Broken References
'<methodname>' has multiple definitions with
identical signatures
7/29/2017 • 1 min to read • Edit Online
A Function or Sub procedure declaration uses the identical procedure name and argument list as a previous
declaration. One possible cause is an attempt to overload the original procedure. Overloaded procedures must have
different argument lists.
Error ID: BC30269
See Also
References to Declared Elements
Considerations in Overloading Procedures
'<name>' is ambiguous in the namespace
'<namespacename>'
7/29/2017 • 1 min to read • Edit Online
You have provided a name that is ambiguous and therefore conflicts with another name. The Visual Basic compiler
does not have any conflict resolution rules; you must disambiguate names yourself.
Error ID: BC30560
See Also
Namespaces in Visual Basic
Namespace Statement
'<name1>' is ambiguous, imported from the
namespaces or types '<name2>'
7/29/2017 • 1 min to read • Edit Online
You have provided a name that is ambiguous and therefore conflicts with another name. The Visual Basic compiler
does not have any conflict resolution rules; you must disambiguate names yourself.
Error ID: BC30561
See Also
Imports Statement (.NET Namespace and Type)
Namespaces in Visual Basic
Namespace Statement
<proceduresignature1> is not CLS-compliant because
it overloads <proceduresignature2> which differs
from it only by array of array parameter types or by
the rank of the array parameter types
7/29/2017 • 1 min to read • Edit Online
A procedure or property is marked as <CLSCompliant(True)> when it overrides another procedure or property and
the only difference between their parameter lists is the nesting level of a jagged array or the rank of an array.
In the following declarations, the second and third declarations generate this error.
Overloads Sub processArray(ByVal arrayParam() As Integer)
The second declaration changes the original one-dimensional parameter arrayParam to an array of arrays. The third
declaration changes arrayParam to a two-dimensional array (rank 2). While Visual Basic allows overloads to differ
only by one of these changes, such overloading is not compliant with the Language Independence and Language-
Independent Components (CLS).
When you apply the CLSCompliantAttribute to a programming element, you set the attribute's isCompliant
parameter to either True or False to indicate compliance or noncompliance. There is no default for this
parameter, and you must supply a value.
If you do not apply the CLSCompliantAttribute to an element, it is considered to be noncompliant.
By default, this message is a warning. For information on hiding warnings or treating warnings as errors, see
Configuring Warnings in Visual Basic.
Error ID: BC40035
See Also
<PAVE OVER> Writing CLS-Compliant Code
Procedure Overloading
Overloads
<type1>'<typename>' must implement
'<membername>' for interface '<interfacename>'
7/29/2017 • 1 min to read • Edit Online
'<typename>' must implement '<membername>' for interface '<interfacename>'. Implementing property must
have matching 'ReadOnly'/'WriteOnly' specifiers.
A class or structure claims to implement an interface but does not implement a procedure, property, or event
defined by the interface. Every member of the interface must be implemented.
Error ID: BC30154
3. When implementing a property, make sure that ReadOnly or WriteOnly is used in the same way as in the
interface definition.
4. When implementing a property, declare Get and Set procedures, as appropriate.
See Also
Implements Statement
Interfaces
<type1>'<typename>' must implement
'<methodname>' for interface '<interfacename>'
7/29/2017 • 1 min to read • Edit Online
A class or structure claims to implement an interface but does not implement a procedure defined by the interface.
Every member of the interface must be implemented.
Error ID: BC30149
See Also
Implements Statement
Interfaces
'<typename>' cannot inherit from <type>
'<basetypename>' because it expands the access of
the base <type> outside the assembly
7/29/2017 • 1 min to read • Edit Online
A class or interface inherits from a base class or interface but has a less restrictive access level.
For example, a Public interface inherits from a Friend interface, or a Protected class inherits from a Private
class. This exposes the base class or interface to access beyond the intended level.
Error ID: BC30910
See Also
Class Statement
Interface Statement
Inherits Statement
Access levels in Visual Basic
'<typename>' is a delegate type
7/29/2017 • 1 min to read • Edit Online
'<typename>' is a delegate type. Delegate construction permits only a single AddressOf expression as an argument
list. Often an AddressOf expression can be used instead of a delegate construction.
A New clause creating an instance of a delegate class supplies an invalid argument list to the delegate constructor.
You can supply only a single AddressOf expression when creating a new delegate instance.
This error can result if you do not pass any arguments to the delegate constructor, if you pass more than one
argument, or if you pass a single argument that is not a valid AddressOf expression.
Error ID: BC32008
See Also
New Operator
AddressOf Operator
Delegates
How to: Invoke a Delegate Method
'<typename>' is a type and cannot be used as an
expression
7/29/2017 • 1 min to read • Edit Online
A type name occurs where an expression is required. An expression must consist of some combination of variables,
constants, literals, properties, and Function procedure calls.
Error ID: BC30108
See Also
Operators and Expressions
A double quote is not a valid comment token for
delimited fields where EscapeQuote is set to True
7/29/2017 • 1 min to read • Edit Online
A quotation mark has been supplied as the delimiter for the TextFieldParser , but EscapeQuotes is set to True .
See Also
SetDelimiters
Delimiters
TextFieldParser
How to: Read From Comma-Delimited Text Files
A property or method call cannot include a reference
to a private object, either as an argument or as a
return value
7/29/2017 • 1 min to read • Edit Online
See Also
Private
A reference was created to embedded interop
assembly '<assembly1>' because of an indirect
reference to that assembly from assembly
'<assembly2>'
7/29/2017 • 1 min to read • Edit Online
A reference was created to embedded interop assembly '<assembly1>' because of an indirect reference to that
assembly from assembly '<assembly2>'. Consider changing the 'Embed Interop Types' property on either
assembly.
You have added a reference to an assembly (assembly1) that has the Embed Interop Types property set to True .
This instructs the compiler to embed interop type information from that assembly. However, the compiler cannot
embed interop type information from that assembly because another assembly that you have referenced
(assembly2) also references that assembly (assembly1) and has the Embed Interop Types property set to False .
NOTE
Setting the Embed Interop Types property on an assembly reference to True is equivalent to referencing the assembly by
using the /link option for the command-line compiler.
See Also
/link (Visual Basic)
Programming with Primary Interop Assemblies
A startup form has not been specified
7/29/2017 • 1 min to read • Edit Online
The application uses the WindowsFormsApplicationBase class but does not specify the startup form.
This can occur if the Enable application framework check box is selected in the project designer but the Startup
form is not specified. For more information, see Application Page, Project Designer (Visual Basic).
See Also
WindowsFormsApplicationBase
OnCreateMainForm
MainForm
Overview of the Visual Basic Application Model
Access of shared member through an instance;
qualifying expression will not be evaluated
7/29/2017 • 1 min to read • Edit Online
An instance variable of a class or structure is used to access a Shared variable, property, procedure, or event
defined in that class or structure. This warning can also occur if an instance variable is used to access an implicitly
shared member of a class or structure, such as a constant or enumeration, or a nested class or structure.
The purpose of sharing a member is to create only a single copy of that member and make that single copy
available to every instance of the class or structure in which it is declared. It is consistent with this purpose to access
a Shared member through the name of its class or structure, rather than through a variable that holds an individual
instance of that class or structure.
Accessing a Shared member through an instance variable can make your code more difficult to understand by
obscuring the fact that the member is Shared . Furthermore, if such access is part of an expression that performs
other actions, such as a Function procedure that returns an instance of the shared member, Visual Basic bypasses
the expression and any other actions it would otherwise perform.
For more information and an example, see Shared.
By default, this message is a warning. For more information about hiding warnings or treating warnings as errors,
see Configuring Warnings in Visual Basic.
Error ID: BC42025
Module testModule
Public Sub Main()
' Access a shared method through an instance variable.
' This generates a warning.
Dim tc As New testClass
tc.sayHello()
See Also
Shared
Scope in Visual Basic
'AddressOf' operand must be the name of a method
(without parentheses)
7/29/2017 • 1 min to read • Edit Online
The AddressOf operator creates a procedure delegate instance that references a specific procedure. The syntax is as
follows.
AddressOf procedurename
You inserted parentheses around the argument following AddressOf , where none are needed.
Error ID: BC30577
See Also
AddressOf Operator
Delegates
An unexpected error has occurred because an
operating system resource required for single instance
startup cannot be acquired
7/29/2017 • 1 min to read • Edit Online
The application could not acquire a necessary operating system resource. Some of the possible causes for this
problem are:
The application does not have permissions to create named operating-system objects.
The common language runtime does not have permissions to create memory-mapped files.
The application needs to access an operating-system object, but another process is using it.
See Also
Application Page, Project Designer (Visual Basic)
Debugger Basics
Talk to Us
Anonymous type member name can be inferred only
from a simple or qualified name with no arguments
7/29/2017 • 1 min to read • Edit Online
You cannot infer an anonymous type member name from a complex expression.
For more information about sources from which anonymous types can and cannot infer member names and types,
see How to: Infer Property Names and Types in Anonymous Type Declarations.
Error ID: BC36556
See Also
Anonymous Types
How to: Infer Property Names and Types in Anonymous Type Declarations
Argument not optional (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
The number and types of arguments must match those expected. Either there is an incorrect number of arguments,
or an omitted argument is not optional. An argument can only be omitted from a call to a user-defined procedure if
it was declared Optional in the procedure definition.
See Also
Error Types
Array bounds cannot appear in type specifiers
7/29/2017 • 1 min to read • Edit Online
Define an array and initialize it with the desired number of elements, as shown in the following example.
See Also
Arrays
Array declared as for loop control variable cannot be
declared with an initial size
7/29/2017 • 1 min to read • Edit Online
A For Each loop uses an array as its element iteration variable but initializes that array.
The following statements show how this error can be generated.
The first For Each statement is the correct way to access elements of arrayList . The second For Each statement
generates this error.
Error ID: BC32039
See Also
For...Next Statement
Arrays
Collections
Array subscript expression missing
7/29/2017 • 1 min to read • Edit Online
An array initialization leaves out one or more of the subscripts that define the array bounds. For example, the
statement might contain the expression myArray (5,5,,10) , which leaves out the third subscript.
Error ID: BC30306
See Also
Arrays
Arrays declared as structure members cannot be
declared with an initial size
7/29/2017 • 1 min to read • Edit Online
An array in a structure is declared with an initial size. You cannot initialize any structure element, and declaring an
array size is one form of initialization.
Error ID: BC31043
Structure demoStruct
Public demoArray() As Integer
End Structure
Sub useStruct()
Dim struct As demoStruct
ReDim struct.demoArray(9)
Struct.demoArray(2) = 777
End Sub
See Also
Arrays
How to: Declare a Structure
'As Any' is not supported in 'Declare' statements
7/29/2017 • 1 min to read • Edit Online
The Any data type was used with Declare statements in Visual Basic 6.0 and earlier versions to permit the use of
arguments that could contain any type of data. Visual Basic supports overloading, however, and so makes the Any
data type obsolete.
Error ID: BC30828
2. Use the MarshalAsAttribute attribute to specify As Any when Void* is expected by the procedure being
called.
See Also
MarshalAsAttribute
Walkthrough: Calling Windows APIs
Declare Statement
Creating Prototypes in Managed Code
Attribute '<attributename>' cannot be applied
multiple times
7/29/2017 • 1 min to read • Edit Online
The attribute can only be applied once. The AttributeUsage attribute determines whether an attribute can be
applied more than once.
Error ID: BC30663
<AttributeUsage(AllowMultiple := True)>
See Also
AttributeUsageAttribute
Creating Custom Attributes
AttributeUsage
Automation error
7/29/2017 • 1 min to read • Edit Online
An error occurred while executing a method or getting or setting a property of an object variable. The error was
reported by the application that created the object.
See Also
Error Types
Talk to Us
Bad checksum value, non hex digits or odd number of
hex digits
7/29/2017 • 1 min to read • Edit Online
A checksum value contains invalid hexadecimal digits or has an odd number of digits.
When ASP.NET generates a Visual Basic source file (extension .vb), it calculates a checksum and places it in a hidden
source file identified by #externalchecksum . It is possible for a user generating a .vb file to do this also, but this
process is best left to internal use.
By default, this message is a warning. For information on hiding warnings or treating warnings as errors, see
Configuring Warnings in Visual Basic.
Error ID: BC42033
See Also
ASP.NET Overview
Talk to Us
Bad DLL calling convention
7/29/2017 • 1 min to read • Edit Online
Arguments passed to a dynamic-link library (DLL) must exactly match those expected by the routine. Calling
conventions deal with number, type, and order of arguments. Your program may be calling a routine in a DLL that
is being passed the wrong type or number of arguments.
See Also
Error Types
Call Statement
Declare Statement
Bad file mode
7/29/2017 • 1 min to read • Edit Online
Statements used in manipulating file contents must be appropriate to the mode in which the file was opened.
Possible causes include:
A FilePutObject or FileGetObject statement specifies a sequential file.
A Print statement specifies a file opened for an access mode other than Output or Append .
An Input statement specifies a file opened for an access mode other than Input
See Also
FileSystem
Troubleshooting: Reading from and Writing to Text Files
Bad file name or number
7/29/2017 • 1 min to read • Edit Online
An error occurred while trying to access the specified file. Among the possible causes for this error are:
A statement refers to a file with a file name or number that was not specified in the FileOpen statement or
that was specified in a FileOpen statement but was subsequently closed.
A statement refers to a file with a number that is out of the range of file numbers.
A statement refers to a file name or number that is not valid.
See Also
FileOpen
Visual Basic Naming Conventions
Bad record length
7/29/2017 • 1 min to read • Edit Online
See Also
FileGet
FileGetObject
FilePut
FilePutObject
Because this call is not awaited, the current method
continues to run before the call is completed
7/29/2017 • 6 min to read • Edit Online
Because this call is not awaited, execution of the current method continues before the call is completed. Consider
applying the 'Await' operator to the result of the call.
The current method calls an async method that returns a Task or a Task<TResult> and doesn’t apply the Await
operator to the result. The call to the async method starts an asynchronous task. However, because no Await
operator is applied, the program continues without waiting for the task to complete. In most cases, that behavior
isn't expected. Usually other aspects of the calling method depend on the results of the call or, minimally, the called
method is expected to complete before you return from the method that contains the call.
An equally important issue is what happens with exceptions that are raised in the called async method. An
exception that’s raised in a method that returns a Task or Task<TResult> is stored in the returned task. If you don't
await the task or explicitly check for exceptions, the exception is lost. If you await the task, its exception is rethrown.
As a best practice, you should always await the call.
By default, this message is a warning. For more information about hiding warnings or treating warnings as errors,
see Configuring Warnings in Visual Basic.
Error ID: BC42358
To address this warning
You should consider suppressing the warning only if you're sure that you don't want to wait for the
asynchronous call to complete and that the called method won't raise any exceptions. In that case, you can
suppress the warning by assigning the task result of the call to a variable.
The following example shows how to cause the warning, how to suppress it, and how to await the call.
Async Function CallingMethodAsync() As Task
' Variable delay is used to slow down the called method so that you
' can distinguish between awaiting and not awaiting in the program's output.
' You can adjust the value to produce the output that this topic shows
' after the code.
Dim delay = 5000
' Call #3
' To contrast with an awaited call, replace the unawaited call
' (Call #1 or Call #2) with the following awaited call. The best
' practice is to await the call.
'Await CalledMethodAsync(delay)
ResultsTextBox.Text &= vbCrLf & " Entering called method, starting and awaiting Task.Delay."
' Slow the process down a little so you can distinguish between awaiting
' and not awaiting. Adjust the value for howLong if necessary.
Await Task.Delay(howLong)
ResultsTextBox.Text &= vbCrLf & " Task.Delay is finished--returning from called method."
End Function
In the example, if you choose Call #1 or Call #2, the unawaited async method ( CalledMethodAsync ) finishes
after both its caller ( CallingMethodAsync ) and the caller's caller ( StartButton_Click ) are complete. The last
line in the following output shows you when the called method finishes. Entry to and exit from the event
handler that calls CallingMethodAsync in the full example are marked in the output.
Example
The following Windows Presentation Foundation (WPF) application contains the methods from the previous
example. The following steps set up the application.
1. Create a WPF application, and name it AsyncWarning .
2. In the Visual Studio Code Editor, choose the MainWindow.xaml tab.
If the tab isn't visible, open the shortcut menu for MainWindow.xaml in Solution Explorer, and then choose
View Code.
3. Replace the code in the XAML view of MainWindow.xaml with the following code.
<Window x:Class="MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Button x:Name="StartButton" Content="Start" HorizontalAlignment="Left" Margin="214,28,0,0"
VerticalAlignment="Top" Width="75" HorizontalContentAlignment="Center" FontWeight="Bold"
FontFamily="Aharoni" Click="StartButton_Click" />
<TextBox x:Name="ResultsTextBox" Margin="0,80,0,0" TextWrapping="Wrap" FontFamily="Lucida
Console"/>
</Grid>
</Window>
A simple window that contains a button and a text box appears in the Design view of MainWindow.xaml.
For more information about the XAML Designer, see Creating a UI by using XAML Designer. For information
about how to build your own simple UI, see the "To create a WPF application" and "To design a simple WPF
MainWindow" sections of Walkthrough: Accessing the Web by Using Async and Await.
4. Replace the code in MainWindow.xaml.vb with the following code.
Class MainWindow
' Variable delay is used to slow down the called method so that you
' can distinguish between awaiting and not awaiting in the program's output.
' You can adjust the value to produce the output that this topic shows
' after the code.
Dim delay = 5000
' Call #3
' Call #3
' To contrast with an awaited call, replace the unawaited call
' (Call #1 or Call #2) with the following awaited call. The best
' practice is to await the call.
'Await CalledMethodAsync(delay)
ResultsTextBox.Text &= vbCrLf & " Entering called method, starting and awaiting Task.Delay."
' Slow the process down a little so you can distinguish between awaiting
' and not awaiting. Adjust the value for howLong if necessary.
Await Task.Delay(howLong)
ResultsTextBox.Text &= vbCrLf & " Task.Delay is finished--returning from called method."
End Function
End Class
' Output
' Output
5. Choose the F5 key to run the program, and then choose the Start button.
The expected output appears at the end of the code.
See Also
Await Operator
Asynchronous Programming with Async and Await
Cannot convert anonymous type to expression tree
because it contains a field that is used in the
initialization of another field
7/29/2017 • 1 min to read • Edit Online
The compiler does not accept conversion of an anonymous to an expression tree when one property of the
anonymous type is used to initialize another property of the anonymous type. For example, in the following code,
Prop1 is declared in the initialization list and then used as the initial value for Prop2 .
Module M2
Sub Main()
' The following line causes the error.
' ExpressionExample(Function() New With {.Prop1 = 2, .Prop2 = .Prop1})
End Sub
End Module
Sub Main()
Dim temp = 2
ExpressionExample(Function() New With {.Prop1 = temp, .Prop2 = temp})
End Sub
See Also
Anonymous Types
Expression Trees
How to: Use Expression Trees to Build Dynamic Queries
Cannot create ActiveX Component
7/29/2017 • 1 min to read • Edit Online
You tried to place an ActiveX control on a form at design time or add a form to a project with an ActiveX control on
it, but the associated information in the registry could not be found.
See Also
Error Types
Talk to Us
Cannot refer to '<name>' because it is a member of
the value-typed field '<name>' of class '<classname>'
which has 'System.MarshalByRefObject' as a base
class
7/29/2017 • 1 min to read • Edit Online
The System.MarshalByRefObject class enables applications that support remote access to objects across application
domain boundaries. Types must inherit from the MarshalByRejectObject class when the type is used across
application domain boundaries. The state of the object must not be copied because the members of the object are
not usable outside the application domain in which they were created.
Error ID: BC30310
See Also
MarshalByRefObject
Dim Statement
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
7/29/2017 • 1 min to read • Edit Online
You have tried to refer to a non-shared member of a class from within a shared procedure. The following example
demonstrates such a situation.
Class sample
Public x as Integer
Public Shared Sub setX()
x = 10
End Sub
End Class
In the preceding example, the assignment statement x = 10 generates this error message. This is because a shared
procedure is attempting to access an instance variable.
The variable x is an instance member because it is not declared as Shared. Each instance of class sample contains
its own individual variable x . When one instance sets or changes the value of x , it does not affect the value of x
in any other instance.
However, the procedure setX is Shared among all instances of class sample . This means it is not associated with
any one instance of the class, but rather operates independently of individual instances. Because it has no
connection with a particular instance, setX cannot access an instance variable. It must operate only on Shared
variables. When setX sets or changes the value of a shared variable, that new value is available to all instances of
the class.
Error ID: BC30369
See Also
Shared
Can't create necessary temporary file
7/29/2017 • 1 min to read • Edit Online
Either the drive is full that contains the directory specified by the TEMP environment variable, or the TEMP
environment variable specifies an invalid or read-only drive or directory.
See Also
Error Types
Can't open '<filename>' for writing
7/29/2017 • 1 min to read • Edit Online
The specified file cannot be opened for writing, perhaps because it has already been opened.
Error ID: BC2012
See Also
WriteAllText
WriteAllBytes
Writing to Files
Class '<classname>' cannot be found
7/29/2017 • 1 min to read • Edit Online
Class '<classname>' cannot be found. This condition is usually the result of a mismatched
'Microsoft.VisualBasic.dll'.
A defined member could not be located.
Error ID: BC31098
See Also
Talk to Us
Class does not support Automation or does not
support expected interface
7/29/2017 • 1 min to read • Edit Online
Either the class you specified in the GetObject or CreateObject function call has not exposed a programmability
interface, or you changed a project from .dll to .exe, or vice versa.
See Also
Error Types
Talk to Us
'Class' statement must end with a matching 'End
Class'
7/29/2017 • 1 min to read • Edit Online
Class is used to initiate a Class block; hence it can only appear at the beginning of the block, with a matching
End Class statement ending the block. Either you have a redundant Class statement, or you have not ended your
Class block with End Class .
See Also
End <keyword> Statement
Class Statement
Clipboard format is not valid
7/29/2017 • 1 min to read • Edit Online
The specified Clipboard format is incompatible with the method being executed. Among the possible causes for this
error are:
Using the Clipboard's GetText or SetText method with a Clipboard format other than vbCFText or
vbCFLink .
Using the Clipboard's GetData or SetData method with a Clipboard format other than vbCFBitmap ,
vbCFDIB , or vbCFMetafile .
Using the DataObject``GetData method or SetData method with a Clipboard format in the range reserved
by Microsoft Windows for registered formats (&HC000-&HFFFF), when that Clipboard format has not been
registered with Microsoft Windows.
See Also
Clipboard: Adding Other Formats
Constant expression not representable in type
'<typename>'
7/29/2017 • 1 min to read • Edit Online
You are trying to evaluate a constant that will not fit into the target type, usually because it is overflowing the range.
Error ID: BC30439
See Also
Constants Overview
Constants and Enumerations
Constants must be of an intrinsic or enumerated type,
not a class, structure, type parameter, or array type
7/29/2017 • 1 min to read • Edit Online
You have attempted to declare a constant as a class, structure, or array type, or as a type parameter defined by a
containing generic type.
Constants must be of an intrinsic type ( Boolean , Byte , Date , Decimal , Double , Integer , Long , Object , SByte ,
Short , Single , String , UInteger , ULong , or UShort ), or an Enum type based on one of the integral types.
Error ID: BC30424
See Also
Constants and Enumerations
Data Types
Data Types
Constructor '<name>' cannot call itself
7/29/2017 • 1 min to read • Edit Online
See Also
Object Lifetime: How Objects Are Created and Destroyed
Copying the value of 'ByRef' parameter
'<parametername>' back to the matching argument
narrows from type '<typename1>' to type
'<typename2>'
7/29/2017 • 1 min to read • Edit Online
A procedure is called with an argument that widens to the corresponding parameter type, and the conversion from
the parameter to the argument is narrowing.
When you define a class or structure, you can define one or more conversion operators to convert that class or
structure type to other types. You can also define reverse conversion operators to convert those other types back to
your class or structure type. When you use your class or structure type in a procedure call, Visual Basic can use
these conversion operators to convert the type of an argument to the type of its corresponding parameter.
If you pass the argument ByRef, Visual Basic sometimes copies the argument value into a local variable in the
procedure instead of passing a reference. In such a case, when the procedure returns, Visual Basic must then copy
the local variable value back into the argument in the calling code.
If a ByRef argument value is copied into the procedure and the argument and parameter are of the same type, no
conversion is necessary. But if the types are different, Visual Basic must convert in both directions. If one of the
types is your class or structure type, Visual Basic must convert it both to and from the other type. If one of these
conversions is widening, the reverse conversion might be narrowing.
Error ID: BC32053
See Also
Procedures
Procedure Parameters and Arguments
Passing Arguments by Value and by Reference
Operator Procedures
Operator Statement
How to: Define an Operator
How to: Define a Conversion Operator
Type Conversions in Visual Basic
Widening and Narrowing Conversions
'Custom' modifier is not valid on events declared
without explicit delegate types
7/29/2017 • 1 min to read • Edit Online
Unlike a non-custom event, a Custom Event declaration requires an As clause following the event name that
explicitly specifies the delegate type for the event.
Non-custom events can be defined either with an As clause and an explicit delegate type, or with a parameter list
immediately following the event name.
Error ID: BC31122
2. Replace the parameter list of the custom event with an As clause specifying the delegate type.
Continuing with the example, Custom Event declaration would be rewritten as follows.
Example
This example declares a Custom Event and specifies the required As clause with a delegate type.
See Also
Event Statement
Delegate Statement
Events
Data type(s) of the type parameter(s) cannot be
inferred from these arguments
7/29/2017 • 1 min to read • Edit Online
Data type(s) of the type parameter(s) cannot be inferred from these arguments. Specifying the data type(s) explicitly
might correct this error.
This error occurs when overload resolution has failed. It occurs as a subordinate message that states why a
particular overload candidate has been eliminated. The error message explains that the compiler cannot use type
inference to find data types for the type parameters.
NOTE
When specifying arguments is not an option (for example, for query operators in query expressions), the error message
appears without the second sentence.
Module Module1
Sub Main()
End Sub
End Module
Interface InterfaceExample(Of T)
End Interface
See Also
Relaxed Delegate Conversion
Generic Procedures in Visual Basic
Type Conversions in Visual Basic
Declaration expected
7/29/2017 • 1 min to read • Edit Online
A nondeclarative statement, such as an assignment or loop statement, occurs outside any procedure. Only
declarations are allowed outside procedures.
Alternatively, a programming element is declared without a declaration keyword such as Dim or Const .
Error ID: BC30188
See Also
Procedures
Dim Statement
Default property '<propertyname1>' conflicts with
default property '<propertyname2>' in '<classname>'
and so should be declared 'Shadows'
7/29/2017 • 1 min to read • Edit Online
A property is declared with the same name as a property defined in the base class. In this situation, the property in
this class should shadow the base class property.
This message is a warning. Shadows is assumed by default. For more information about hiding warnings or treating
warnings as errors, see Configuring Warnings in Visual Basic.
Error ID: BC40007
See Also
Shadows
Shadowing in Visual Basic
Default property access is ambiguous between the
inherited interface members
'<defaultpropertyname>' of interface
'<interfacename1>' and '<defaultpropertyname>' of
interface '<interfacename2>'
7/29/2017 • 1 min to read • Edit Online
An interface inherits from two interfaces, each of which declares a default property with the same name. The
compiler cannot resolve an access to this default property without qualification. The following example illustrates
this.
When you specify testObj(1) , the compiler tries to resolve it to the default property. However, there are two
possible default properties because of the inherited interfaces, so the compiler signals this error.
Error ID: BC30686
-or-
Implement the inheriting interface in a class. Then you can implement each of the inherited properties with
different names. However, only one of them can be the default property of the implementing class. The
following example illustrates this.
Public Class useIface3
Implements Iface3
Default Public Property prop1(ByVal arg As Integer) As Integer Implements Iface1.prop
' Insert code to define Get and Set procedures for prop1.
End Property
Public Property prop2(ByVal arg As Integer) As Integer Implements Iface2.prop
' Insert code to define Get and Set procedures for prop2.
End Property
End Class
See Also
Interfaces
Delegate class '<classname>' has no Invoke method,
so an expression of this type cannot be the target of a
method call
7/29/2017 • 1 min to read • Edit Online
A call to Invoke through a delegate has failed because Invoke is not implemented on the delegate class.
Error ID: BC30220
See Also
Delegates
Delegate Statement
AddressOf Operator
Dim Statement
Derived classes cannot raise base class events
7/29/2017 • 1 min to read • Edit Online
An event can be raised only from the declaration space in which it is declared. Therefore, a class cannot raise events
from any other class, even one from which it is derived.
Error ID: BC30029
See Also
Event Statement
RaiseEvent Statement
Device I/O error
7/29/2017 • 1 min to read • Edit Online
An input or output error occurred while your program was using a device such as a printer or disk drive.
See Also
Error Types
'Dir' function must first be called with a 'PathName'
argument
7/29/2017 • 1 min to read • Edit Online
An initial call to the Dir function does not include the PathName argument. The first call to Dir must include a
PathName , but subsequent calls to Dir do not need to include parameters to retrieve the next item.
See Also
Dir
End of statement expected
7/29/2017 • 1 min to read • Edit Online
The statement is syntactically complete, but an additional programming element follows the element that
completes the statement. A line terminator is required at the end of every statement.
A line terminator divides the characters of a Visual Basic source file into lines. Examples of line terminators are the
Unicode carriage return character (&HD), the Unicode linefeed character (&HA), and the Unicode carriage return
character followed by the Unicode linefeed character. For more information about line terminators, see the Visual
Basic Language Specification.
Error ID: BC30205
See Also
How to: Break and Combine Statements in Code
Statements
Error creating assembly manifest: <error message>
7/29/2017 • 1 min to read • Edit Online
The Visual Basic compiler calls the Assembly Linker (Al.exe, also known as Alink) to generate an assembly with a
manifest. The linker has reported an error in the pre-emission stage of creating the assembly.
This can occur if there are problems with the key file or the key container specified. To fully sign an assembly, you
must provide a valid key file that contains information about the public and private keys. To delay sign an assembly,
you must select the Delay sign only check box and provide a valid key file that contains information about the
public key information. The private key is not necessary when an assembly is delay-signed. For more information,
see How to: Sign an Assembly (Visual Studio).
Error ID: BC30140
See Also
How to: Sign an Assembly (Visual Studio)
Signing Page, Project Designer
Al.exe (Assembly Linker)
Al.exe Tool Errors and Warnings
Talk to Us
Error creating Win32 resources: <error message>
7/29/2017 • 1 min to read • Edit Online
The Visual Basic compiler calls the Assembly Linker (Al.exe, also known as Alink) to generate an assembly with a
manifest. The linker has reported an error creating an in-memory resource. This might be a problem with the
environment, or your computer might be low on memory.
Error ID: BC30136
See Also
Al.exe (Assembly Linker)
Al.exe Tool Errors and Warnings
Talk to Us
Error in loading DLL (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
A dynamic-link library (DLL) is a library specified in the Lib clause of a Declare statement. Possible causes for this
error include:
The file is not DLL executable.
The file is not a Microsoft Windows DLL.
The DLL references another DLL that is not present.
The DLL or referenced DLL is not in a directory specified in the path.
See Also
Declare Statement
Error saving temporary Win32 resource file
'<filename>': <error message>
7/29/2017 • 1 min to read • Edit Online
The Visual Basic compiler calls the Assembly Linker (Al.exe, also known as Alink) to generate an assembly with a
manifest. The linker reported an error obtaining a file name for use in writing an in-memory resource.
Error ID: BC30137
See Also
Al.exe (Assembly Linker)
Al.exe Tool Errors and Warnings
Talk to Us
Errors occurred while compiling the XML schemas in
the project
7/29/2017 • 1 min to read • Edit Online
Errors occurred while compiling the XML schemas in the project. Because of this, XML IntelliSense is not available.
There is an error in an XML Schema Definition (XSD) schema included in the project. This error occurs when you
add an XSD schema (.xsd) file that conflicts with the existing XSD schema set for the project.
Error ID: BC36810
See Also
Error List Window
XML IntelliSense in Visual Basic
XML
Evaluation of expression or statement timed out
7/29/2017 • 1 min to read • Edit Online
See Also
Debugging in Visual Studio
Event '<eventname1>' cannot implement event
'<eventname2>' on interface '<interface>' because
their delegate types '<delegate1>' and '<delegate2>'
do not match
7/29/2017 • 1 min to read • Edit Online
Visual Basic cannot implement an event because the delegate type of the event does not match the delegate type of
the event in the interface. This error can occur when you define multiple events in an interface and then attempt to
implement them together with the same event. An event can implement two or more events only if all implemented
events are declared using the As syntax and specify the same delegate type.
Error ID: BC31423
See Also
Event Statement
Delegate Statement
Events
Events cannot be declared with a delegate type that
has a return type
7/29/2017 • 1 min to read • Edit Online
See Also
Events
Events of shared WithEvents variables cannot be
handled by non-shared methods
7/29/2017 • 1 min to read • Edit Online
A variable declared with the Shared modifier is a shared variable. A shared variable identifies exactly one storage
location. A variable declared with the WithEvents modifier asserts that the type to which the variable belongs
handles the set of events the variable raises. When a value is assigned to the variable, the property created by the
WithEvents declaration unhooks any existing event handler and hooks up the new event handler via the Add
method.
Error ID: BC30594
See Also
Shared
WithEvents
Expression does not produce a value
7/29/2017 • 1 min to read • Edit Online
You have tried to use an expression that does not produce a value in a value-producing context, such as calling a
Sub in a context where a Function is expected.
See Also
Error Types
Expression has the type '<typename>' which is a
restricted type and cannot be used to access
members inherited from 'Object' or 'ValueType'
7/29/2017 • 1 min to read • Edit Online
An expression evaluates to a type that cannot be boxed by the common language runtime (CLR) but accesses a
member that requires boxing.
Boxing refers to the processing necessary to convert a type to Object or, on occasion, to ValueType. The common
language runtime cannot box certain structure types, for example ArgIterator, RuntimeArgumentHandle, and
TypedReference.
This expression attempts to use the restricted type to call a method inherited from Object or ValueType, such as
GetHashCode or ToString. To access this method, Visual Basic has attempted an implicit boxing conversion that
causes this error.
Error ID: BC31393
See Also
Implicit and Explicit Conversions
Expression is a value and therefore cannot be the
target of an assignment
7/29/2017 • 1 min to read • Edit Online
A statement attempts to assign a value to an expression. You can assign a value only to a writable variable,
property, or array element at run time. The following example illustrates how this error can occur.
The last statement of the preceding example fails because it creates only a temporary allocation for the Point
structure returned by the Location property. A structure is a value type, and the temporary structure is not retained
after the statement runs. The problem is resolved by declaring and using a variable for Location, which creates a
more permanent allocation for the Point structure. The following example shows code that can replace the last
statement of the preceding example.
See Also
Operators and Expressions
Statements
Troubleshooting Procedures
Expression of type <type> is not queryable
7/29/2017 • 1 min to read • Edit Online
Expression of type <type> is not queryable. Make sure you are not missing an assembly reference and/or
namespace import for the LINQ provider.
Queryable types are defined in the System.Linq, System.Data.Linq, and System.Xml.Linq namespaces. You must
import one or more of these namespaces to perform LINQ queries.
The System.Linq namespace enables you to query objects such as collections and arrays by using LINQ.
The System.Data.Linq namespace enables you to query ADO.NET Datasets and SQL Server databases by using
LINQ.
The System.Xml.Linq namespace enables you to query XML by using LINQ and to use XML features in Visual Basic.
Error ID: BC36593
See Also
System.Linq
System.Data.Linq
System.Xml.Linq
Introduction to LINQ in Visual Basic
LINQ
XML
References and the Imports Statement
Imports Statement (.NET Namespace and Type)
References Page, Project Designer (Visual Basic)
Expression recursively calls the containing property
'<propertyname>'
7/29/2017 • 1 min to read • Edit Online
A statement in the Set procedure of a property definition stores a value into the name of the property.
The recommended approach to holding the value of a property is to define a Private variable in the property's
container and use it in both the Get and Set procedures. The Set procedure should then store the incoming
value in this Private variable.
The Get procedure behaves like a Function procedure, so it can assign a value to the property name and return
control by encountering the End Get statement. The recommended approach, however, is to include the Private
variable as the value in a Return Statement.
The Set procedure behaves like a Sub procedure, which does not return a value. Therefore, the procedure or
property name has no special meaning within a Set procedure, and you cannot store a value into it.
The following example illustrates the approach that can cause this error, followed by the recommended approach.
By default, this message is a warning. For more information about hiding warnings or treating warnings as errors,
please see Configuring Warnings in Visual Basic.
Error ID: BC42026
See Also
Operators and Expressions
'Extension' attribute can be applied only to 'Module',
'Sub', or 'Function' declarations
7/29/2017 • 1 min to read • Edit Online
The only way to extend a data type in Visual Basic is to define an extension method inside a standard module. The
extension method can be a Sub procedure or a Function procedure. All extension methods must be marked with
the extension attribute, <Extension()> , from the System.Runtime.CompilerServices namespace. Optionally, a
module that contains an extension method may be marked in the same way. No other use of the extension attribute
is valid.
Error ID: BC36550
Example
The following example defines a Print method for the String data type.
Imports StringUtility
Imports System.Runtime.CompilerServices
Namespace StringUtility
<Extension()>
Module StringExtensions
<Extension()>
Public Sub Print (ByVal str As String)
Console.WriteLine(str)
End Sub
End Module
End Namespace
See Also
Attributes overview
Extension Methods
Module Statement
File already open
7/29/2017 • 1 min to read • Edit Online
Sometimes a file must be closed before another FileOpen or other operation can occur. Among the possible causes
of this error are:
A sequential output mode FileOpen operation was executed for a file that is already open
A statement refers to an open file.
See Also
FileOpen
File is too large to read into a byte array
7/29/2017 • 1 min to read • Edit Online
The size of the file you are attempting to read into a byte array exceeds 4 GB. The
My.Computer.FileSystem.ReadAllBytes method cannot read a file that exceeds this size.
See Also
ReadAllBytes
StreamReader
File Access with Visual Basic
How to: Read Text from Files with a StreamReader
File name or class name not found during
Automation operation (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
The name specified for file name or class in a call to the GetObject function could not be found.
See Also
Error Types
File not found (Visual Basic Run-Time Error)
7/29/2017 • 1 min to read • Edit Online
The file was not found where specified. The error has the following possible causes:
A statement refers to a file that does not exist.
An attempt was made to call a procedure in a dynamic-link library (DLL), but the library specified in the Lib
clause of the Declare statement cannot be found.
You attempted to open a project or load a text file that does not exist.
See Also
Declare Statement
First operand in a binary 'If' expression must be
nullable or a reference type
7/29/2017 • 1 min to read • Edit Online
An If expression can take either two or three arguments. When you send only two arguments, the first argument
must be a reference type or a nullable type. If the first argument evaluates to anything other than Nothing , its value
is returned. If the first argument evaluates to Nothing , the second argument is evaluated and returned.
For example, the following code contains two If expressions, one with three arguments and one with two
arguments. The expressions calculate and return the same value.
Dim choice1 = 4
Dim choice2 = 5
Dim booleanVar = True
See Also
If Operator
If...Then...Else Statement
Nullable Value Types
First statement of this 'Sub New' must be a call to
'MyBase.New' or 'MyClass.New' (No Accessible
Constructor Without Parameters)
7/29/2017 • 1 min to read • Edit Online
First statement of this 'Sub New' must be a call to 'MyBase.New' or 'MyClass.New' because base class
'<basename>' of '<derivedname>' does not have an accessible 'Sub New' that can be called with no arguments.
In a derived class, every constructor must call a base class constructor ( MyBase.New ). If the base class has a
constructor with no parameters that is accessible to derived classes, MyBase.New can be called automatically. If not,
a base class constructor must be called with parameters, and this cannot be done automatically. In this case, the first
statement of every derived class constructor must call a parameterized constructor on the base class, or call another
constructor in the derived class that makes a base class constructor call.
Error ID: BC30148
See Also
Inheritance Basics
First statement of this 'Sub New' must be an explicit
call to 'MyBase.New' or 'MyClass.New' because the
'<constructorname>' in the base class
'<baseclassname>' of '<derivedclassname>' is
marked obsolete: '<errormessage>'
7/29/2017 • 1 min to read • Edit Online
A class constructor does not explicitly call a base class constructor, and the implicit base class constructor is marked
with the ObsoleteAttribute attribute and the directive to treat it as an error.
When a derived class constructor does not call a base class constructor, Visual Basic attempts to generate an
implicit call to a parameterless base class constructor. If there is no accessible constructor in the base class that can
be called without arguments, Visual Basic cannot generate an implicit call. In this case, the required constructor is
marked with the ObsoleteAttribute attribute, so Visual Basic cannot call it.
You can mark any programming element as being no longer in use by applying ObsoleteAttribute to it. If you do
this, you can set the attribute's IsError property to either True or False . If you set it to True , the compiler treats
an attempt to use the element as an error. If you set it to False , or let it default to False , the compiler issues a
warning if there is an attempt to use the element.
Error ID: BC30920
See Also
Attributes overview
'For Each' on type '<typename>' is ambiguous
because the type implements multiple instantiations
of 'System.Collections.Generic.IEnumerable(Of T)'
7/29/2017 • 1 min to read • Edit Online
A For Each statement specifies an iterator variable that has more than one GetEnumerator method.
The iterator variable must be of a type that implements the System.Collections.IEnumerable or
System.Collections.Generic.IEnumerable<T> interface in one of the Collections namespaces of the .NET
Framework. It is possible for a class to implement more than one constructed generic interface, using a different
type argument for each construction. If a class that does this is used for the iterator variable, that variable has more
than one GetEnumerator method. In such a case, Visual Basic cannot choose which method to call.
Error ID: BC32096
See Also
For Each...Next Statement
Interfaces
Friend assembly reference <reference> is invalid
7/29/2017 • 1 min to read • Edit Online
Friend assembly reference <reference> is invalid. Strong-name signed assemblies must specify a public key in their
InternalsVisibleTo declarations.
The assembly name passed to the InternalsVisibleToAttribute attribute constructor identifies a strong-named
assembly, but it does not include a PublicKey attribute.
Error ID: BC31535
See Also
AssemblyName
Friend Assemblies
How to: Create Signed Friend Assemblies
Function '<procedurename>' doesn't return a value
on all code paths
7/29/2017 • 1 min to read • Edit Online
Function '<procedurename>' doesn't return a value on all code paths. Are you missing a 'Return' statement?
A Function procedure has at least one possible path through its code that does not return a value.
You can return a value from a Function procedure in any of the following ways:
Include the value in a Return Statement.
Assign the value to the Function procedure name and then perform an Exit Function statement.
Assign the value to the Function procedure name and then perform the End Function statement.
If control passes to Exit Function or End Function and you have not assigned any value to the procedure name,
the procedure returns the default value of the return data type. For more information, see "Behavior" in Function
Statement.
By default, this message is a warning. For more information on hiding warnings or treating warnings as errors, see
Configuring Warnings in Visual Basic.
Error ID: BC42105
See Also
Function Procedures
Function Statement
Compile Page, Project Designer (Visual Basic)
Function evaluation is disabled because a previous
function evaluation timed out
7/29/2017 • 1 min to read • Edit Online
Function evaluation is disabled because a previous function evaluation timed out. To re-enable function evaluation,
step again or restart debugging.
In the Visual Studio debugger, an expression specifies a procedure call, but another evaluation has timed out.
Possible causes for a procedure call to time out include an infinite loop or endless loop. For more information, see
For...Next Statement.
A special case of an infinite loop is recursion. For more information, see Recursive Procedures.
Error ID: BC30957
See Also
Debugging in Visual Studio
Navigating through Code with the Debugger
Generic parameters used as optional parameter types
must be class constrained
7/29/2017 • 1 min to read • Edit Online
A procedure is declared with an optional parameter that uses a type parameter that is not constrained to be a
reference type.
You must always supply a default value for each optional parameter. If the parameter is of a reference type, the
optional value must be Nothing , which is a valid value for any reference type. However, if the parameter is of a
value type, that type must be an elementary data type predefined by Visual Basic. This is because a composite value
type, such as a user-defined structure, has no valid default value.
When you use a type parameter for an optional parameter, you must guarantee that it is of a reference type to
avoid the possibility of a value type with no valid default value. This means you must constrain the type parameter
either with the Class keyword or with the name of a specific class.
Error ID: BC32124
See Also
Generic Types in Visual Basic
Type List
Class Statement
Optional Parameters
Structures
Nothing
'Get' accessor of property '<propertyname>' is not
accessible
7/29/2017 • 1 min to read • Edit Online
A statement attempts to retrieve the value of a property when it does not have access to the property's Get
procedure.
If the Get Statement is marked with a more restrictive access level than its Property Statement, an attempt to read
the property value could fail in the following cases:
The Get statement is marked Private and the calling code is outside the class or structure in which the
property is defined.
The Get statement is marked Protected and the calling code is not in the class or structure in which the
property is defined, nor in a derived class.
The Get statement is marked Friend and the calling code is not in the same assembly in which the property
is defined.
Error ID: BC31103
See Also
Property Procedures
How to: Declare a Property with Mixed Access Levels
Handles clause requires a WithEvents variable defined
in the containing type or one of its base types
7/29/2017 • 1 min to read • Edit Online
You did not supply a WithEvents variable in your Handles clause. The Handles keyword at the end of a procedure
declaration causes it to handle events raised by an object variable declared using the WithEvents keyword.
Error ID: BC30506
See Also
Handles
Identifier expected
7/29/2017 • 1 min to read • Edit Online
A programming element that is not a recognizable declared element name occurs where the context requires an
element name. One possible cause is that an attribute has been specified somewhere other than at the beginning of
the statement.
Error ID: BC30203
See Also
Declared Element Names
Attributes overview
Identifier is too long
7/29/2017 • 1 min to read • Edit Online
The name, or identifier, of every programming element is limited to 1023 characters. In addition, a fully qualified
name cannot exceed 1023 characters. This means that the entire identifier string (
<namespace>.<...>.<namespace>.<class>.<element> ) cannot be more than 1023 characters long, including the
member-access operator ( . ) characters.
Error ID: BC30033
See Also
Declared Element Names
Initializer expected
7/29/2017 • 1 min to read • Edit Online
You have tried to declare an instance of a class by using an object initializer in which the initialization list is empty,
as shown in the following example.
' Not valid.
At least one field or property must be initialized in the initializer list, as shown in the following example.
Dim aStudent As New Student With {.year = "Senior"}
See Also
Object Initializers: Named and Anonymous Types
How to: Declare an Object by Using an Object Initializer
Input past end of file
7/29/2017 • 1 min to read • Edit Online
Either an Input statement is reading from a file that is empty or one in which all the data is used, or you used the
EOF function with a file opened for binary access.
See Also
Input
EOF
Seek
Loc
Internal error happened at <location>
7/29/2017 • 1 min to read • Edit Online
An internal error has occurred. The line at which it occurred is contained in the error message.
See Also
Debugger Basics
Implicit conversion from '<typename1>' to
'<typename2>' in copying the value of 'ByRef'
parameter '<parametername>' back to the matching
argument.
7/29/2017 • 1 min to read • Edit Online
A procedure is called with a ByRef argument of a different type than that of its corresponding parameter.
If you pass an argument ByRef , Visual Basic sometimes copies the argument value into a local variable in the
procedure instead of passing a reference. In such a case, when the procedure returns, Visual Basic must then copy
the local variable value back into the argument in the calling code.
If a ByRef argument value is copied into the procedure and the argument and parameter are of the same type, no
conversion is necessary. But if the types are different, Visual Basic must convert in both directions. Because you
cannot use CType or any of the other conversion keywords on a procedure argument or parameter, such a
conversion is always implicit.
By default, this message is a warning. For information on hiding warnings or treating warnings as errors, see
Configuring Warnings in Visual Basic.
Error ID: BC41999
See Also
Procedures
Procedure Parameters and Arguments
Passing Arguments by Value and by Reference
Implicit and Explicit Conversions
'Is' requires operands that have reference types, but
this operand has the value type '<typename>'
7/29/2017 • 1 min to read • Edit Online
The Is comparison operator determines whether two object variables refer to the same instance. This comparison
is not defined for value types.
Error ID: BC30020
See Also
Is Operator
Like Operator
Comparison Operators
'IsNot' operand of type 'typename' can only be
compared to 'Nothing', because 'typename' is a
nullable type
7/29/2017 • 1 min to read • Edit Online
A variable declared as nullable has been compared to an expression other than Nothing using the IsNot operator.
Error ID: BC32128
End If
End If
See Also
Nullable Value Types
IsNot Operator
Labels that are numbers must be followed by colons
7/29/2017 • 1 min to read • Edit Online
Line numbers follow the same rules as other kinds of labels, and must contain a colon.
Error ID: BC30801
400: X += 1
See Also
GoTo Statement
Lambda expression will not be removed from this
event handler
7/29/2017 • 1 min to read • Edit Online
Lambda expression will not be removed from this event handler. Assign the lambda expression to a variable and
use the variable to add and remove the event.
When lambda expressions are used with event handlers, you may not see the behavior you expect. The compiler
generates a new method for each lambda expression definition, even if they are identical. Therefore, the following
code displays False .
Module Module1
Sub Main()
Dim fun1 As ChangeInteger = Function(p As Integer) p + 1
Dim fun2 As ChangeInteger = Function(p As Integer) p + 1
Console.WriteLine(fun1 = fun2)
End Sub
End Module
When lambda expressions are used with event handlers, this may cause unexpected results. In the following
example, the lambda expression added by AddHandler is not removed by the RemoveHandler statement.
Module Module1
Sub Main()
End Sub
End Module
By default, this message is a warning. For more information about how to hide warnings or treat warnings as
errors, see Configuring Warnings in Visual Basic.
Error ID: BC42326
Sub Main()
' Use the variable again when you want to remove the listener.
RemoveHandler ProcessInteger, PrintHandler
End Sub
End Module
See Also
Lambda Expressions
Relaxed Delegate Conversion
Events
Lambda expressions are not valid in the first
expression of a 'Select Case' statement
7/29/2017 • 1 min to read • Edit Online
You cannot use a lambda expression for the test expression in a Select Case statement. Lambda expression
definitions return functions, and the test expression of a Select Case statement must be an elementary data type.
The following code causes this error:
See Also
Lambda Expressions
If...Then...Else Statement
Select...Case Statement
Late bound resolution; runtime errors could occur
7/29/2017 • 1 min to read • Edit Online
See Also
Early and Late Binding
Object Variable Declaration
Latebound overload resolution cannot be applied to
'<procedurename>' because the accessing instance is
an interface type
7/29/2017 • 1 min to read • Edit Online
The compiler is attempting to resolve a reference to an overloaded property or procedure, but the reference fails
because an argument is of type Object and the referring object has the data type of an interface. The Object
argument forces the compiler to resolve the reference as late-bound.
In these circumstances, the compiler resolves the overload through the implementing class instead of through the
underlying interface. If the class renames one of the overloaded versions, the compiler does not consider that
version to be an overload because its name is different. This in turn causes the compiler to ignore the renamed
version when it might have been the correct choice to resolve the reference.
Error ID: BC30933
Example
The following example shows a call to an overloaded Sub procedure that causes this error at compile time.
Module m1
Interface i1
Sub s1(ByVal p1 As Integer)
Sub s1(ByVal p1 As Double)
End Interface
Class c1
Implements i1
Public Overloads Sub s1(ByVal p1 As Integer) Implements i1.s1
End Sub
Public Overloads Sub s2(ByVal p1 As Double) Implements i1.s1
End Sub
End Class
Sub Main()
Dim refer As i1 = New c1
Dim o1 As Object = 3.1415
' The following reference is INVALID and causes a compiler error.
refer.s1(o1)
End Sub
End Module
In the preceding example, if the compiler allowed the call to s1 as written, the resolution would take place through
the class c1 instead of the interface i1 . This would mean that the compiler would not consider s2 because its
name is different in c1 , even though it is the correct choice as defined by i1 .
You can correct the error by changing the call to either of the following lines of code:
refer.s1(CType(o1, Integer))
refer.s1(CType(o1, Double))
Each of the preceding lines of code explicitly casts the Object variable o1 to one of the parameter types defined
for the overloads.
See Also
Procedure Overloading
Overload Resolution
CType Function
Leading '.' or '!' can only appear inside a 'With'
statement
7/29/2017 • 1 min to read • Edit Online
A period (.) or exclamation point (!) that is not inside a With block occurs without an expression on the left.
Member access ( . ) and dictionary member access ( ! ) require an expression specifying the element that contains
the member. This must appear immediately to the left of the accessor or as the target of a With block containing
the member access.
Error ID: BC30157
See Also
Special Characters in Code
With...End With Statement
Line is too long
7/29/2017 • 1 min to read • Edit Online
See Also
Error Types
'Line' statements are no longer supported (Visual
Basic Compiler Error)
7/29/2017 • 1 min to read • Edit Online
See Also
System.IO
System.Drawing
File Access with Visual Basic
Method does not have a signature compatible with
the delegate
7/29/2017 • 1 min to read • Edit Online
There is an incompatibility between the signatures of the method and the delegate you are trying to use. The
Delegate statement defines the parameter types and return types of a delegate class. Any procedure that has
matching parameters of compatible types and return types can be used to create an instance of this delegate type.
Error ID: BC36563
See Also
AddressOf Operator
Delegate Statement
Overload Resolution
Generic Types in Visual Basic
Methods of 'System.Nullable(Of T)' cannot be used as
operands of the 'AddressOf' operator
7/29/2017 • 1 min to read • Edit Online
A statement uses the AddressOf operator with an operand that represents a procedure of the Nullable<T>
structure.
Error ID: BC32126
Module Module1
Sub Main()
Dim nullInstance As New Nullable(Of Integer)(1)
Console.WriteLine(del.Invoke())
End Sub
See Also
Nullable<T>
AddressOf Operator
Nullable Value Types
Generic Types in Visual Basic
'Module' statements can occur only at file or
namespace level
7/29/2017 • 1 min to read • Edit Online
Module statements must appear at the top of your source file immediately after Option and Imports statements,
global attributes, and namespace declarations, but before all other declarations.
Error ID: BC30617
See Also
Module Statement
Name <membername> is not CLS-compliant
7/29/2017 • 1 min to read • Edit Online
An assembly is marked as <CLSCompliant(True)> but exposes a member with a name that begins with an
underscore ( _ ).
A programming element can contain one or more underscores, but to be compliant with the Language
Independence and Language-Independent Components (CLS), it must not begin with an underscore. See Declared
Element Names.
When you apply the CLSCompliantAttribute to a programming element, you set the attribute's isCompliant
parameter to either True or False to indicate compliance or noncompliance. There is no default for this
parameter, and you must supply a value.
If you do not apply the CLSCompliantAttribute to an element, it is considered to be noncompliant.
By default, this message is a warning. For information on hiding warnings or treating warnings as errors, see
Configuring Warnings in Visual Basic.
Error ID: BC40031
See Also
Declared Element Names
Visual Basic Naming Conventions
<PAVE OVER> Writing CLS-Compliant Code
Name '<name>' is not declared
7/29/2017 • 1 min to read • Edit Online
A statement refers to a programming element, but the compiler cannot find an element with that exact name.
Error ID: BC30451
See Also
Declarations and Constants Summary
Visual Basic Naming Conventions
Declared Element Names
References to Declared Elements
Name <namespacename> in the root namespace
<fullnamespacename> is not CLS-compliant
7/29/2017 • 1 min to read • Edit Online
An assembly is marked as <CLSCompliant(True)> , but an element of the root namespace name begins with an
underscore ( _ ).
A programming element can contain one or more underscores, but to be compliant with the Language
Independence and Language-Independent Components (CLS), it must not begin with an underscore. See Declared
Element Names.
When you apply the CLSCompliantAttribute to a programming element, you set the attribute's isCompliant
parameter to either True or False to indicate compliance or noncompliance. There is no default for this
parameter, and you must supply a value.
If you do not apply the CLSCompliantAttribute to an element, it is considered to be noncompliant.
By default, this message is a warning. For information on hiding warnings or treating warnings as errors, see
Configuring Warnings in Visual Basic.
Error ID: BC40039
See Also
Namespace Statement
Namespaces in Visual Basic
/rootnamespace
Application Page, Project Designer (Visual Basic)
Declared Element Names
Visual Basic Naming Conventions
<PAVE OVER> Writing CLS-Compliant Code
Namespace or type specified in the Imports
'<qualifiedelementname>' doesn't contain any public
member or cannot be found
7/29/2017 • 1 min to read • Edit Online
Namespace or type specified in the Imports '<qualifiedelementname>' doesn't contain any public member or
cannot be found. Make sure the namespace or the type is defined and contains at least one public member. Make
sure the alias name doesn't contain other aliases.
An Imports statement specifies a containing element that either cannot be found or does not define any Public
members.
A containing element can be a namespace, class, structure, module, interface, or enumeration. The containing
element contains members, such as variables, procedures, or other containing elements.
The purpose of importing is to allow your code to access namespace or type members without having to qualify
them. Your project might also need to add a reference to the namespace or type. For more information, see
"Importing Containing Elements" in References to Declared Elements.
If the compiler cannot find the specified containing element, then it cannot resolve references that use it. If it finds
the element but the element does not expose any Public members, then no reference can be successful. In either
case it is meaningless to import the element.
Keep in mind that if you import a containing element and assign an import alias to it, then you cannot use that
import alias to import another element. The following code generates a compiler error.
Imports winfrm = System.Windows.Forms
See Also
Imports Statement (.NET Namespace and Type)
Namespace Statement
Public
Namespaces in Visual Basic
References to Declared Elements
Namespace or type specified in the project-level
Imports '<qualifiedelementname>' doesn't contain
any public member or cannot be found
7/29/2017 • 1 min to read • Edit Online
Namespace or type specified in the project-level Imports '<qualifiedelementname>' doesn't contain any public
member or cannot be found. Make sure the namespace or the type is defined and contains at least one public
member. Make sure the alias name doesn't contain other aliases.
An import property of a project specifies a containing element that either cannot be found or does not define any
Public members.
A containing element can be a namespace, class, structure, module, interface, or enumeration. The containing
element contains members, such as variables, procedures, or other containing elements.
The purpose of importing is to allow your code to access namespace or type members without having to qualify
them. Your project might also need to add a reference to the namespace or type. For more information, see
"Importing Containing Elements" in References to Declared Elements.
If the compiler cannot find the specified containing element, then it cannot resolve references that use it. If it finds
the element but the element does not expose any Public members, then no reference can be successful. In either
case it is meaningless to import the element.
You use the Project Designer to specify elements to import. Use the Imported namespaces section of the
References page. You can get to the Project Designer by double-clicking the My Project icon in Solution
Explorer.
Error ID: BC40057
See Also
References Page, Project Designer (Visual Basic)
Managing Project and Solution Properties
Public
Namespaces in Visual Basic
References to Declared Elements
Need property array index
7/29/2017 • 1 min to read • Edit Online
This property value consists of an array rather than a single value. You did not specify the index for the property
array you tried to access.
See Also
Error Types
Talk to Us
Nested function does not have a signature that is
compatible with delegate '<delegatename>'
7/29/2017 • 1 min to read • Edit Online
A lambda expression has been assigned to a delegate that has an incompatible signature. For example, in the
following code, delegate Del has two integer parameters.
The error is raised if a lambda expression with one argument is declared as type Del :
See Also
Relaxed Delegate Conversion
Lambda Expressions
No accessible 'Main' method with an appropriate
signature was found in '<name>'
7/29/2017 • 1 min to read • Edit Online
Command-line applications must have a Sub Main defined. Main must be declared as Public Shared if it is
defined in a class, or as Public if defined in a module.
For more information on Main , see NIB: Visual Basic Version of Hello, World.
Error ID: BC30737
See Also
NIB: Visual Basic Version of Hello, World
Structure of a Visual Basic Program
Procedures
Non-CLS-compliant <membername> is not allowed
in a CLS-compliant interface
7/29/2017 • 1 min to read • Edit Online
A property, procedure, or event in an interface is marked as <CLSCompliant(True)> when the interface itself is
marked as <CLSCompliant(False)> or is not marked.
For an interface to be compliant with the Language Independence and Language-Independent Components (CLS),
all its members must be compliant.
When you apply the CLSCompliantAttribute to a programming element, you set the attribute's isCompliant
parameter to either True or False to indicate compliance or noncompliance. There is no default for this
parameter, and you must supply a value.
If you do not apply the CLSCompliantAttribute to an element, it is considered to be noncompliant.
By default, this message is a warning. For information on hiding warnings or treating warnings as errors, see
Configuring Warnings in Visual Basic.
Error ID: BC40033
If you require CLS compliance and do not have control over the interface source code, or if it does not qualify
to be compliant, define this member within a different interface.
If you require that this member remain within its current interface, remove the CLSCompliantAttribute from
its definition or mark it as <CLSCompliant(False)> .
See Also
Interface Statement
<PAVE OVER> Writing CLS-Compliant Code
Nullable type inference is not supported in this
context
7/29/2017 • 1 min to read • Edit Online
Dim a? As Integer
Dim b As Integer?
However, you cannot use the nullable declaration in combination with type inference. The following examples cause
this error.
See Also
Nullable Value Types
Local Type Inference
Number of indices exceeds the number of dimensions
of the indexed array
7/29/2017 • 1 min to read • Edit Online
The number of indices used to access an array element must be exactly the same as the rank of the array, that is, the
number of dimensions declared for it.
Error ID: BC30106
See Also
Arrays
Object or class does not support the set of events
7/29/2017 • 1 min to read • Edit Online
You tried to use a WithEvents variable with a component that cannot work as an event source for the specified set
of events. For example, you wanted to sink the events of an object, then create another object that Implements the
first object. Although you might think you could sink the events from the implemented object, this is not always the
case. Implements only implements an interface for methods and properties. WithEvents is not supported for
private UserControls , because the type info needed to raise the ObjectEvent is not available at run time.
See Also
WithEvents
Implements Statement
Object required (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
References to properties and methods often require an explicit object qualifier. This is such a case.
See Also
Error Types
Object variable or With block variable not set
7/29/2017 • 2 min to read • Edit Online
An invalid object variable is being referenced. This error can occur for several reasons:
A variable was declared without specifying a type. If a variable is declared without specifying a type, it
defaults to type Object .
For example, a variable declared with Dim x would be of type Object; a variable declared with
Dim x As String would be of type String .
TIP
The Option Strict statement disallows implicit typing that results in an Object type. If you omit the type, a
compile-time error will occur. See Option Strict Statement.
You are attempting to reference an object that has been set to Nothing
.
You are attempting to access an element of an array variable that wasn't properly declared.
For example, an array declared as products() As String will trigger the error if you try to reference an
element of the array products(3) = "Widget" . The array has no elements and is treated as an object.
You are attempting to access code within a With...End With block before the block has been initialized. A
With...End With block must be initialized by executing the With statement entry point.
NOTE
In earlier versions of Visual Basic or VBA this error was also triggered by assigning a value to a variable without using the
Set keyword ( x = "name" instead of Set x = "name" ). The Set keyword is no longer valid in Visual Basic .Net.
Option Strict On
When you run the project, a compiler error will appear in the **Error List** for any variable that was
specified without a type.
2. If you don't want to enable Option Strict , search your code for any variables that were specified without a
type ( Dim x instead of Dim x As String ) and add the intended type to the declaration.
3. Make sure you aren't referring to an object variable that has been set to Nothing . Search your code for the
keyword Nothing , and revise your code so that the object isn't set to Nothing until after you have
referenced it.
4. Make sure that any array variables are dimensioned before you access them. You can either assign a
dimension when you first create the array ( Dim x(5) As String instead of Dim x() As String ), or use the
ReDim keyword to set the dimensions of the array before you first access it.
5. Make sure your With block is initialized by executing the With statement entry point.
See Also
Object Variable Declaration
ReDim Statement
With...End With Statement
Operator declaration must be one of: +,-,*,\,/,^, &,
Like, Mod, And, Or, Xor, Not, <<, >>...
7/29/2017 • 1 min to read • Edit Online
You can declare only an operator that is eligible for overloading. The following table lists the operators you can
declare.
TYPE OPERATORS
Note that the = operator in the binary list is the comparison operator, not the assignment operator.
Error ID: BC33000
See Also
Operator Statement
Operator Procedures
How to: Define an Operator
How to: Define a Conversion Operator
Function Statement
'Optional' expected
7/29/2017 • 1 min to read • Edit Online
An optional argument in a procedure declaration is followed by a required argument. Every argument following an
optional argument must also be optional.
Error ID: BC30202
See Also
Optional Parameters
Optional parameters must specify a default value
7/29/2017 • 1 min to read • Edit Online
Optional parameters must provide default values that can be used if no parameter is supplied by a calling
procedure.
Error ID: BC30812
See Also
Optional
Ordinal is not valid
7/29/2017 • 1 min to read • Edit Online
Your call to a dynamic-link library (DLL) indicated to use a number instead of a procedure name, using the #num
syntax. This error has the following possible causes:
An attempt to convert the #num expression to an ordinal failed.
The #num specified does not specify any function in the DLL.
A type library has an invalid declaration resulting in internal use of an invalid ordinal number.
See Also
Declare Statement
Out of memory (Visual Basic Compiler Error)
7/29/2017 • 1 min to read • Edit Online
See Also
Error Types
Out of stack space (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
The stack is a working area of memory that grows and shrinks dynamically with the demands of your executing
program. Its limits have been exceeded.
See Also
Memory Windows
Out of string space (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
With Visual Basic, you can use very large strings. However, the requirements of other programs and the way you
work with your strings can still cause this error.
See Also
Error Types
String Manipulation Summary
Overflow (Visual Basic Error)
7/29/2017 • 1 min to read • Edit Online
A literal represents a value outside the limits of the data type to which it is being assigned.
Error ID: BC30036
See Also
Data Types
Overflow (Visual Basic Run-Time Error)
7/29/2017 • 1 min to read • Edit Online
An overflow results when you attempt an assignment that exceeds the limits of the assignment's target.
See Also
System.Int32.MaxValue
System.Double.MaxValue
Data Types
Error Types
Path not found
7/29/2017 • 1 min to read • Edit Online
During a file-access or disk-access operation, the operating system was unable to find the specified path. The path
to a file includes the drive specification plus the directories and subdirectories that must be traversed to locate the
file. A path can be relative or absolute.
See Also
Error Types
Path/File access error
7/29/2017 • 1 min to read • Edit Online
During a file-access or disk-access operation, the operating system could not make a connection between the path
and the file name.
See Also
Error Types
Permission denied (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
See Also
Error Types
Procedure call or argument is not valid (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
See Also
Error Types
Property '<propertyname>' doesn't return a value on
all code paths
7/29/2017 • 1 min to read • Edit Online
Property '<propertyname>' doesn't return a value on all code paths. A null reference exception could occur at run
time when the result is used.
A property Get procedure has at least one possible path through its code that does not return a value.
You can return a value from a property Get procedure in any of the following ways:
Assign the value to the property name and then perform an Exit Property statement.
Assign the value to the property name and then perform the End Get statement.
Include the value in a Return Statement.
If control passes to Exit Property or End Get and you have not assigned any value to the property name, the Get
procedure returns the default value of the property's data type. For more information, see "Behavior" in Function
Statement.
By default, this message is a warning. For more information on hiding warnings or treating warnings as errors, see
Configuring Warnings in Visual Basic.
Error ID: BC42107
See Also
Property Procedures
Property Statement
Get Statement
Property array index is not valid
7/29/2017 • 1 min to read • Edit Online
See Also
Arrays
Property let procedure not defined and property get
procedure did not return an object
7/29/2017 • 1 min to read • Edit Online
Certain properties, methods, and operations can only apply to Collection objects. You specified an operation or
property that is exclusive to collections, but the object is not a collection.
See Also
Collection
Property not found
7/29/2017 • 1 min to read • Edit Online
See Also
Error Types
Property or method not found
7/29/2017 • 1 min to read • Edit Online
See Also
Error Types
Range variable <variable> hides a variable in an
enclosing block, a previously defined range variable,
or an implicitly declared variable in a query
expression
7/29/2017 • 1 min to read • Edit Online
A range variable name specified in a Select , From , Aggregate , or Let clause duplicates the name of a range
variable already specified previously in the query, or the name of a variable that is implicitly declared by the query,
such as a field name or the name of an aggregate function.
Error ID: BC36633
See Also
Introduction to LINQ in Visual Basic
From Clause
Let Clause
Aggregate Clause
Select Clause
Range variable name can be inferred only from a
simple or qualified name with no arguments
7/29/2017 • 1 min to read • Edit Online
A programming element that takes one or more arguments is included in a LINQ query. The compiler is unable to
infer a range variable from that programming element.
Error ID: BC36599
See Also
Introduction to LINQ in Visual Basic
Select Clause
Reference required to assembly '<assemblyidentity>'
containing type '<typename>', but a suitable
reference could not be found due to ambiguity
between projects '<projectname1>' and
'<projectname2>'
7/29/2017 • 1 min to read • Edit Online
An expression uses a type, such as a class, structure, interface, enumeration, or delegate, that is defined outside your
project. However, you have project references to more than one assembly defining that type.
The cited projects produce assemblies with the same name. Therefore, the compiler cannot determine which
assembly to use for the type you are accessing.
To access a type defined in another assembly, the Visual Basic compiler must have a reference to that assembly.
This must be a single, unambiguous reference that does not cause circular references among projects.
Error ID: BC30969
See Also
Managing references in a project
References to Declared Elements
NIB How to: Add or Remove References By Using the Add Reference Dialog Box
Managing Project and Solution Properties
Troubleshooting Broken References
Reference required to assembly '<assemblyname>'
containing the base class '<classname>'
7/29/2017 • 1 min to read • Edit Online
Reference required to assembly '<assemblyname>' containing the base class '<classname>'. Add one to your
project.
The class is defined in a dynamic-link library (DLL) or assembly that is not directly referenced in your project. The
Visual Basic compiler requires a reference to avoid ambiguity in case the class is defined in more than one DLL or
assembly.
Error ID: BC30007
See Also
NIB How to: Add or Remove References By Using the Add Reference Dialog Box
Managing references in a project
Troubleshooting Broken References
Resume without error
7/29/2017 • 1 min to read • Edit Online
A Resume statement appeared outside error-handling code, or the code jumped into an error handler even though
there was no error.
See Also
Resume Statement
On Error Statement
Return type of function '<procedurename>' is not
CLS-compliant
7/29/2017 • 1 min to read • Edit Online
For a procedure to be compliant with the Language Independence and Language-Independent Components (CLS),
it must use only CLS-compliant types. This applies to the types of the parameters, the return type, and the types of
all its local variables.
The following Visual Basic data types are not CLS-compliant:
SByte Data Type
UInteger Data Type
ULong Data Type
UShort Data Type
When you apply the CLSCompliantAttribute to a programming element, you set the attribute's isCompliant
parameter to either True or False to indicate compliance or noncompliance. There is no default for this
parameter, and you must supply a value.
If you do not apply the CLSCompliantAttribute to an element, it is considered to be noncompliant.
By default, this message is a warning. For information on hiding warnings or treating warnings as errors, see
Configuring Warnings in Visual Basic.
Error ID: BC40027
See Also
<PAVE OVER> Writing CLS-Compliant Code
'Set' accessor of property '<propertyname>' is not
accessible
7/29/2017 • 1 min to read • Edit Online
A statement attempts to store the value of a property when it does not have access to the property's Set
procedure.
If the Set Statement is marked with a more restrictive access level than its Property Statement, an attempt to set the
property value could fail in the following cases:
The Set statement is marked Private and the calling code is outside the class or structure in which the
property is defined.
The Set statement is marked Protected and the calling code is not in the class or structure in which the
property is defined, nor in a derived class.
The Set statement is marked Friend and the calling code is not in the same assembly in which the property
is defined.
Error ID: BC31102
See Also
Property Procedures
How to: Declare a Property with Mixed Access Levels
Some subkeys cannot be deleted
7/29/2017 • 1 min to read • Edit Online
An attempt has been made to delete a registry key, but the operation failed because some subkeys cannot be
deleted. Usually this is due to a lack of permissions.
See Also
Microsoft.VisualBasic.MyServices.RegistryProxy
DeleteSubKey
DeleteSubKey
RegistryPermission
Statement cannot end a block outside of a line 'If'
statement
7/29/2017 • 1 min to read • Edit Online
A single-line If statement contains several statements separated by colons (:), one of which is an End statement
for a control block outside the single-line If . Single-line If statements do not use the End If statement.
Error ID: BC32005
See Also
If...Then...Else Statement
Statement is not valid in a namespace
7/29/2017 • 1 min to read • Edit Online
The statement cannot appear at the level of a namespace. The only declarations allowed at namespace level are
module, interface, class, delegate, enumeration, and structure declarations.
Error ID: BC30001
See Also
Scope in Visual Basic
Namespaces in Visual Basic
Statement is not valid inside a method/multiline
lambda
7/29/2017 • 1 min to read • Edit Online
The statement is not valid within a Sub , Function , property Get , or property Set procedure. Some statements
can be placed at the module or class level. Others, such as Option Strict , must be at namespace level and precede
all other declarations.
Error ID: BC30024
See Also
Sub Statement
Function Statement
Get Statement
Set Statement
String constants must end with a double quote
7/29/2017 • 1 min to read • Edit Online
See Also
Strings
Structure '<structurename>' must contain at least one
instance member variable or at least one instance
event declaration not marked 'Custom'
7/29/2017 • 1 min to read • Edit Online
A structure definition does not include any nonshared variables or nonshared noncustom events.
Every structure must have either a variable or an event that applies to each specific instance (nonshared) instead of
to all instances collectively (Shared). Nonshared constants, properties, and procedures do not satisfy this
requirement. In addition, if there are no nonshared variables and only one nonshared event, that event cannot be a
Custom event.
See Also
Structures
How to: Declare a Structure
Structure Statement
'Sub Main' was not found in '<name>'
7/29/2017 • 1 min to read • Edit Online
Sub Main is missing, or the wrong location has been specified for it.
Error ID: BC30420
See Also
Sub Statement
Main Procedure in Visual Basic
Sub or Function not defined (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
A Sub or Function must be defined in order to be called. Possible causes of this error include:
Misspelling the procedure name.
Trying to call a procedure from another project without explicitly adding a reference to that project in the
References dialog box.
Specifying a procedure that is not visible to the calling procedure.
Declaring a Windows dynamic-link library (DLL) routine or Macintosh code-resource routine that is not in
the specified library or code resource.
See Also
Error Types
Managing references in a project
Sub Statement
Function Statement
Subscript out of range (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
An array subscript is not valid because it falls outside the allowable range. The lowest subscript value for a
dimension is always 0, and the highest subscript value is returned by the GetUpperBound method for that
dimension.
See Also
System.Array.GetUpperBound
Arrays
TextFieldParser is unable to complete the read
operation because maximum buffer size has been
exceeded
7/29/2017 • 1 min to read • Edit Online
The operation cannot be completed because the maximum buffer size (10,000,000 bytes) has been exceeded.
See Also
OpenTextFieldParser
TextFieldParser
How to: Read From Text Files with Multiple Formats
Parsing Text Files with the TextFieldParser Object
The type for variable '<variablename>' will not be
inferred because it is bound to a field in an enclosing
scope
7/29/2017 • 1 min to read • Edit Online
The type for variable '<variablename>' will not be inferred because it is bound to a field in an enclosing scope.
Either change the name of '<variablename>', or use the fully qualified name (for example, 'Me.variablename' or
'MyBase.variablename').
A loop control variable in your code has the same name as a field of the class or other enclosing scope. Because the
control variable is used without an As clause, it is bound to the field in the enclosing scope, and the compiler does
not create a new variable for it or infer its type.
In the following example, Index , the control variable in the For statement, is bound to the Index field in the
Customer class. The compiler does not create a new variable for the control variable Index or infer its type.
Class Customer
Sub Main()
End Sub
End Class
By default, this message is a warning. For information about how to hide warnings or how to treat warnings as
errors, see Configuring Warnings in Visual Basic.
Error ID: BC42110
To address this warning
Make the loop control variable local by changing its name to an identifier that is not also the name of a field
of the class.
For I = 1 To 10
Clarify that the loop control variable binds to the class field by prefixing Me. to the variable name.
For Me.Index = 1 To 10
Instead of relying on local type inference, use an As clause to specify a type for the loop control variable.
Class Customer
Sub Main()
For I = 1 To 10
' ...
Next
End Sub
End Class
See Also
Option Infer Statement
For Each...Next Statement
For...Next Statement
How to: Refer to the Current Instance of an Object
Local Type Inference
Me, My, MyBase, and MyClass
This array is fixed or temporarily locked (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
See Also
Arrays
This key is already associated with an element of this
collection
7/29/2017 • 1 min to read • Edit Online
The specified a key for a collection member already identifies another member of the collection. A key is a string
specified in the Add method that uniquely identifies a specific member of a collection.
See Also
Error Types
Too many files
7/29/2017 • 1 min to read • Edit Online
Either more files have been created in the root directory than the operating system permits, or more files have been
opened than the number specified in the files= setting in your CONFIG.SYS file.
See Also
Error Types
Type '<typename>' has no constructors
7/29/2017 • 1 min to read • Edit Online
A type does not support a call to Sub New() . One possible cause is a corrupted compiler or binary file.
Error ID: BC30251
See Also
Objects and Classes
Talk to Us
Type <typename> is not CLS-compliant
7/29/2017 • 1 min to read • Edit Online
A variable, property, or function return is declared with a data type that is not CLS-compliant.
For an application to be compliant with the Language Independence and Language-Independent Components
(CLS), it must use only CLS-compliant types.
The following Visual Basic data types are not CLS-compliant:
SByte Data Type
UInteger Data Type
ULong Data Type
UShort Data Type
Error ID: BC40041
See Also
<PAVE OVER> Writing CLS-Compliant Code
Type '<typename>' is not defined
7/29/2017 • 1 min to read • Edit Online
The statement has made reference to a type that has not been defined. You can define a type in a declaration
statement such as Enum , Structure , Class , or Interface .
Error ID: BC30002
See Also
Namespaces in Visual Basic
Enum Statement
Structure Statement
Class Statement
Interface Statement
Managing references in a project
Type arguments could not be inferred from the
delegate
7/29/2017 • 1 min to read • Edit Online
An assignment statement uses AddressOf to assign the address of a generic procedure to a delegate, but it does
not supply any type arguments to the generic procedure.
Normally, when you invoke a generic type, you supply a type argument for each type parameter that the generic
type defines. If you do not supply any type arguments, the compiler attempts to infer the types to be passed to the
type parameters. If the context does not provide enough information for the compiler to infer the types, an error is
generated.
Error ID: BC36564
See Also
Generic Types in Visual Basic
AddressOf Operator
Generic Procedures in Visual Basic
Type List
Extension Methods
Type mismatch (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
You attempted to convert a value to another type in a way that is not valid.
See Also
Error Types
Type of '<variablename>' cannot be inferred because
the loop bounds and the step variable do not widen
to the same type
7/29/2017 • 1 min to read • Edit Online
You have written a For...Next loop in which the compiler cannot infer a data type for the loop control variable
because the following conditions are true:
The data type of the loop control variable is not specified with an As clause.
The loop bounds and step variable contain at least two data types.
No standard conversions exist between the data types.
Therefore, the compiler cannot infer the data type of a loop's control variable.
In the following example, the step variable is a character and the loop bounds are both integers. Because there is no
standard conversion between characters and integers, this error is reported.
Dim stepVar = 1
—or—
Use explicit conversion functions to convert the loop bounds and step variable to the appropriate types. In
the preceding example, apply the Val function to stepVar .
See Also
Val
For...Next Statement
Implicit and Explicit Conversions
Local Type Inference
Option Infer Statement
Type Conversion Functions
Widening and Narrowing Conversions
Type of member '<membername>' is not CLS-
compliant
7/29/2017 • 1 min to read • Edit Online
The data type specified for this member is not part of the Language Independence and Language-Independent
Components (CLS). This is not an error within your component, because the .NET Framework and Visual Basic
support this data type. However, another component written in strictly CLS-compliant code might not support this
data type. Such a component might not be able to interact successfully with your component.
The following Visual Basic data types are not CLS-compliant:
SByte Data Type
UInteger Data Type
ULong Data Type
UShort Data Type
By default, this message is a warning. For more information on hiding warnings or treating warnings as errors, see
Configuring Warnings in Visual Basic.
Error ID: BC40025
See Also
Reflection
<PAVE OVER> Writing CLS-Compliant Code
Type of optional value for optional parameter
<parametername> is not CLS-compliant
7/29/2017 • 1 min to read • Edit Online
A procedure is marked as <CLSCompliant(True)> but declares an Optional parameter with default value of a
noncompliant type.
For a procedure to be compliant with the Language Independence and Language-Independent Components (CLS),
it must use only CLS-compliant types. This applies to the types of the parameters, the return type, and the types of
all its local variables. It also applies to the default values of optional parameters.
The following Visual Basic data types are not CLS-compliant:
SByte Data Type
UInteger Data Type
ULong Data Type
UShort Data Type
When you apply the CLSCompliantAttribute attribute to a programming element, you set the attribute's
isCompliant parameter to either True or False to indicate compliance or noncompliance. There is no default for
this parameter, and you must supply a value.
If you do not apply CLSCompliantAttribute to an element, it is considered to be noncompliant.
By default, this message is a warning. For information on hiding warnings or treating warnings as errors, see
Configuring Warnings in Visual Basic.
Error ID: BC40042
See Also
<PAVE OVER> Writing CLS-Compliant Code
Type of parameter '<parametername>' is not CLS-
compliant
7/29/2017 • 1 min to read • Edit Online
A procedure is marked as <CLSCompliant(True)> but declares a parameter with a type that is marked as
<CLSCompliant(False)> , is not marked, or does not qualify because it is a noncompliant type.
For a procedure to be compliant with the Language Independence and Language-Independent Components (CLS),
it must use only CLS-compliant types. This applies to the types of the parameters, the return type, and the types of
all its local variables.
The following Visual Basic data types are not CLS-compliant:
SByte Data Type
UInteger Data Type
ULong Data Type
UShort Data Type
When you apply the CLSCompliantAttribute to a programming element, you set the attribute's isCompliant
parameter to either True or False to indicate compliance or noncompliance. There is no default for this
parameter, and you must supply a value.
If you do not apply the CLSCompliantAttribute to an element, it is considered to be noncompliant.
By default, this message is a warning. For information on hiding warnings or treating warnings as errors, see
Configuring Warnings in Visual Basic.
Error ID: BC40028
See Also
<PAVE OVER> Writing CLS-Compliant Code
Type parameters cannot be used as qualifiers
7/29/2017 • 1 min to read • Edit Online
A programming element is qualified with a qualification string that includes a type parameter.
A type parameter represents a requirement for a type that is to be supplied when the generic type is constructed. It
does not represent a specific defined type. A qualification string must include only elements that are defined at
compile time.
The following statements can generate this error.
See Also
References to Declared Elements
Generic Types in Visual Basic
Type List
Unable to create strong-named assembly from key
file '<filename>': <error>
7/29/2017 • 1 min to read • Edit Online
A strong-named assembly could not be created from the specified key file.
Error ID: BC31026
See Also
Sn.exe (Strong Name Tool)
Unable to embed resource file '<filename>': <error
message>
7/29/2017 • 1 min to read • Edit Online
The Visual Basic compiler calls the Assembly Linker (Al.exe, also known as Alink) to generate an assembly with a
manifest. The linker has reported an error embedding a native COM+ resource file directly into the assembly.
Error ID: BC30143
See Also
Al.exe (Assembly Linker)
Al.exe Tool Errors and Warnings
Talk to Us
Unable to emit assembly: <error message>
7/29/2017 • 1 min to read • Edit Online
The Visual Basic compiler calls the Assembly Linker (Al.exe, also known as Alink) to generate an assembly with a
manifest, with the linker reporting an error in the emission stage of creating the assembly.
Error ID: BC30145
tlbimp <path to COM reference file> /out:<output assembly name> /keyfile:<path to .snk file>
See Also
Al.exe (Assembly Linker)
Al.exe Tool Errors and Warnings
Sn.exe (Strong Name Tool)
How to: Create a Public-Private Key Pair
Talk to Us
Unable to find required file '<filename>'
7/29/2017 • 1 min to read • Edit Online
See Also
Talk to Us
Unable to get serial port names because of an
internal system error
7/29/2017 • 1 min to read • Edit Online
See Also
SerialPortNames
Debugger Basics
Talk to Us
Unable to link to resource file '<filename>': <error
message>
7/29/2017 • 1 min to read • Edit Online
The Visual Basic compiler calls the Assembly Linker (Al.exe, also known as Alink) to generate an assembly with a
manifest. The linker has reported an error linking to a native COM+ resource file from the assembly.
Error ID: BC30144
See Also
Al.exe (Assembly Linker)
Al.exe Tool Errors and Warnings
Talk to Us
Unable to load information for class '<classname>'
7/29/2017 • 1 min to read • Edit Online
See Also
Debugging in Visual Studio
Unable to write output to memory
7/29/2017 • 1 min to read • Edit Online
See Also
Talk to Us
Unable to write temporary file because temporary
path is not available
7/29/2017 • 1 min to read • Edit Online
Visual Basic could not determine the path where temporary files are stored.
Error ID: BC30698
See Also
Talk to Us
Unable to write to output file '<filename>': <error>
7/29/2017 • 1 min to read • Edit Online
See Also
Talk to Us
Underlying type <typename> of Enum is not CLS-
compliant
7/29/2017 • 1 min to read • Edit Online
The data type specified for this enumeration is not part of the Language Independence and Language-Independent
Components (CLS). This is not an error within your component, because the .NET Framework and Visual Basic
support this data type. However, another component written in strictly CLS-compliant code might not support this
data type. Such a component might not be able to interact successfully with your component.
The following Visual Basic data types are not CLS-compliant:
SByte Data Type
UInteger Data Type
ULong Data Type
UShort Data Type
By default, this message is a warning. For more information on hiding warnings or treating warnings as errors, see
Configuring Warnings in Visual Basic.
Error ID: BC40032
See Also
Reflection
Reflection
<PAVE OVER> Writing CLS-Compliant Code
Using the iteration variable in a lambda expression
may have unexpected results
7/29/2017 • 1 min to read • Edit Online
Using the iteration variable in a lambda expression may have unexpected results. Instead, create a local variable
within the loop and assign it the value of the iteration variable.
This warning appears when you use a loop iteration variable in a lambda expression that is declared inside the loop.
For example, the following example causes the warning to appear.
For i As Integer = 1 To 10
' The warning is given for the use of i.
Dim exampleFunc As Func(Of Integer) = Function() i
Next
The following example shows the unexpected results that might occur.
Module Module1
Sub Main()
Dim array1 As Func(Of Integer)() = New Func(Of Integer)(4) {}
For i As Integer = 0 To 4
array1(i) = Function() i
Next
End Sub
End Module
The For loop creates an array of lambda expressions, each of which returns the value of the loop iteration variable
i . When the lambda expressions are evaluated in the For Each loop, you might expect to see 0, 1, 2, 3, and 4
displayed, the successive values of i in the For loop. Instead, you see the final value of i displayed five times:
5
By default, this message is a warning. For more information about hiding warnings or treating warnings as errors,
see Configuring Warnings in Visual Basic.
Error ID: BC42324
For i As Integer = 0 To 4
Dim j = i
array1(i) = Function() j
Next
End Sub
End Module
See Also
Lambda Expressions
Value of type '<typename1>' cannot be converted to
'<typename2>'
7/29/2017 • 1 min to read • Edit Online
Value of type '<typename1>' cannot be converted to '<typename2>'. Type mismatch could be due to the mixing of
a file reference with a project reference to assembly '<assemblyname>'. Try replacing the file reference to
'<filepath>' in project '<projectname1>' with a project reference to '<projectname2>'.
In a situation where a project makes both a project reference and a file reference, the compiler cannot guarantee
that one type can be converted to another.
The following pseudo-code illustrates a situation that can generate this error.
' ================ Visual Basic project P1 ================
commonObject = P2.getCommonClass()
End Function
End Class
Project P1 makes an indirect project reference through project P2 to project P3 , and also a direct file reference to
P3 . The declaration of commonObject uses the file reference to P3 , while the call to P2.getCommonClass uses the
project reference to P3 .
The problem in this situation is that the file reference specifies a file path and name for the output file of P3
(typically p3.dll), while the project references identify the source project ( P3 ) by project name. Because of this, the
compiler cannot guarantee that the type P3.commonClass comes from the same source code through the two
different references.
This situation typically occurs when project references and file references are mixed. In the preceding illustration,
the problem would not occur if P1 made a direct project reference to P3 instead of a file reference.
Error ID: BC30955
See Also
Type Conversions in Visual Basic
Managing references in a project
NIB How to: Add or Remove References By Using the Add Reference Dialog Box
Value of type '<typename1>' cannot be converted to
'<typename2>' (Multiple file references)
7/29/2017 • 1 min to read • Edit Online
Value of type '<typename1>' cannot be converted to '<typename2>'. Type mismatch could be due to mixing a file
reference to '<filepath1>' in project '<projectname1>' with a file reference to '<filepath2>' in project
'<projectname2>'. If both assemblies are identical, try replacing these references so both references are from the
same location.
In a situation where a project makes more than one file reference to an assembly, the compiler cannot guarantee
that one type can be converted to another.
Each file reference specifies a file path and name for the output file of a project (typically a DLL file). The compiler
cannot guarantee that the output files come from the same source, or that they represent the same version of the
same assembly. Therefore, it cannot guarantee that the types in the different references are the same type, or even
that one can be converted to the other.
You can use a single file reference if you know that the referenced assemblies have the same assembly identity. The
assembly identity includes the assembly's name, version, public key if any, and culture. This information uniquely
identifies the assembly.
Error ID: BC30961
See Also
Type Conversions in Visual Basic
Managing references in a project
NIB How to: Add or Remove References By Using the Add Reference Dialog Box
Value of type 'type1' cannot be converted to 'type2'
7/29/2017 • 1 min to read • Edit Online
Value of type 'type1' cannot be converted to 'type2'. You can use the 'Value' property to get the string value of the
first element of '<parentElement>'.
An attempt has been made to implicitly cast an XML literal to a specific type. The XML literal cannot be implicitly
cast to the specified type.
Error ID: BC31194
See Also
Convert
Type Conversion Functions
XML Literals
XML
Variable '<variablename>' hides a variable in an
enclosing block
7/29/2017 • 1 min to read • Edit Online
A variable enclosed in a block has the same name as another local variable.
Error ID: BC30616
Dim a, b, x As Integer
If a = b Then
Dim y As Integer = 20 ' Uniquely named block variable.
End If
A common cause for this error is the use of Catch e As Exception inside an event handler. If this is the case,
name the Catch block variable ex rather than e .
Another common source of this error is an attempt to access a local variable declared within a Try block in
a separate Catch block. To correct this, declare the variable outside the Try...Catch...Finally structure.
See Also
Try...Catch...Finally Statement
Variable Declaration
Variable '<variablename>' is used before it has been
assigned a value
7/29/2017 • 1 min to read • Edit Online
Variable '<variablename>' is used before it has been assigned a value. A null reference exception could result at run
time.
An application has at least one possible path through its code that reads a variable before any value is assigned to
it.
If a variable has never been assigned a value, it holds the default value for its data type. For a reference data type,
that default value is Nothing. Reading a reference variable that has a value of Nothing can cause a
NullReferenceException in some circumstances.
By default, this message is a warning. For more information on hiding warnings or treating warnings as errors, see
Configuring Warnings in Visual Basic.
Error ID: BC42104
See Also
Dim Statement
Variable Declaration
Troubleshooting Variables
Variable uses an Automation type not supported in
Visual Basic
7/29/2017 • 1 min to read • Edit Online
You tried to use a variable defined in a type library or object library that has a data type not supported by Visual
Basic.
See Also
Data Types
XML axis properties do not support late binding
7/29/2017 • 1 min to read • Edit Online
See Also
XML Axis Properties
XML
XML comment exception must have a 'cref' attribute
7/29/2017 • 1 min to read • Edit Online
The <exception> tag provides a way to document the exceptions that may be thrown by a method. The required
cref attribute designates the name of a member, which is checked by the documentation generator. If the member
exists, it is translated to the canonical element name in the documentation file.
Error ID: BC42319
'''<exception cref="member">description</exception>
See Also
<exception>
How to: Create XML Documentation
XML Comment Tags
XML entity references are not supported
7/29/2017 • 1 min to read • Edit Online
An entity reference (for example, © ) that is not defined in the XML 1.0 specification is included as a value for an
XML literal. Only & , " , < , > , and ' XML entity references are supported in XML literals.
Error ID: BC31180
See Also
XML Literals and the XML 1.0 Specification
XML Literals
XML
XML literals and XML properties are not supported in
embedded code within ASP.NET
7/29/2017 • 1 min to read • Edit Online
XML literals and XML properties are not supported in embedded code within ASP.NET. To use XML features, move
the code to code-behind.
An XML literal or XML axis property is defined within embedded code ( <%= => ) in an ASP.NET file.
Error ID: BC31200
See Also
XML Literals
XML Axis Properties
XML
XML namespace URI
'http://www.w3.org/XML/1998/namespace'; can be
bound only to 'xmlns'
7/29/2017 • 1 min to read • Edit Online
The URI http://www.w3.org/XML/1998/namespace is used in an XML namespace declaration. This URI is a reserved
namespace and cannot be included in an XML namespace declaration.
Error ID: BC31183
See Also
Imports Statement (XML Namespace)
XML Literals
XML
Reference (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
This section provides links to reference information about various aspects of Visual Basic programming.
In This Section
Visual Basic Language Reference
Provides reference information for various aspects of the Visual Basic language.
Visual Basic Command-Line Compiler
Provides links to information about the command-line compiler, which provides an alternative to compiling
programs from the Visual Studio IDE.
.NET Framework Reference Information
Provides links to information on working with the .NET Framework class library.
Visual Basic Language Specification
Provides links to the complete Visual Basic language specification, which contains detailed information on all
aspects of the language.
Reference
Microsoft.VisualBasic.PowerPacks
This namespace contains classes for the Visual Basic Power Packs controls. Visual Basic Power Packs controls are
additional Windows Forms controls.
Microsoft.VisualBasic.PowerPacks.Printing
This namespace provides a component that enables you to print a facsimile of the form as it appears on screen.
Related Sections
General User Interface Elements (Visual Studio)
Contains topics for dialog boxes and windows used in Visual Studio.
XML Tools in Visual Studio
Provides links to topics on various XML tools available in Visual Studio.
Automation and Extensibility Reference
Provides links to topics covering automation and extensibility in Visual Studio, for both shared and language-
specific components.
Visual Basic Command-Line Compiler
7/29/2017 • 1 min to read • Edit Online
The Visual Basic command-line compiler provides an alternative to compiling programs from within the
Visual Studio integrated development environment (IDE). This section contains descriptions for the Visual
Basic compiler options.
In This Section
Building from the Command Line
Describes the Visual Basic command-line compiler, which is provided as an alternative to compiling
programs from within the Visual Studio IDE.
Visual Basic Compiler Options Listed Alphabetically
Lists compiler options in an alphabetical table.
Visual Basic Compiler Options Listed by Category
Presents compiler options in functional groups.
Related Sections
NIB: Managing Project Properties with the Project Designer
Discusses how to use the Project Designer to specify global settings for your project.
Visual Basic
The starting point for the Visual Basic Help.
Building from the Command Line (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
A Visual Basic project is made up of one or more separate source files. During the process known as compilation,
these files are brought together into one package—a single executable file that can be run as an application.
Visual Basic provides a command-line compiler as an alternative to compiling programs from within the Visual
Studio integrated development environment (IDE). The command-line compiler is designed for situations in which
you do not require the full set of features in the IDE—for example, when you are using or writing for computers
with limited system memory or storage space.
When compiling from the command line, you must explicitly reference the Microsoft Visual Basic run-time library
through the /reference compiler option.
To compile source files from within the Visual Studio IDE, choose the Build command from the Build menu.
TIP
When you build project files by using the Visual Studio IDE, you can display information about the associated vbc command
and its switches in the output window. To display this information, open the Options Dialog Box, Projects and Solutions,
Build and Run, and then set the MSBuild project build output verbosity to Normal or a higher level of verbosity. For
more information, see How to: View, Save, and Configure Build Log Files.
You can compile project (.vbproj) files at a command prompt by using MSBuild. For more information, see
Command-Line Reference and Walkthrough: Using MSBuild.
In This Section
How to: Invoke the Command-Line Compiler
Describes how to invoke the command-line compiler at the MS-DOS prompt or from a specific subdirectory.
Sample Compilation Command Lines
Provides a list of sample command lines that you can modify for your own use.
Related Sections
Visual Basic Command-Line Compiler
Provides lists of compiler options, organized alphabetically or by purpose.
Conditional Compilation
Describes how to compile particular sections of code.
Building and Cleaning Projects and Solutions in Visual Studio
Describes how to organize what will be included in different builds, choose project properties, and ensure that
projects build in the correct order.
How to: Invoke the Command-Line Compiler (Visual
Basic)
7/29/2017 • 2 min to read • Edit Online
You can invoke the command-line compiler by typing the name of its executable file into the command line, also
known as the MS-DOS prompt. If you compile from the default Windows Command Prompt, you must type the
fully qualified path to the executable file. To override this default behavior, you can either use the Visual Studio
Command Prompt, or modify the PATH environment variable. Both allow you to compile from any directory by
simply typing the compiler name.
NOTE
Your computer might show different names or locations for some of the Visual Studio user interface elements in the following
instructions. The Visual Studio edition that you have and the settings that you use determine these elements. For more
information, see Personalizing the IDE.
See Also
Visual Basic Command-Line Compiler
Conditional Compilation
Sample Compilation Command Lines (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
As an alternative to compiling Visual Basic programs from within Visual Studio, you can compile from the
command line to produce executable (.exe) files or dynamic-link library (.dll) files.
The Visual Basic command-line compiler supports a complete set of options that control input and output
files, assemblies, and debug and preprocessor options. Each option is available in two interchangeable forms:
-``option and /``option . This documentation shows only the /``option form.
The following table lists some sample command lines you can modify for your own use.
TO USE
Compile all Visual Basic files in the current directory, with vbc /define:DEBUG=1 /optimize /out:File2.exe *.vb
optimizations on and the DEBUG symbol defined,
producing File2.exe
Compile all Visual Basic files in the current directory, vbc /target:library /out:File2.dll /nowarn /nologo
producing a debug version of File2.dll without displaying /debug *.vb
the logo or warnings
Compile all Visual Basic files in the current directory to vbc /target:library /out:Something.dll *.vb
Something.dll
When compiling from the command line, you must explicitly reference the Microsoft Visual Basic run-time
library through the /reference compiler option.
TIP
When you build a project by using the Visual Studio IDE, you can display information about the associated vbc
command with its compiler options in the output window. To display this information, open the Options Dialog Box,
Projects and Solutions, Build and Run, and then set the MSBuild project build output verbosity to Normal or a
higher level of verbosity. For more information, see How to: View, Save, and Configure Build Log Files.
See Also
Visual Basic Command-Line Compiler
Conditional Compilation
Visual Basic Compiler Options Listed Alphabetically
7/29/2017 • 3 min to read • Edit Online
The Visual Basic command-line compiler is provided as an alternative to compiling programs from the Visual
Studio integrated development environment (IDE). The following is a list of the Visual Basic command-line compiler
options sorted alphabetically.
OPTION PURPOSE
/addmodule Causes the compiler to make all type information from the
specified file(s) available to the project you are currently
compiling.
/analyzer Run the analyzers from this assembly (Short form: /a)
/checksumalgorithm:<alg> Specify the algorithm for calculating the source file checksum
stored in PDB. Supported values are: SHA1 (default) or
SHA256.
/codepage Specifies the code page to use for all source code files in the
compilation.
/errorreport Specifies how the Visual Basic compiler should report internal
compiler errors.
/main Specifies the class that contains the Sub Main procedure to
use at startup.
/platform Specifies the processor platform the compiler targets for the
output file.
See Also
Visual Basic Compiler Options Listed by Category
Introduction to the Project Designer
C# Compiler Options Listed Alphabetically
C# Compiler Options Listed by Category
@ (Specify Response File) (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
Specifies a file that contains compiler options and source-code files to compile.
Syntax
@response_file
Arguments
response_file
Required. A file that lists compiler options or source-code files to compile. Enclose the file name in quotation marks
(" ") if it contains a space.
Remarks
The compiler processes the compiler options and source-code files specified in a response file as if they had been
specified on the command line.
To specify more than one response file in a compilation, specify multiple response-file options, such as the
following.
@file1.rsp @file2.rsp
In a response file, multiple compiler options and source-code files can appear on one line. A single compiler-option
specification must appear on one line (cannot span multiple lines). Response files can have comments that begin
with the # symbol.
You can combine options specified on the command line with options specified in one or more response files. The
compiler processes the command options as it encounters them. Therefore, command-line arguments can override
previously listed options in response files. Conversely, options in a response file override options listed previously
on the command line or in other response files.
Visual Basic provides the Vbc.rsp file, which is located in the same directory as the Vbc.exe file. The Vbc.rsp file is
included by default, unless the /noconfig option is used. For more information, see /noconfig.
NOTE
The @ option is not available from within the Visual Studio development environment; it is available only when compiling
from the command line.
Example
The following lines are from a sample response file.
# build the first output file
/target:exe
/out:MyExe.exe
source1.vb
source2.vb
Example
The following example demonstrates how to use the @ option with the response file named File1.rsp .
vbc @file1.rsp
See Also
Visual Basic Command-Line Compiler
/noconfig
Sample Compilation Command Lines
/addmodule
7/29/2017 • 1 min to read • Edit Online
Causes the compiler to make all type information from the specified file(s) available to the project you are
currently compiling.
Syntax
/addmodule:fileList
Arguments
fileList
Required. Comma-delimited list of files that contain metadata but do not contain assembly manifests. File names
containing spaces should be surrounded by quotation marks (" ").
Remarks
The files listed by the fileList parameter must be created with the /target:module option, or with another
compiler's equivalent to /target:module .
All modules added with /addmodule must be in the same directory as the output file at run time. That is, you can
specify a module in any directory at compile time, but the module must be in the application directory at run time.
If it is not, you get a TypeLoadException error.
If you specify (implicitly or explicitly) any/target (Visual Basic) option other than /target:module with /addmodule ,
the files you pass to /addmodule become part of the project's assembly. An assembly is required to run an output
file that has one or more files added with /addmodule .
Use /reference (Visual Basic) to import metadata from a file that contains an assembly.
NOTE
The /addmodule option is not available from within the Visual Studio development environment; it is available only when
compiling from the command line.
Example
The following code creates a module.
' t1.vb
' Compile with vbc /target:module t1.vb.
' Outputs t1.netmodule.
Namespace NetmoduleTest
Module Module1
Sub Main()
Dim x As TestClass
x = New TestClass
x.i = 802
System.Console.WriteLine(x.i)
End Sub
End Module
End Namespace
See Also
Visual Basic Command-Line Compiler
/target (Visual Basic)
/reference (Visual Basic)
Sample Compilation Command Lines
/baseaddress
7/29/2017 • 1 min to read • Edit Online
Syntax
/baseaddress:address
Arguments
TERM DEFINITION
address Required. The base address for the DLL. This address must be
specified as a hexadecimal number.
Remarks
The default base address for a DLL is set by the .NET Framework.
Be aware that the lower-order word in this address is rounded. For example, if you specify 0x11110001, it is
rounded to 0x11110000.
To complete the signing process for a DLL, use the –R option of the Strong Naming tool (Sn.exe).
This option is ignored if the target is not a DLL.
1. Have a project selected in Solution Explorer. On the Project menu, click Properties. For more information, see Introduction
to the Project Designer.
2. Click the Compile tab.
3. Click Advanced.
4. Modify the value in the DLL base address: box. Note: The DLL base address: box is read-only unless the target is a DLL.
See Also
Visual Basic Command-Line Compiler
/target (Visual Basic)
Sample Compilation Command Lines
Sn.exe (Strong Name Tool)
/bugreport
7/29/2017 • 1 min to read • Edit Online
Creates a file that you can use when you file a bug report.
Syntax
/bugreport:file
Arguments
TERM DEFINITION
file Required. The name of the file that will contain your bug
report. Enclose the file name in quotation marks (" ") if the
name contains a space.
Remarks
The following information is added to file :
A copy of all source-code files in the compilation.
A list of the compiler options used in the compilation.
Version information about your compiler, common language runtime, and operating system.
Compiler output, if any.
A description of the problem, for which you are prompted.
A description of how you think the problem should be fixed, for which you are prompted.
Because a copy of all source-code files is included in file , you may want to reproduce the (suspected) code
defect in the shortest possible program.
IMPORTANT
The /bugreport option produces a file that contains potentially sensitive information. This includes current time, compiler
version, .NET Framework version, OS version, user name, the command-line arguments with which the compiler was run, all
source code, and the binary form of any referenced assembly. This option can be accessed by specifying command-line
options in the Web.config file for a server-side compilation of an ASP.NET application. To prevent this, modify the
Machine.config file to disallow users from compiling on the server.
If this option is used with /errorreport:prompt , /errorreport:queue , or /errorreport:send , and your application
encounters an internal compiler error, the information in file is sent to Microsoft Corporation. That information
will help Microsoft engineers identify the cause of the error and may help improve the next release of Visual Basic.
By default, no information is sent to Microsoft. However, when you compile an application by using
/errorreport:queue , which is enabled by default, the application collects its error reports. Then, when the
computer's administrator logs in, the error reporting system displays a pop-up window that enables the
administrator to forward to Microsoft any error reports that occurred since the logon.
NOTE
The /bugreport option is not available from within the Visual Studio development environment; it is available only when
you compile from the command line.
Example
The following example compiles T2.vb and puts all bug-reporting information in the file Problem.txt .
See Also
Visual Basic Command-Line Compiler
/debug (Visual Basic)
/errorreport
Sample Compilation Command Lines
trustLevel Element for securityPolicy (ASP.NET Settings Schema)
/codepage (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
Specifies the code page to use for all source-code files in the compilation.
Syntax
/codepage:id
Arguments
TERM DEFINITION
Remarks
To compile source code saved with a specific encoding, you can use /codepage to specify which code page should
be used. The /codepage option applies to all source-code files in your compilation. For more information, see
Character Encoding in the .NET Framework.
The /codepage option is not needed if the source-code files were saved using the current ANSI code page, Unicode,
or UTF-8 with a signature. Visual Studio saves all source-code files with the current ANSI code page by default,
unless the user specifies another encoding in the Encoding dialog box. Visual Studio uses the Encoding dialog
box to open source-code files saved with a different code page.
NOTE
The /codepage option is not available from within the Visual Studio development environment; it is available only when
compiling from the command line.
See Also
Visual Basic Command-Line Compiler
/debug (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
Causes the compiler to generate debugging information and place it in the output file(s).
Syntax
/debug[+ | -]
' -or-
/debug:[full | pdbonly]
Arguments
TERM DEFINITION
Remarks
Use this option to create debug builds. If you do not specify /debug , /debug+ , or /debug:full , you will be unable
to debug the output file of your program.
By default, debugging information is not emitted ( /debug- ). To emit debugging information, specify /debug or
/debug+ .
For information on how to configure the debug performance of an application, see Making an Image Easier to
Debug.
1. With a project selected in Solution Explorer, on the Project menu, click Properties. For more information, see Introduction
to the Project Designer.
2. Click the Compile tab.
3. Click Advanced Compile Options.
4. Modify the value in the Generate Debug Info box.
Example
The following example puts debugging information in output file App.exe .
vbc /debug /out:app.exe test.vb
See Also
Visual Basic Command-Line Compiler
/bugreport
Sample Compilation Command Lines
/define (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
Syntax
/define:["]symbol[=value][,symbol[=value]]["]
' -or-
/d:["]symbol[=value][,symbol[=value]]["]
Arguments
TERM DEFINITION
Remarks
The /define option has an effect similar to using a #Const preprocessor directive in your source file, except that
constants defined with /define are public and apply to all files in the project.
You can use symbols created by this option with the #If ... Then ... #Else directive to compile source files
conditionally.
/d is the short form of /define .
You can define multiple symbols with /define by using a comma to separate symbol definitions.
1. Have a project selected in Solution Explorer. On the Project menu, click Properties. For more information, see Introduction
to the Project Designer.
2. Click the Compile tab.
3. Click Advanced.
4. Modify the value in the Custom Constants box.
Example
The following code defines and then uses two conditional compiler constants.
' Vbc /define:DEBUGMODE=True,TRAPERRORS=False test.vb
Sub mysub()
#If debugmode Then
' Insert debug statements here.
MsgBox("debug mode")
#Else
' Insert default statements here.
#End If
End Sub
See Also
Visual Basic Command-Line Compiler
#If...Then...#Else Directives
#Const Directive
Sample Compilation Command Lines
/delaysign
7/29/2017 • 1 min to read • Edit Online
Syntax
/delaysign[+ | -]
Arguments
+ | -
Optional. Use /delaysign- if you want a fully signed assembly. Use /delaysign+ if you want to place the public
key in the assembly and reserve space for the signed hash. The default is /delaysign- .
Remarks
The /delaysign option has no effect unless used with /keyfile or /keycontainer.
When you request a fully signed assembly, the compiler hashes the file that contains the manifest (assembly
metadata) and signs that hash with the private key. The resulting digital signature is stored in the file that contains
the manifest. When an assembly is delay signed, the compiler does not compute and store the signature but
reserves space in the file so the signature can be added later.
For example, by using /delaysign+ , a developer in an organization can distribute unsigned test versions of an
assembly that testers can register with the global assembly cache and use. When work on the assembly is
completed, the person responsible for the organization's private key can fully sign the assembly. This
compartmentalization protects the organization's private key from disclosure, while allowing all developers to
work on the assemblies.
See Creating and Using Strong-Named Assemblies for more information on signing an assembly.
To set /delaysign in the Visual Studio integrated development environment
1. Have a project selected in Solution Explorer. On the Project menu, click Properties. For more
information, see Introduction to the Project Designer.
2. Click the Signing tab.
3. Set the value in the Delay sign only box.
See Also
Visual Basic Command-Line Compiler
/keyfile
/keycontainer
Sample Compilation Command Lines
/doc
7/29/2017 • 1 min to read • Edit Online
Syntax
/doc[+ | -]
' -or-
/doc:file
Arguments
TERM DEFINITION
Remarks
The /doc option controls whether the compiler generates an XML file containing the documentation
comments. If you use the /doc:``file syntax, the file parameter specifies the name of the XML file. If you
use /doc or /doc+ , the compiler takes the XML file name from the executable file or library that the compiler
is creating. If you use /doc- or do not specify the /doc option, the compiler does not create an XML file.
In source-code files, documentation comments can precede the following definitions:
User-defined types, such as a class or interface
Members, such as a field, event, property, function, or subroutine.
To use the generated XML file with the Visual Studio IntelliSense feature, let the file name of the XML file be the
same as the assembly you want to support. Make sure the XML file is in the same directory as the assembly so
that when the assembly is referenced in the Visual Studio project, the .xml file is found as well. XML
documentation files are not required for IntelliSense to work for code within a project or within projects
referenced by a project.
Unless you compile with /target:module , the XML file contains the tags <assembly></assembly> . These tags
specify the name of the file containing the assembly manifest for the output file of the compilation.
See XML Comment Tags for ways to generate documentation from comments in your code.
TO SET /DOC IN THE VISUAL STUDIO INTEGRATED DEVELOPMENT ENVIRONMENT
1. Have a project selected in Solution Explorer. On the Project menu, click Properties. For more information, see
Introduction to the Project Designer.
2. Click the Compile tab.
3. Set the value in the Generate XML documentation file box.
Example
See Documenting Your Code with XML for a sample.
See Also
Visual Basic Command-Line Compiler
Documenting Your Code with XML
/errorreport
7/29/2017 • 2 min to read • Edit Online
Specifies how the Visual Basic compiler should report internal compiler errors.
Syntax
/errorreport:{ prompt | queue | send | none }
Remarks
This option provides a convenient way to report a Visual Basic internal compiler error (ICE) to the Visual Basic team
at Microsoft. By default, the compiler sends no information to Microsoft. However, if you do encounter an internal
compiler error, this option allows you to report the error to Microsoft. That information will help Microsoft
engineers identify the cause and may help improve the next release of Visual Basic.
A user's ability to send reports depends on machine and user policy permissions.
The following table summarizes the effect of the /errorreport option.
OPTION BEHAVIOR
queue Queues the error report. When you log in with administrator
privileges, you can report any failures since the last time you
were logged in (you will not be prompted to send reports for
failures more than once every three days). This is the default
behavior when the /errorreport option is not specified.
send If an internal compiler error occurs, and the machine and user
policy settings allow it, the compiler sends the data to
Microsoft.
The compiler sends data that includes the stack at the time of the error, which usually includes some source code. If
/errorreport is used with the /bugreport option, then the entire source file is sent.
This option is best used with the /bugreport option, because it allows Microsoft engineers to more easily reproduce
the error.
NOTE
The /errorreport option is not available from within the Visual Studio development environment; it is available only when
compiling from the command line.
Example
The following code attempts to compile T2.vb , and if the compiler encounters an internal compiler error, it
prompts you to send the error report to Microsoft.
See Also
Visual Basic Command-Line Compiler
Sample Compilation Command Lines
/bugreport
/filealign
7/29/2017 • 1 min to read • Edit Online
Syntax
/filealign:number
Arguments
number
Required. A value that specifies the alignment of sections in the output file. Valid values are 512, 1024, 2048, 4096,
and 8192. These values are in bytes.
Remarks
You can use the /filealign option to specify the alignment of sections in your output file. Sections are blocks of
contiguous memory in a Portable Executable (PE) file that contains either code or data. The /filealign option lets
you compile your application with a nonstandard alignment; most developers do not need to use this option.
Each section is aligned on a boundary that is a multiple of the /filealign value. There is no fixed default. If
/filealign is not specified, the compiler picks a default at compile time.
By specifying the section size, you can change the size of the output file. Modifying section size may be useful for
programs that will run on smaller devices.
NOTE
The /filealign option is not available from within the Visual Studio development environment; it is available only when
compiling from the command line.
See Also
Visual Basic Command-Line Compiler
/help, /? (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
Syntax
/help
' -or-
/?
Remarks
If you include this option in a compilation, no output file is created and no compilation takes place.
NOTE
The /help option is not available from within the Visual Studio development environment; it is available only when
compiling from the command line.
Example
The following code displays help from the command line.
vbc /help
See Also
Visual Basic Command-Line Compiler
Sample Compilation Command Lines
/highentropyva (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
Indicates whether a 64-bit executable or an executable that's marked by the /platform:anycpu compiler option
supports high entropy Address Space Layout Randomization (ASLR).
Syntax
/highentropyva[+ | -]
Arguments
+ | -
Optional. The option is off by default or if you specify /highentropyva- . The option is on if you specify
/highentropyva or /highentropyva+ .
Remarks
If you specify this option, compatible versions of the Windows kernel can use higher degrees of entropy when the
kernel randomizes the address space layout of a process as part of ASLR. If the kernel uses higher degrees of
entropy, a larger number of addresses can be allocated to memory regions such as stacks and heaps. As a result, it
is more difficult to guess the location of a particular memory region.
When the option is on, the target executable and any modules on which it depends must be able to handle pointer
values that are larger than 4 gigabytes (GB) when those modules are running as 64-bit processes.
See Also
Visual Basic Command-Line Compiler
Sample Compilation Command Lines
/imports (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
Syntax
/imports:namespaceList
Arguments
TERM DEFINITION
Remarks
The /imports option imports any namespace defined within the current set of source files or from any referenced
assembly.
The members in a namespace specified with /imports are available to all source-code files in the compilation. Use
the Imports Statement (.NET Namespace and Type) to use a namespace in a single source-code file.
1. Have a project selected in Solution Explorer. On the Project menu, click Properties. For more information, see Introduction
to the Project Designer.
2. Click the References tab.
3. Enter the namespace name in the box beside the Add User Import button.
4. Click the Add User Import button.
Example
The following code compiles when /imports:system is specified.
Module MyModule
Sub Main()
Console.WriteLine("test")
' Otherwise, would need
' System.Console.WriteLine("test")
End Sub
End Module
See Also
Visual Basic Command-Line Compiler
References and the Imports Statement
Sample Compilation Command Lines
/keycontainer
7/29/2017 • 1 min to read • Edit Online
Specifies a key container name for a key pair to give an assembly a strong name.
Syntax
/keycontainer:container
Arguments
TERM DEFINITION
container Required. Container file that contains the key. Enclose the file
name in quotation marks ("") if the name contains a space.
Remarks
The compiler creates the sharable component by inserting a public key into the assembly manifest and by signing
the final assembly with the private key. To generate a key file, type sn -k``file at the command line. The -i
option installs the key pair into a container. For more information, see Sn.exe (Strong Name Tool).
If you compile with /target:module , the name of the key file is held in the module and incorporated into the
assembly that is created when you compile an assembly with /addmodule.
You can also specify this option as a custom attribute (AssemblyKeyNameAttribute) in the source code for any
Microsoft intermediate language (MSIL) module.
You can also pass your encryption information to the compiler with /keyfile. Use /delaysign if you want a partially
signed assembly.
See Creating and Using Strong-Named Assemblies for more information on signing an assembly.
NOTE
The /keycontainer option is not available from within the Visual Studio development environment; it is available only
when compiling from the command line.
Example
The following code compiles source file Input.vb and specifies a key container.
See Also
Assemblies and the Global Assembly Cache
Visual Basic Command-Line Compiler
/keyfile
Sample Compilation Command Lines
/keyfile
7/29/2017 • 1 min to read • Edit Online
Specifies a file containing a key or key pair to give an assembly a strong name.
Syntax
/keyfile:file
Arguments
file
Required. File that contains the key. If the file name contains a space, enclose the name in quotation marks (" ").
Remarks
The compiler inserts the public key into the assembly manifest and then signs the final assembly with the private
key. To generate a key file, type sn -k file at the command line. For more information, see Sn.exe (Strong Name
Tool).
If you compile with /target:module , the name of the key file is held in the module and incorporated into the
assembly that is created when you compile an assembly with /addmodule.
You can also pass your encryption information to the compiler with /keycontainer. Use /delaysign if you want a
partially signed assembly.
You can also specify this option as a custom attribute (AssemblyKeyFileAttribute) in the source code for any
Microsoft intermediate language module.
In case both /keyfile and /keycontainer are specified (either by command-line option or by custom attribute) in
the same compilation, the compiler first tries the key container. If that succeeds, then the assembly is signed with
the information in the key container. If the compiler does not find the key container, it tries the file specified with
/keyfile . If this succeeds, the assembly is signed with the information in the key file, and the key information is
installed in the key container (similar to sn -i ) so that on the next compilation, the key container will be valid.
Note that a key file might contain only the public key.
See Creating and Using Strong-Named Assemblies for more information on signing an assembly.
NOTE
The /keyfile option is not available from within the Visual Studio development environment; it is available only when
compiling from the command line.
Example
The following code compiles source file Input.vb and specifies a key file.
Causes the compiler to accept only syntax that is included in the specified Visual Basic language version.
Syntax
/langversion:version
Arguments
version
Required. The language version to be used during the compilation. Accepted values are 9 , 9.0 , 10 , and 10.0 .
Remarks
The /langversion option specifies what syntax the compiler accepts. For example, if you specify that the language
version is 9.0, the compiler generates errors for syntax that is valid only in version 10.0 and later.
You can use this option when you develop applications that target different versions of the .NET Framework. For
example, if you are targeting .NET Framework 3.5, you could use this option to ensure that you do not use syntax
from language version 10.0.
You can set /langversion directly only by using the command line. For more information, see Targeting a Specific
.NET Framework Version.
Example
The following code compiles sample.vb for Visual Basic 9.0.
See Also
Visual Basic Command-Line Compiler
Sample Compilation Command Lines
Targeting a Specific .NET Framework Version
/libpath
7/29/2017 • 1 min to read • Edit Online
Syntax
/libpath:dirList
Arguments
TERM DEFINITION
Remarks
The /libpath option specifies the location of assemblies referenced by the /reference option.
The compiler searches for assembly references that are not fully qualified in the following order:
1. Current working directory. This is the directory from which the compiler is invoked.
2. The common language runtime system directory.
3. Directories specified by /libpath .
4. Directories specified by the LIB environment variable.
The /libpath option is additive; specifying it more than once appends to any prior values.
Use /reference to specify an assembly reference.
1. Have a project selected in Solution Explorer. On the Project menu, click Properties. For more information, see Introduction
to the Project Designer.
2. Click the References tab.
3. Click the Reference Paths... button.
4. In the Reference Paths dialog box, enter the directory name in the Folder: box.
5. Click Add Folder.
Example
The following code compiles T2.vb to create an .exe file. The compiler looks in the working directory, in the root
directory of the C: drive, and in the New Assemblies directory of the C: drive for assembly references.
vbc /libpath:c:\;"c:\New Assemblies" /reference:t2.dll t2.vb
See Also
Assemblies and the Global Assembly Cache
Visual Basic Command-Line Compiler
Sample Compilation Command Lines
/link (Visual Basic)
7/29/2017 • 3 min to read • Edit Online
Causes the compiler to make COM type information in the specified assemblies available to the project that you
are currently compiling.
Syntax
/link:fileList
' -or-
/l:fileList
Arguments
TERM DEFINITION
Remarks
The /link option enables you to deploy an application that has embedded type information. The application can
then use types in a runtime assembly that implement the embedded type information without requiring a
reference to the runtime assembly. If various versions of the runtime assembly are published, the application that
contains the embedded type information can work with the various versions without having to be recompiled. For
an example, see Walkthrough: Embedding Types from Managed Assemblies.
Using the /link option is especially useful when you are working with COM interop. You can embed COM types
so that your application no longer requires a primary interop assembly (PIA) on the target computer. The /link
option instructs the compiler to embed the COM type information from the referenced interop assembly into the
resulting compiled code. The COM type is identified by the CLSID (GUID) value. As a result, your application can run
on a target computer that has installed the same COM types with the same CLSID values. Applications that
automate Microsoft Office are a good example. Because applications like Office usually keep the same CLSID value
across different versions, your application can use the referenced COM types as long as .NET Framework 4 or later
is installed on the target computer and your application uses methods, properties, or events that are included in the
referenced COM types.
The /link option embeds only interfaces, structures, and delegates. Embedding COM classes is not supported.
NOTE
When you create an instance of an embedded COM type in your code, you must create the instance by using the
appropriate interface. Attempting to create an instance of an embedded COM type by using the CoClass causes an error.
To set the /link option in Visual Studio, add an assembly reference and set the Embed Interop Types property to
true. The default for the Embed Interop Types property is false.
If you link to a COM assembly (Assembly A) which itself references another COM assembly (Assembly B), you also
have to link to Assembly B if either of the following is true:
A type from Assembly A inherits from a type or implements an interface from Assembly B.
A field, property, event, or method that has a return type or parameter type from Assembly B is invoked.
Use /libpath to specify the directory in which one or more of your assembly references is located.
Like the /reference compiler option, the /link compiler option uses the Vbc.rsp response file, which references
frequently used .NET Framework assemblies. Use the /noconfig compiler option if you do not want the compiler to
use the Vbc.rsp file.
The short form of /link is /l .
' The following code causes an error if ISampleInterface is an embedded interop type.
Dim sample As ISampleInterface(Of SampleType)
Imports System.Collections.Generic
Imports Microsoft.Office.Interop.Excel
Class Utility
' The following code causes an error when called by a client assembly.
Public Function GetRange1() As List(Of Range)
End Function
' The following code is valid for calls from a client assembly.
Public Function GetRange2() As IList(Of Range)
End Function
End Class
In the following example, client code can call the method that returns the IList generic interface without error.
Module Client
Public Sub Main()
Dim util As New Utility()
Example
The following code compiles source file OfficeApp.vb and reference assemblies from COMData1.dll and
COMData2.dll to produce OfficeApp.exe .
See Also
Visual Basic Command-Line Compiler
Walkthrough: Embedding Types from Managed Assemblies
/reference (Visual Basic)
/noconfig
/libpath
Sample Compilation Command Lines
Introduction to COM Interop
/linkresource (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
Syntax
/linkresource:filename[,identifier[,public|private]]
' -or-
/linkres:filename[,identifier[,public|private]]
Arguments
filename
Required. The resource file to link to the assembly. If the file name contains a space, enclose the name in quotation
marks (" ").
identifier
Optional. The logical name for the resource. The name that is used to load the resource. The default is the name of
the file. Optionally, you can specify whether the file is public or private in the assembly manifest, for example:
/linkres:filename.res,myname.res,public . By default, filename is public in the assembly.
Remarks
The /linkresource option does not embed the resource file in the output file; use the /resource option to do this.
The /linkresource option requires one of the /target options other than /target:module .
If filename is a .NET Framework resource file created, for example, by the Resgen.exe (Resource File Generator) or
in the development environment, it can be accessed with members in the System.Resources namespace. (For more
information, see ResourceManager.) To access all other resources at run time, use the methods that begin with
GetManifestResource in the Assembly class.
The file name can be any file format. For example, you may want to make a native DLL part of the assembly, so that
it can be installed into the global assembly cache and accessed from managed code in the assembly.
The short form of /linkresource is /linkres .
NOTE
The /linkresource option is not available from the Visual Studio development environment; it is available only when you
compile from the command line.
Example
The following code compiles In.vb and links to resource file Rf.resource .
Specifies the class or module that contains the Sub Main procedure.
Syntax
/main:location
Arguments
location
Required. A full qualification to the class or module that contains the Sub Main procedure to be called when the
program starts. This may be in the form /main:module or /main:namespace.module.
Remarks
Use this option when you create an executable file or Windows executable program. If the /main option is omitted,
the compiler searches for a valid shared Sub Main in all public classes and modules.
See Main Procedure in Visual Basic for a discussion of the various forms of the Main procedure.
When location is a class that inherits from Form, the compiler provides a default Main procedure that starts the
application if the class has no Main procedure. This lets you compile code at the command line that was created in
the development environment.
Example
The following code compiles T2.vb and T3.vb , specifying that the Sub Main procedure will be found in the
Test2 class.
vbc t2.vb t3.vb /main:Test2
See Also
Visual Basic Command-Line Compiler
/target (Visual Basic)
Sample Compilation Command Lines
NIB: Visual Basic Version of Hello, World
Main Procedure in Visual Basic
/moduleassemblyname
7/29/2017 • 1 min to read • Edit Online
Specifies the name of the assembly that this module will be a part of.
Syntax
/moduleassemblyname:assembly_name
Arguments
TERM DEFINITION
assembly_name The name of the assembly that this module will be a part of.
Remarks
The compiler processes the /moduleassemblyname option only if the /target:module option has been specified. This
causes the compiler to create a module. The module created by the compiler is valid only for the assembly
specified with the /moduleassemblyname option. If you place the module in a different assembly, run-time errors will
occur.
The /moduleassemblyname option is needed only when the following are true:
A data type in the module needs access to a Friend type in a referenced assembly.
The referenced assembly has granted friend assembly access to the assembly into which the module will be
built.
For more information about creating a module, see /target (Visual Basic). For more information about friend
assemblies, see Friend Assemblies.
NOTE
The /moduleassemblyname option is not available from within the Visual Studio development environment; it is available
only when you compile from a command prompt.
See Also
How to: Build a Multifile Assembly
Visual Basic Command-Line Compiler
/target (Visual Basic)
/main
/reference (Visual Basic)
/addmodule
Assemblies and the Global Assembly Cache
Sample Compilation Command Lines
Friend Assemblies
/netcf
7/29/2017 • 2 min to read • Edit Online
Syntax
/netcf
Remarks
The /netcf option causes the Visual Basic compiler to target the .NET Compact Framework rather than the full
.NET Framework. Language functionality that is present only in the full .NET Framework is disabled.
The /netcf option is designed to be used with /sdkpath. The language features disabled by /netcf are the same
language features not present in the files targeted with /sdkpath .
NOTE
The /netcf option is not available from within the Visual Studio development environment; it is available only when
compiling from the command line. The /netcf option is set when a Visual Basic device project is loaded.
Module Module1
Sub Main()
End ' not valid to terminate execution with /netcf
End Sub
End Module
Late binding, in all forms, is disabled. Compile-time errors are generated when recognized late-binding
scenarios are encountered. The following program compiles and runs without /netcf but fails at compile
time with /netcf .
Class LateBoundClass
Sub S1()
End Sub
Module Module1
Sub Main()
Dim o1 As Object
Dim o2 As Object
Dim o3 As Object
Dim IntArr(3) As Integer
o1 = New LateBoundClass
o2 = 1
o3 = IntArr
The Auto, Ansi, and Unicode modifiers are disabled. The syntax of the Declare Statement statement is also
modified to Declare Sub|Function name Lib "library" [Alias "alias"] [([arglist])] . The following code
shows the effect of /netcf on a compilation.
Using Visual Basic 6.0 keywords that were removed from Visual Basic generates a different error when
/netcf is used. This affects the error messages for the following keywords:
Open
Close
Put
Write
Input
Lock
Unlock
Seek
Width
Name
FreeFile
EOF
Loc
LOF
Line
Example
The following code compiles Myfile.vb with the .NET Compact Framework, using the versions of mscorlib.dll and
Microsoft.VisualBasic.dll found in the default installation directory of the .NET Compact Framework on the C drive.
Typically, you would use the most recent version of the .NET Compact Framework.
See Also
Visual Basic Command-Line Compiler
Sample Compilation Command Lines
/sdkpath
/noconfig
7/29/2017 • 1 min to read • Edit Online
Specifies that the compiler should not automatically reference the commonly used .NET Framework assemblies or
import the System and Microsoft.VisualBasic namespaces.
Syntax
/noconfig
Remarks
The /noconfig option tells the compiler not to compile with the Vbc.rsp file, which is located in the same
directory as the Vbc.exe file. The Vbc.rsp file references the commonly used .NET Framework assemblies and
imports the System and Microsoft.VisualBasic namespaces. The compiler implicitly references the System.dll
assembly unless the /nostdlib option is specified. The /nostdlib option tells the compiler not to compile with
Vbc.rsp or automatically reference the System.dll assembly.
NOTE
The Mscorlib.dll and Microsoft.VisualBasic.dll assemblies are always referenced.
You can modify the Vbc.rsp file to specify additional compiler options that should be included in every Vbc.exe
compilation (except when specifying the /noconfig option). For more information, see @ (Specify Response File).
The compiler processes the options passed to the vbc command last. Therefore, any option on the command line
overrides the setting of the same option in the Vbc.rsp file.
NOTE
The /noconfig option is not available from within the Visual Studio development environment; it is available only when
compiling from the command line.
See Also
/nostdlib (Visual Basic)
Visual Basic Command-Line Compiler
@ (Specify Response File)
/reference (Visual Basic)
/nologo (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
Suppresses display of the copyright banner and informational messages during compilation.
Syntax
/nologo
Remarks
If you specify /nologo , the compiler does not display a copyright banner. By default, /nologo is not in effect.
NOTE
The /nologo option is not available from within the Visual Studio development environment; it is available only when
compiling from the command line.
Example
The following code compiles T2.vb and does not display a copyright banner.
See Also
Visual Basic Command-Line Compiler
Sample Compilation Command Lines
/nostdlib (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
Syntax
/nostdlib
Remarks
The /nostdlib option removes the automatic reference to the System.dll assembly and prevents the compiler
from reading the Vbc.rsp file. The Vbc.rsp file—which is located in the same directory as the Vbc.exe file—
references the commonly used .NET Framework assemblies and imports the System and Microsoft.VisualBasic
namespaces.
NOTE
The Mscorlib.dll and Microsoft.VisualBasic.dll assemblies are always referenced.
NOTE
The /nostdlib option is not available from within the Visual Studio development environment; it is available only when
compiling from the command line.
Example
The following code compiles T2.vb without referencing the standard libraries. You must set the _MYTYPE
conditional-compilation constant to the string "Empty" to remove the My object.
See Also
/noconfig
Visual Basic Command-Line Compiler
Sample Compilation Command Lines
Customizing Which Objects are Available in My
/nowarn
7/29/2017 • 1 min to read • Edit Online
Syntax
/nowarn[:numberList]
Arguments
TERM DEFINITION
Remarks
The /nowarn option causes the compiler to not generate warnings. To suppress an individual warning, supply the
warning ID to the /nowarn option following the colon. Separate multiple warning numbers with commas.
You need to specify only the numeric part of the warning identifier. For example, if you want to suppress BC42024,
the warning for unused local variables, specify /nowarn:42024 .
For more information on the warning ID numbers, see Configuring Warnings in Visual Basic.
1. Have a project selected in Solution Explorer. On the Project menu, click Properties. For more information, see Introduction
to the Project Designer.
2. Click the Compile tab.
3. Select the Disable all warnings check box to disable all warnings.
- or -
To disable a particular warning, click None from the drop-down list adjacent to the warning.
Example
The following code compiles T2.vb and does not display any warnings.
Example
The following code compiles T2.vb and does not display the warnings for unused local variables (42024).
Instructs the compiler not to embed any application manifest into the executable file.
Syntax
/nowin32manifest
Remarks
When this option is used, the application will be subject to virtualization on Windows Vista unless you provide an
application manifest in a Win32 Resource file or during a later build step. For more information about
virtualization, see ClickOnce Deployment on Windows Vista.
For more information about manifest creation, see /win32manifest (Visual Basic).
See Also
Visual Basic Command-Line Compiler
Application Page, Project Designer (Visual Basic)
/optimize
7/29/2017 • 1 min to read • Edit Online
Syntax
/optimize[ + | - ]
Arguments
TERM DEFINITION
Remarks
Compiler optimizations make your output file smaller, faster, and more efficient. However, because optimizations
result in code rearrangement in the output file, /optimize+ can make debugging difficult.
All modules generated with /target:module for an assembly must use the same /optimize settings as the
assembly. For more information, see /target (Visual Basic).
You can combine the /optimize and /debug options.
1. Have a project selected in Solution Explorer. On the Project menu, click Properties.
For more information, see Introduction to the Project Designer.
2. Click the Compile tab.
3. Click the Advanced button.
4. Modify the Enable optimizations check box.
Example
The following code compiles T2.vb and enables compiler optimizations.
See Also
Visual Basic Command-Line Compiler
/debug (Visual Basic)
Sample Compilation Command Lines
/target (Visual Basic)
/optioncompare
7/29/2017 • 1 min to read • Edit Online
Syntax
/optioncompare:{binary | text}
Remarks
You can specify /optioncompare in one of two forms: /optioncompare:binary to use binary string comparisons,
and /optioncompare:text to use text string comparisons. By default, the compiler uses /optioncompare:binary .
In Microsoft Windows, the code page being used determines the binary sort order. A typical binary sort order is as
follows:
A < B < E < Z < a < b < e < z < À < Ê < Ø < à < ê < ø
Text-based string comparisons are based on a case-insensitive text sort order determined by your system's locale.
A typical text sort order is as follows:
(A = a) < (À = à) < (B=b) < (E=e) < (Ê = ê) < (Z=z) < (Ø = ø)
Example
The following code compiles ProjFile.vb and uses binary string comparisons.
See Also
Visual Basic Command-Line Compiler
/optionexplicit
/optionstrict
/optioninfer
Sample Compilation Command Lines
Option Compare Statement
Visual Basic Defaults, Projects, Options Dialog Box
/optionexplicit
7/29/2017 • 1 min to read • Edit Online
Causes the compiler to report errors if variables are not declared before they are used.
Syntax
/optionexplicit[+ | -]
Arguments
+ | -
Optional. Specify /optionexplicit+ to require explicit declaration of variables. The /optionexplicit+ option is the
default and is the same as /optionexplicit . The /optionexplicit- option enables implicit declaration of
variables.
Remarks
If the source code file contains an Option Explicit Statement, the statement overrides the /optionexplicit
command-line compiler setting.
To set /optionexplicit in the Visual Studio IDE
1. Have a project selected in Solution Explorer. On the Project menu, click Properties. For more
information, see Introduction to the Project Designer.
2. Click the Compile tab.
3. Modify the value in the Option Explicit box.
Example
The following code compiles when /optionexplicit- is used.
Module Module1
Sub Main()
i = 99
System.Console.WriteLine(i)
End Sub
End Module
See Also
Visual Basic Command-Line Compiler
/optioncompare
/optionstrict
/optioninfer
Sample Compilation Command Lines
Option Explicit Statement
Visual Basic Defaults, Projects, Options Dialog Box
/optioninfer
7/29/2017 • 1 min to read • Edit Online
Syntax
/optioninfer[+ | -]
Arguments
TERM DEFINITION
NOTE
You can use the /noconfig option to retain the compiler's internal defaults instead of those specified in vbc.rsp. The
compiler default for this option is /optioninfer- .
Remarks
If the source code file contains an Option Infer Statement, the statement overrides the /optioninfer command-
line compiler setting.
To set /optioninfer in the Visual Studio IDE
1. Select a project in Solution Explorer. On the Project menu, click Properties. For more information, see
NIB: Managing Project Properties with the Project Designer.
2. On the Compile tab, modify the value in the Option infer box.
Example
The following code compiles test.vb with local type inference enabled.
See Also
Visual Basic Command-Line Compiler
/optioncompare
/optionexplicit
/optionstrict
Sample Compilation Command Lines
Option Infer Statement
Local Type Inference
Visual Basic Defaults, Projects, Options Dialog Box
Compile Page, Project Designer (Visual Basic)
/noconfig
Building from the Command Line
/optionstrict
7/29/2017 • 1 min to read • Edit Online
Syntax
/optionstrict[+ | -]
/optionstrict[:custom]
Arguments
+ | -
Optional. The /optionstrict+option restricts implicit type conversion. The default for this option is
/optionstrict- . The /optionstrict+ option is the same as /optionstrict . You can use both for permissive type
semantics.
custom
Required. Warn when strict language semantics are not respected.
Remarks
When /optionstrict+ is in effect, only widening type conversions can be made implicitly. Implicit narrowing type
conversions, such as assigning a Decimal type object to an integer type object, are reported as errors.
To generate warnings for implicit narrowing type conversions, use /optionstrict:custom . Use
/nowarn:numberlist to ignore particular warnings and /warnaserror:numberlist to treat particular warnings as
errors.
To set /optionstrict in the Visual Studio IDE
1. Have a project selected in Solution Explorer. On the Project menu, click Properties. For more
information, see Introduction to the Project Designer.
2. Click the Compile tab.
3. Modify the value in the Option Strict box.
To set /optionstrict programmatically
See Option Strict Statement.
Example
The following code compiles Test.vb using strict type semantics.
See Also
Visual Basic Command-Line Compiler
/optioncompare
/optionexplicit
/optioninfer
/nowarn
/warnaserror (Visual Basic)
Sample Compilation Command Lines
Option Strict Statement
Visual Basic Defaults, Projects, Options Dialog Box
/out (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
Syntax
/out:filename
Arguments
TERM DEFINITION
filename Required. The name of the output file the compiler creates. If
the file name contains a space, enclose the name in quotation
marks (" ").
Remarks
Specify the full name and extension of the file to create. If you do not, the .exe file takes its name from the source-
code file containing the Sub Main procedure, and the .dll file takes its name from the first source-code file.
If you specify a file name without an .exe or .dll extension, the compiler automatically adds the extension for you,
depending on the value specified for the /target compiler option.
1. Have a project selected in Solution Explorer. On the Project menu, click Properties. For more information, see Introduction
to the Project Designer.
2. Click the Application tab.
3. Modify the value in the Assembly Name box.
Example
The following code compiles T2.vb and creates output file T2.exe .
See Also
Visual Basic Command-Line Compiler
/target (Visual Basic)
Sample Compilation Command Lines
/platform (Visual Basic)
7/29/2017 • 2 min to read • Edit Online
Specifies which platform version of common language runtime (CLR) can run the output file.
Syntax
/platform:{ x86 | x64 | Itanium | arm | anycpu | anycpu32bitpreferred }
Arguments
TERM DEFINITION
Remarks
Use the /platform option to specify the type of processor targeted by the output file.
In general, .NET Framework assemblies written in Visual Basic will run the same regardless of the platform.
However, there are some cases that behave differently on different platforms. These common cases are:
Structures that contain members that change size depending on the platform, such as any pointer type.
Pointer arithmetic that includes constant sizes.
Incorrect platform invoke or COM declarations that use Integer for handles instead of IntPtr.
Casting IntPtr to Integer .
Using platform invoke or COM interop with components that do not exist on all platforms.
The /platform option will mitigate some issues if you know you have made assumptions about the architecture
your code will run on. Specifically:
If you decide to target a 64-bit platform, and the application is run on a 32-bit machine, the error message
comes much earlier and is more targeted at the problem than the error that occurs without using this
switch.
If you set the x86 flag on the option and the application is subsequently run on a 64-bit machine, the
application will run in the WOW subsystem instead of running natively.
On a 64-bit Windows operating system:
Assemblies compiled with /platform:x86 will execute on the 32-bit CLR running under WOW64.
Executables compiled with the /platform:anycpu will execute on the 64-bit CLR.
A DLL compiled with the /platform:anycpu will execute on the same CLR as the process into which it
loaded.
Executables that are compiled with /platform:anycpu32bitpreferred will execute on the 32-bit CLR.
For more information about how to develop an application to run on a 64-bit version of Windows, see 64-bit
Applications.
To set /platform in the Visual Studio IDE
1. In Solution Explorer, choose the project, open the Project menu, and then click Properties.
For more information, see NIB: Managing Project Properties with the Project Designer.
2. On the Compile tab, select or clear the Prefer 32-bit check box, or, in the Target CPU list, choose a value.
For more information, see Compile Page, Project Designer (Visual Basic).
Example
The following example illustrates how to use the /platform compiler option.
See Also
/target (Visual Basic)
Visual Basic Command-Line Compiler
Sample Compilation Command Lines
/quiet
7/29/2017 • 1 min to read • Edit Online
Prevents the compiler from displaying code for syntax-related errors and warnings.
Syntax
/quiet
Remarks
By default, /quiet is not in effect. When the compiler reports a syntax-related error or warning, it also outputs the
line from source code. For applications that parse compiler output, it may be more convenient for the compiler to
output only the text of the diagnostic.
In the following example, Module1 outputs an error that includes source code when compiled without /quiet .
Module Module1
Sub Main()
x()
End Sub
End Module
Output:
E:\test\t2.vb(3) : error BC30451: Name 'x' is not declared.
NOTE
The /quiet option is not available from within the Visual Studio development environment; it is available only when
compiling from the command line.
Example
The following code compiles T2.vb and does not display code for syntax-related compiler diagnostics:
See Also
Visual Basic Command-Line Compiler
Sample Compilation Command Lines
/recurse
7/29/2017 • 1 min to read • Edit Online
Compiles source-code files in all child directories of either the specified directory or the project directory.
Syntax
/recurse:[dir\]file
Arguments
dir
Optional. The directory in which you want the search to begin. If not specified, the search begins in the project
directory.
file
Required. The file(s) to search for. Wildcard characters are allowed.
Remarks
You can use wildcards in a file name to compile all matching files in the project directory without using /recurse . If
no output file name is specified, the compiler bases the output file name on the first input file processed. This is
generally the first file in the list of files compiled when viewed alphabetically. For this reason, it is best to specify an
output file using the /out option.
NOTE
The /recurse option is not available from within the Visual Studio development environment; it is available only when
compiling from the command line.
Example
The following code compiles all Visual Basic files in the current directory.
vbc *.vb
The following code compiles all Visual Basic files in the Test\ABC directory and any directories below it, and then
generates Test.ABC.dll .
See Also
Visual Basic Command-Line Compiler
/out (Visual Basic)
Sample Compilation Command Lines
/reference (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
Causes the compiler to make type information in the specified assemblies available to the project you are
currently compiling.
Syntax
/reference:fileList
' -or-
/r:fileList
Arguments
TERM DEFINITION
Remarks
The file(s) you import must contain assembly metadata. Only public types are visible outside the assembly. The
/addmodule option imports metadata from a module.
If you reference an assembly (Assembly A) which itself references another assembly (Assembly B), you need to
reference Assembly B if:
A type from Assembly A inherits from a type or implements an interface from Assembly B.
A field, property, event, or method that has a return type or parameter type from Assembly B is invoked.
Use /libpath to specify the directory in which one or more of your assembly references is located.
For the compiler to recognize a type in an assembly (not a module), it must be forced to resolve the type. One
example of how you can do this is to define an instance of the type. Other ways are available to resolve type
names in an assembly for the compiler. For example, if you inherit from a type in an assembly, the type name
then becomes known to the compiler.
The Vbc.rsp response file, which references commonly used .NET Framework assemblies, is used by default. Use
/noconfig if you do not want the compiler to use Vbc.rsp.
Example
The following code compiles source file Input.vb and reference assemblies from Metad1.dll and Metad2.dll
to produce Out.exe .
Syntax
/removeintchecks[+ | -]
Arguments
TERM DEFINITION
1. Have a project selected in Solution Explorer. On the Project menu, click Properties. For more information, see Introduction
to the Project Designer.
2. Click the Compile tab.
3. Click the Advanced button.
4. Modify the value of the Remove integer overflow checks box.
Example
The following code compiles Test.vb and turns off integer overflow-error checking.
See Also
Visual Basic Command-Line Compiler
Sample Compilation Command Lines
/resource (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
Syntax
/resource:filename[,identifier[,public|private]]
' -or-
/res:filename[,identifier[,public|private]]
Arguments
TERM DEFINITION
identifier Optional. The logical name for the resource; the name used to
load it. The default is the name of the file. Optionally, you can
specify whether the resource is public or private in the
assembly manifest, as with the following:
/res:``filename.res , myname.res , public
Remarks
Use /linkresource to link a resource to an assembly without placing the resource file in the output file.
If filename is a .NET Framework resource file created, for example, by the Resgen.exe (Resource File Generator) or
in the development environment, it can be accessed with members in the System.Resources namespace (see
ResourceManager for more information). To access all other resources at run time, use one of the following
methods: GetManifestResourceInfo, GetManifestResourceNames, or GetManifestResourceStream.
The short form of /resource is /res .
For information about how to set /resource in the Visual Studio IDE, see Managing Application Resources (.NET).
Example
The following code compiles In.vb and attaches resource file Rf.resource .
See Also
Visual Basic Command-Line Compiler
/win32resource
/linkresource (Visual Basic)
/target (Visual Basic)
Sample Compilation Command Lines
/rootnamespace
7/29/2017 • 1 min to read • Edit Online
Syntax
/rootnamespace:namespace
Arguments
TERM DEFINITION
Remarks
If you use the Visual Studio executable file (Devenv.exe) to compile a project created in the Visual Studio integrated
development environment, use /rootnamespace to specify the value of the RootNamespace property. See Devenv
Command Line Switches for more information.
Use the common language runtime MSIL Disassembler ( Ildasm.exe ) to view the namespace names in your output
file.
1. Have a project selected in Solution Explorer. On the Project menu, click Properties. For more information, see Introduction
to the Project Designer.
2. Click the Application tab.
3. Modify the value in the Root Namespace box.
Example
The following code compiles In.vb and encloses all type declarations in the namespace mynamespace .
See Also
Visual Basic Command-Line Compiler
Ildasm.exe (IL Disassembler)
Sample Compilation Command Lines
/sdkpath
7/29/2017 • 1 min to read • Edit Online
Syntax
/sdkpath:path
Arguments
path
The directory containing the versions of Mscorlib.dll and Microsoft.VisualBasic.dll to use for compilation. This path
is not verified until it is loaded. Enclose the directory name in quotation marks (" ") if it contains a space.
Remarks
This option tells the Visual Basic compiler to load the Mscorlib.dll and Microsoft.VisualBasic.dll files from a non-
default location. The /sdkpath option was designed to be used with /netcf. The .NET Compact Framework uses
different versions of these support libraries to avoid the use of types and language features not found on the
devices.
NOTE
The /sdkpath option is not available from within the Visual Studio development environment; it is available only when
compiling from the command line. The /sdkpath option is set when a Visual Basic device project is loaded.
You can specify that the compiler should compile without a reference to the Visual Basic Runtime Library by using
the /vbruntime compiler option. For more information, see /vbruntime.
Example
The following code compiles Myfile.vb with the .NET Compact Framework, using the versions of Mscorlib.dll and
Microsoft.VisualBasic.dll found in the default installation directory of the .NET Compact Framework on the C drive.
Typically, you would use the most recent version of the .NET Compact Framework.
See Also
Visual Basic Command-Line Compiler
Sample Compilation Command Lines
/netcf
/vbruntime
/target (Visual Basic)
7/29/2017 • 4 min to read • Edit Online
Syntax
/target:{exe | library | module | winexe | appcontainerexe | winmdobj}
Remarks
The following table summarizes the effect of the /target option.
OPTION BEHAVIOR
Unless you specify /target:module , /target causes a .NET Framework assembly manifest to be added to an
output file.
Each instance of Vbc.exe produces, at most, one output file. If you specify a compiler option such as /out or
/target more than one time, the last one the compiler processes is put into effect. Information about all files
in a compilation is added to the manifest. All output files except those created with /target:module contain
assembly metadata in the manifest. Use Ildasm.exe (IL Disassembler) to view the metadata in an output file.
The short form of /target is /t .
To set /target in the Visual Studio IDE
1. Have a project selected in Solution Explorer. On the Project menu, click Properties. For more
information, see Introduction to the Project Designer.
2. Click the Application tab.
3. Modify the value in the Application Type box.
Example
The following code compiles in.vb , creating in.dll :
See Also
Visual Basic Command-Line Compiler
/main
/out (Visual Basic)
/reference (Visual Basic)
/addmodule
/moduleassemblyname
Assemblies and the Global Assembly Cache
Sample Compilation Command Lines
/subsystemversion (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
Specifies the minimum version of the subsystem on which the generated executable file can run, thereby
determining the versions of Windows on which the executable file can run. Most commonly, this option ensures
that the executable file can leverage particular security features that aren’t available with older versions of
Windows.
NOTE
To specify the subsystem itself, use the /target compiler option.
Syntax
/subsystemversion:major.minor
Parameters
major.minor
The minimum required version of the subsystem, as expressed in a dot notation for major and minor versions. For
example, you can specify that an application can't run on an operating system that's older than Windows 7 if you
set the value of this option to 6.01, as the table later in this topic describes. You must specify the values for major
and minor as integers.
Leading zeroes in the minor version don't change the version, but trailing zeroes do. For example, 6.1 and 6.01
refer to the same version, but 6.10 refers to a different version. We recommend expressing the minor version as
two digits to avoid confusion.
Remarks
The following table lists common subsystem versions of Windows.
Windows XP 5.01
Windows 7 6.01
Windows 8 6.02
Default values
The default value of the /subsystemversion compiler option depends on the conditions in the following list:
The default value is 6.02 if any compiler option in the following list is set:
/target:appcontainerexe
/target:winmdobj
/platform:arm
The default value is 6.00 if you're using MSBuild, you're targeting .NET Framework 4.5, and you haven't set
any of the compiler options that were specified earlier in this list.
The default value is 4.00 if none of the previous conditions is true.
See Also
Visual Basic Command-Line Compiler
MSBuild Properties
/utf8output (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
Syntax
/utf8output[+ | -]
Arguments
+ | -
Optional. The default for this option is /utf8output- , which means compiler output does not use UTF-8 encoding.
Specifying /utf8output is the same as specifying /utf8output+ .
Remarks
In some international configurations, compiler output cannot be displayed correctly in the console. In such
situations, use /utf8output and redirect compiler output to a file.
NOTE
The /utf8output option is not available from within the Visual Studio development environment; it is available only when
compiling from the command line.
Example
The following code compiles In.vb and directs the compiler to display output using UTF-8 encoding.
See Also
Visual Basic Command-Line Compiler
Sample Compilation Command Lines
/vbruntime
7/29/2017 • 2 min to read • Edit Online
Specifies that the compiler should compile without a reference to the Visual Basic Runtime Library, or with a
reference to a specific runtime library.
Syntax
/vbruntime:{ - | + | * | path }
Arguments
-
Compile without a reference to the Visual Basic Runtime Library.
+
Compile with a reference to the default Visual Basic Runtime Library.
*
Compile without a reference to the Visual Basic Runtime Library, and embed core functionality from the Visual
Basic Runtime Library into the assembly.
path
Compile with a reference to the specified library (DLL).
Remarks
The /vbruntime compiler option enables you to specify that the compiler should compile without a reference to
the Visual Basic Runtime Library. If you compile without a reference to the Visual Basic Runtime Library, errors or
warnings are logged on code or language constructs that generate a call to a Visual Basic runtime helper. (A Visual
Basic runtime helper is a function defined in Microsoft.VisualBasic.dll that is called at runtime to execute a specific
language semantic.)
The /vbruntime+ option produces the same behavior that occurs if no /vbruntime switch is specified. You can use
the /vbruntime+ option to override previous /vbruntime switches.
Most objects of the My type are unavailable when you use the /vbruntime- or vbruntime:``path options.
If you compile using the /vbruntime* option and your code references a member from the Visual Basic Runtime
Library that is not embedded with the core functionality, the compiler returns an error that indicates that the
member is not available.
Example
The following example shows how to use the /vbruntime option to compile with a reference to a custom library.
vbc /vbruntime:C:\VBLibraries\CustomVBLibrary.dll
See Also
Visual Basic Core – New compilation mode in Visual Studio 2010 SP1
Visual Basic Command-Line Compiler
Sample Compilation Command Lines
/sdkpath
/verbose
7/29/2017 • 1 min to read • Edit Online
Syntax
/verbose[+ | -]
Arguments
+ | -
Optional. Specifying /verbose is the same as specifying /verbose+ , which causes the compiler to emit verbose
messages. The default for this option is /verbose- .
Remarks
The /verbose option displays information about the total number of errors issued by the compiler, reports which
assemblies are being loaded by a module, and displays which files are currently being compiled.
NOTE
The /verbose option is not available from within the Visual Studio development environment; it is available only when
compiling from the command line.
Example
The following code compiles In.vb and directs the compiler to display verbose status information.
See Also
Visual Basic Command-Line Compiler
Sample Compilation Command Lines
/warnaserror (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
Syntax
/warnaserror[+ | -][:numberList]
Arguments
TERM DEFINITION
Remarks
The /warnaserror option treats all warnings as errors. Any messages that would ordinarily be reported as
warnings are instead reported as errors. The compiler reports subsequent occurrences of the same warning as
warnings.
By default, /warnaserror- is in effect, which causes the warnings to be informational only. The /warnaserror
option, which is the same as /warnaserror+ , causes warnings to be treated as errors.
If you want only a few specific warnings to be treated as errors, you may specify a comma-separated list of
warning numbers to treat as errors.
NOTE
The /warnaserror option does not control how warnings are displayed. Use the /nowarn option to disable warnings.
TO SET /WARNASERROR TO TREAT ALL WARNINGS AS ERRORS IN THE VISUAL STUDIO IDE
1. Have a project selected in Solution Explorer. On the Project menu, click Properties. For more information, see Introduction
to the Project Designer.
2. Click the Compile tab.
3. Make sure the Disable all warnings check box is unchecked.
4. Check the Treat all warnings as errors check box.
TO SET /WARNASERROR TO TREAT SPECIFIC WARNINGS AS ERRORS IN THE VISUAL STUDIO IDE
1. Have a project selected in Solution Explorer. On the Project menu, click Properties.
2. Click the Compile tab.
3. Make sure the Disable all warnings check box is unchecked.
4. Make sure the Treat all warnings as errors check box is unchecked.
5. Select Error from the Notification column adjacent to the warning that should be treated as an error.
Example
The following code compiles In.vb and directs the compiler to display an error for the first occurrence of every
warning it finds.
Example
The following code compiles T2.vb and treats only the warning for unused local variables (42024) as an error.
See Also
Visual Basic Command-Line Compiler
Sample Compilation Command Lines
Configuring Warnings in Visual Basic
/win32icon
7/29/2017 • 1 min to read • Edit Online
Inserts an .ico file in the output file. This .ico file represents the output file in File Explorer.
Syntax
/win32icon:filename
Arguments
TERM DEFINITION
filename The .ico file to add to your output file. Enclose the file name in
quotation marks (" ") if it contains a space.
Remarks
You can create an .ico file with the Microsoft Windows Resource Compiler (RC). The resource compiler is invoked
when you compile a Visual C++ program; an .ico file is created from the .rc file. The /win32icon and
/win32resource options are mutually exclusive.
See /linkresource (Visual Basic) to reference a .NET Framework resource file, or /resource (Visual Basic) to attach a
.NET Framework resource file. See /win32resource to import a .res file.
1. Have a project selected in Solution Explorer. On the Project menu, click Properties. For more information, see Introduction
to the Project Designer.
2. Click the Application tab.
3. Modify the value in the Icon box.
Example
The following code compiles In.vb and attaches an .ico file, Rf.ico .
See Also
Visual Basic Command-Line Compiler
Sample Compilation Command Lines
/win32manifest (Visual Basic)
7/29/2017 • 2 min to read • Edit Online
Identifies a user-defined Win32 application manifest file to be embedded into a project's portable executable (PE)
file.
Syntax
/win32manifest: fileName
Arguments
TERM DEFINITION
Remarks
By default, the Visual Basic compiler embeds an application manifest that specifies a requested execution level of
asInvoker. It creates the manifest in the same folder in which the executable file is built, typically the bin\Debug or
bin\Release folder when you use Visual Studio. If you want to supply a custom manifest, for example to specify a
requested execution level of highestAvailable or requireAdministrator, use this option to specify the name of the
file.
NOTE
This option and the /win32resource option are mutually exclusive. If you try to use both options in the same command line,
you will get a build error.
An application that has no application manifest that specifies a requested execution level will be subject to
file/registry virtualization under the User Account Control feature in Windows Vista. For more information about
virtualization, see ClickOnce Deployment on Windows Vista.
Your application will be subject to virtualization if either of the following conditions is true:
1. You use the /nowin32manifest option and you do not provide a manifest in a later build step or as part of a
Windows Resource (.res) file by using the /win32resource option.
2. You provide a custom manifest that does not specify a requested execution level.
Visual Studio creates a default .manifest file and stores it in the debug and release directories alongside the
executable file. You can view or edit the default app.manifest file by clicking View UAC Settings on the
Application tab in the Project Designer. For more information, see Application Page, Project Designer (Visual
Basic).
You can provide the application manifest as a custom post-build step or as part of a Win32 resource file by using
the /nowin32manifest option. Use that same option if you want your application to be subject to file or registry
virtualization on Windows Vista. This will prevent the compiler from creating and embedding a default manifest in
the PE file.
Example
The following example shows the default manifest that the Visual Basic compiler inserts into a PE.
NOTE
The compiler inserts a standard application name MyApplication.app into the manifest XML. This is a workaround to enable
applications to run on Windows Server 2003 Service Pack 3.
See Also
Visual Basic Command-Line Compiler
/nowin32manifest (Visual Basic)
/win32resource
7/29/2017 • 1 min to read • Edit Online
Syntax
/win32resource:filename
Arguments
filename
The name of the resource file to add to your output file. Enclose the file name in quotation marks (" ") if it contains
a space.
Remarks
You can create a Win32 resource file with the Microsoft Windows Resource Compiler (RC).
A Win32 resource can contain version or bitmap (icon) information that helps identify your application in File
Explorer. If you do not specify /win32resource , the compiler generates version information based on the
assembly version. The /win32resource and /win32icon options are mutually exclusive.
See /linkresource (Visual Basic) to reference a .NET Framework resource file, or /resource (Visual Basic) to attach a
.NET Framework resource file.
NOTE
The /win32resource option is not available from within the Visual Studio development environment; it is available only
when compiling from the command line.
Example
The following code compiles In.vb and attaches a Win32 resource file, Rf.res :
See Also
Visual Basic Command-Line Compiler
Sample Compilation Command Lines
Visual Basic Compiler Options Listed by Category
7/29/2017 • 3 min to read • Edit Online
The Visual Basic command-line compiler is provided as an alternative to compiling programs from within the
Visual Studio integrated development environment (IDE). The following is a list of the Visual Basic command-line
compiler options sorted by functional category.
Compiler Output
OPTION PURPOSE
Optimization
OPTION PURPOSE
Output Files
OPTION PURPOSE
.NET Assemblies
OPTION PURPOSE
OPTION PURPOSE
/addmodule Causes the compiler to make all type information from the
specified file(s) available to the project you are currently
compiling.
/analyzer Run the analyzers from this assembly (Short form: /a)
Debugging/Error Checking
OPTION PURPOSE
Help
OPTION PURPOSE
Language
OPTION PURPOSE
Preprocessor
OPTION PURPOSE
Resources
OPTION PURPOSE
Miscellaneous
OPTION PURPOSE
/codepage Specifies the code page to use for all source code files in the
compilation.
/errorreport Specifies how the Visual Basic compiler should report internal
compiler errors.
/platform Specifies the processor platform the compiler targets for the
output file.
/checksumalgorithm:<alg> Specify the algorithm for calculating the source file checksum
stored in PDB. Supported values are: SHA1 (default) or
SHA256.
See Also
Visual Basic Compiler Options Listed Alphabetically
Introduction to the Project Designer
C# Compiler Options Listed Alphabetically
C# Compiler Options Listed by Category
.NET Framework Reference Information (Visual Basic)
7/29/2017 • 1 min to read • Edit Online
This topic provides links to information about how to work with the .NET Framework class library.
Related Sections
Getting Started
Provides a comprehensive overview of the .NET Framework and links to additional resources.
Class Library Overview
Introduces the classes, interfaces, and value types that help expedite and optimize the development process and
provide access to system functionality.
Development Guide
Provides a guide to all key technology areas and tasks for application development, including creating, configuring,
debugging, securing, and deploying your application. This topic also provides information about dynamic
programming, interoperability, extensibility, memory management, and threading.
Tools
Describes the tools that you can use to develop, configure, and deploy applications by using .NET Framework
technologies.
.NET Framework Samples
Provides links to sample applications that demonstrate .NET Framework technologies.
.NET Framework Class Library
Provides syntax, code examples, and related information for each class in the .NET Framework namespaces.
Visual Basic Language Specification
8/3/2017 • 1 min to read • Edit Online
The Visual Basic Language Specification is the authoritative source for answers to all questions about Visual Basic
grammar and syntax. It contains detailed information about the language, including many points not covered in
the Visual Basic reference documentation.
The specification is available on the Microsoft Download Center.
This site contains the VB 11 specification. It's built from the Markdown files contained in the dotnet/vblang GitHub
repository.
Issues on the specification should be created in the dotnet/vblang repository. Or, if you're interested in fixing any
errors you find, you may submit a Pull Request to the same repository.
See Also
Visual Basic Language Reference
NEXT
Visual Basic Sample Applications
7/29/2017 • 1 min to read • Edit Online
You can use Visual Studio to download and install samples of full, packaged Visual Basic applications from the
MSDN Code Gallery
You can download each sample individually, or you can download a Sample Pack, which contains related samples
that share a technology or topic. You’ll receive a notification when source code changes are published for any
sample that you download.
See Also
Visual Studio Samples
Visual Basic Programming Guide
Visual Basic
Visual Basic Language Walkthroughs
7/29/2017 • 2 min to read • Edit Online
Walkthroughs give step-by-step instructions for common scenarios, which makes them a good place to start
learning about the product or a particular feature area.
Writing an Async Program
Shows how to create an asynchronous solution by using Async and Await.
Declaring and Raising Events
Illustrates how events are declared and raised in Visual Basic.
Handling Events
Shows how to handle events using either the standard WithEvents keyword or the new AddHandler /
RemoveHandler keywords.
The .NET documentation contains a set of samples and tutorials that teach you about .NET. This topic describes how
to find, view, and download .NET Core, ASP.NET Core, and C# samples and tutorials. Find resources to learn the F#
programming language on the F# Foundation's site. If you're interested in exploring C# using an online code editor,
try these interactive tutorials. For instructions on how to view and download sample code, see the Viewing and
downloading samples section.
.NET Core
Samples
Unit Testing in .NET Core using dotnet test
This guide shows you how to create an ASP.NET Core web app and associated unit tests. It starts by creating a
simple web service app and then adds tests. It continues with creating more tests to guide implementing new
features. The completed sample is available in the dotnet/docs repository on GitHub.
Tutorials
Writing .NET Core console apps using the CLI tools: A step-by-step guide
This guide shows you how to use the .NET Core CLI tooling to build cross-platform console apps. It starts with a
basic console app and eventually spans multiple projects, including testing. You add features step-by-step, building
your knowledge as you go. The completed sample is available in the dotnet/docs repository on GitHub.
Writing Libraries with Cross Platform Tools
This sample covers how to write libraries for .NET using cross-platform CLI tools. These tools provide an efficient
and low-level experience that works across any supported operating system. The completed sample is available in
the dotnet/docs repository on GitHub.
ASP.NET Core
See the ASP.NET Core tutorials. Many articles in the ASP.NET Core documentation have links to samples written for
them.
C# language
Samples
Iterators
This sample demonstrates the syntax and features for creating and consuming C# iterators. The completed sample
is available in the dotnet/docs repository on GitHub.
Indexers
This sample demonstrates the syntax and features for C# indexers. The completed sample is available in the
dotnet/docs repository on GitHub.
Delegates and Events
This sample demonstrates the syntax and features for C# delegates and events. The completed sample is available
in the dotnet/docs repository on GitHub. A second sample focused on events is also in the same repository.
Expression Trees
This sample demonstrates many of the problems that can be solved by using Expression Trees. The completed
sample is available in the dotnet/docs repository on GitHub.
LINQ Samples
This series of samples demonstrate many of the features of Language Integrated Query (LINQ). The completed
sample is available in the dotnet/docs repository on GitHub.
Tutorials
Console Application
This tutorial demonstrates Console I/O, the structure of a console app, and the basics of the task-based
asynchronous programming model. The completed sample is available in the dotnet/docs repository on GitHub.
REST Client
This tutorial demonstrates web communications, JSON serialization, and object-oriented features of the C#
language. The completed sample is available in the dotnet/docs repository on GitHub.
Working with LINQ
This tutorial demonstrates many of the features of LINQ and the language elements that support it. The completed
sample is available in the dotnet/docs repository on GitHub.
Microservices hosted in Docker
This tutorial demonstrates building an ASP.NET Core microservice and hosting it in Docker. The completed sample
is available in the dotnet/docs repository on GitHub.
Getting started with .NET Core on macOS using Visual Studio for Mac
This tutorial shows you how to build a simple .NET Core console app using Visual Studio for Mac.
Building a complete .NET Core solution on macOS using Visual Studio for Mac
This tutorial shows you how to build a complete .NET Core solution that includes a reusable library and unit testing.
Deploying to containers
Running ASP.NET MVC Applications in Windows Docker Containers
This tutorial demonstrates how to deploy an existing ASP.NET MVC app in a Windows Docker Container. The
completed sample is available in the dotnet/docs repository on GitHub.
Running .NET Framework Console Applications in Windows Containers
This tutorial demonstrates how to deploy an existing console app in a Windows container. The completed sample is
available in the dotnet/docs repository on GitHub.