diff --git a/.openpublishing.redirection.json b/.openpublishing.redirection.json
index 80452aadc40a8..7360507cfa50a 100644
--- a/.openpublishing.redirection.json
+++ b/.openpublishing.redirection.json
@@ -1760,14 +1760,46 @@
"source_path": "docs/csharp/structs.md",
"redirect_url": "/dotnet/csharp/language-reference/builtin-types/struct"
},
+ {
+ "source_path": "docs/csharp/tour-of-csharp/arrays.md",
+ "redirect_url": "/dotnet/csharp/tour-of-csharp/features#arrays-collections-and-LINQ"
+ },
+ {
+ "source_path": "docs/csharp/tour-of-csharp/attributes.md",
+ "redirect_url": "/dotnet/csharp/tour-of-csharp/features#attributes"
+ },
+ {
+ "source_path": "docs/csharp/tour-of-csharp/delegates.md",
+ "redirect_url": "/dotnet/csharp/tour-of-csharp/features#delegates-and-lambda-expressions"
+ },
{
"source_path": "docs/csharp/tour-of-csharp/enums.md",
"redirect_url": "/dotnet/csharp/language-reference/builtin-types/enum"
},
+ {
+ "source_path": "docs/csharp/tour-of-csharp/expressions.md",
+ "redirect_url": "/dotnet/csharp/tour-of-csharp/program-building-blocks#expressions"
+ },
+ {
+ "source_path": "docs/csharp/tour-of-csharp/interfaces.md",
+ "redirect_url": "/dotnet/csharp/tour-of-csharp/types#interfaces"
+ },
+ {
+ "source_path": "docs/csharp/tour-of-csharp/program-structure.md",
+ "redirect_url": "/dotnet/csharp/tour-of-csharp/#program-structure"
+ },
+ {
+ "source_path": "docs/csharp/tour-of-csharp/statements.md",
+ "redirect_url": "/dotnet/csharp/tour-of-csharp/program-building-blocks#statements"
+ },
{
"source_path": "docs/csharp/tour-of-csharp/structs.md",
"redirect_url": "/dotnet/csharp/language-reference/builtin-types/struct"
},
+ {
+ "source_path": "docs/csharp/tour-of-csharp/types-and-variables.md",
+ "redirect_url": "/dotnet/csharp/tour-of-csharp/types"
+ },
{
"source_path": "docs/csharp/tuples.md",
"redirect_url": "/dotnet/csharp/language-reference/builtin-types/value-tuples"
diff --git a/docs/csharp/methods.md b/docs/csharp/methods.md
index 6606cf24b03dd..3a6fe4d8385fa 100644
--- a/docs/csharp/methods.md
+++ b/docs/csharp/methods.md
@@ -76,7 +76,7 @@ Types can override inherited members by using the `override` keyword and providi
## Passing parameters
-Types in C# are either *value types* or *reference types*. For a list of built-in value types, see [Types and variables](./tour-of-csharp/types-and-variables.md). By default, both value types and reference types are passed to a method by value.
+Types in C# are either *value types* or *reference types*. For a list of built-in value types, see [Types](./tour-of-csharp/types.md). By default, both value types and reference types are passed to a method by value.
diff --git a/docs/csharp/toc.yml b/docs/csharp/toc.yml
index 6b0f1ec7a3165..efd41b0966a17 100644
--- a/docs/csharp/toc.yml
+++ b/docs/csharp/toc.yml
@@ -72,24 +72,12 @@
items:
- name: Introduction
href: tour-of-csharp/index.md
- - name: Program Structure
- href: tour-of-csharp/program-structure.md
- - name: Types and Variables
- href: tour-of-csharp/types-and-variables.md
- - name: Expressions
- href: tour-of-csharp/expressions.md
- - name: Statements
- href: tour-of-csharp/statements.md
- - name: Classes and objects
- href: tour-of-csharp/classes-and-objects.md
- - name: Arrays
- href: tour-of-csharp/arrays.md
- - name: Interfaces
- href: tour-of-csharp/interfaces.md
- - name: Delegates
- href: tour-of-csharp/delegates.md
- - name: Attributes
- href: tour-of-csharp/attributes.md
+ - name: Types
+ href: tour-of-csharp/types.md
+ - name: Program building blocks
+ href: tour-of-csharp/program-building-blocks.md
+ - name: Major language areas
+ href: tour-of-csharp/features.md
- name: What's new in C#
items:
- name: C# 8.0
diff --git a/docs/csharp/tour-of-csharp/arrays.md b/docs/csharp/tour-of-csharp/arrays.md
deleted file mode 100644
index cc031bb401068..0000000000000
--- a/docs/csharp/tour-of-csharp/arrays.md
+++ /dev/null
@@ -1,43 +0,0 @@
----
-title: C# Arrays - A tour of the C# language
-description: Arrays are the most basic collection type in the C# language
-ms.date: 02/27/2020
-ms.assetid: a440704c-9e88-4c75-97dd-bfe30ca0fb97
----
-
-# Arrays
-
-An ***array*** is a data structure that contains a number of variables that are accessed through computed indices. The variables contained in an array, also called the ***elements*** of the array, are all of the same type, and this type is called the ***element type*** of the array.
-
-Array types are reference types, and the declaration of an array variable simply sets aside space for a reference to an array instance. Actual array instances are created dynamically at runtime using the new operator. The new operation specifies the ***length*** of the new array instance, which is then fixed for the lifetime of the instance. The indices of the elements of an array range from `0` to `Length - 1`. The `new` operator automatically initializes the elements of an array to their default value, which, for example, is zero for all numeric types and `null` for all reference types.
-
-The following example creates an array of `int` elements, initializes the array, and prints out the contents of the array.
-
-[!code-csharp[ArraySample](../../../samples/snippets/csharp/tour/arrays/Program.cs#L3-L18)]
-
-This example creates and operates on a ***single-dimensional array***. C# also supports ***multi-dimensional arrays***. The number of dimensions of an array type, also known as the ***rank*** of the array type, is one plus the number of commas written between the square brackets of the array type. The following example allocates a single-dimensional, a two-dimensional, and a three-dimensional array, respectively.
-
-[!code-csharp[ArrayRank](../../../samples/snippets/csharp/tour/arrays/Program.cs#L24-L26)]
-
-The `a1` array contains 10 elements, the `a2` array contains 50 (10 × 5) elements, and the `a3` array contains 100 (10 × 5 × 2) elements.
-The element type of an array can be any type, including an array type. An array with elements of an array type is sometimes called a ***jagged array*** because the lengths of the element arrays don't all have to be the same. The following example allocates an array of arrays of `int`:
-
-[!code-csharp[ArrayAllocation](../../../samples/snippets/csharp/tour/arrays/Program.cs#L31-L34)]
-
-The first line creates an array with three elements, each of type `int[]` and each with an initial value of `null`. The subsequent lines then initialize the three elements with references to individual array instances of varying lengths.
-
-The new operator permits the initial values of the array elements to be specified using an ***array initializer***, which is a list of expressions written between the delimiters `{` and `}`. The following example allocates and initializes an `int[]` with three elements.
-
-[!code-csharp[ArrayInitialization](../../../samples/snippets/csharp/tour/arrays/Program.cs#L39-L39)]
-
-The length of the array is inferred from the number of expressions between { and }. Local variable and field declarations can be shortened further such that the array type does not have to be restated.
-
-[!code-csharp[ArrayInitialization](../../../samples/snippets/csharp/tour/arrays/Program.cs#L44-L44)]
-
-Both of the previous examples are equivalent to the following code:
-
-[!code-csharp[ArrayAssignment](../../../samples/snippets/csharp/tour/arrays/Program.cs#L49-L53)]
-
->[!div class="step-by-step"]
->[Previous](classes-and-objects.md)
->[Next](interfaces.md)
diff --git a/docs/csharp/tour-of-csharp/attributes.md b/docs/csharp/tour-of-csharp/attributes.md
deleted file mode 100644
index 591e93528349c..0000000000000
--- a/docs/csharp/tour-of-csharp/attributes.md
+++ /dev/null
@@ -1,29 +0,0 @@
----
-title: C# Attributes - A tour of the C# language
-description: Learn about declarative programming using attributes in C#
-ms.date: 02/27/2020
-ms.assetid: 753bcfe2-7ddd-4487-9513-ba70937fc8e9
----
-
-# Attributes
-
-Types, members, and other entities in a C# program support modifiers that control certain aspects of their behavior. For example, the accessibility of a method is controlled using the `public`, `protected`, `internal`, and `private` modifiers. C# generalizes this capability such that user-defined types of declarative information can be attached to program entities and retrieved at run-time. Programs specify this additional declarative information by defining and using ***attributes***.
-
-The following example declares a `HelpAttribute` attribute that can be placed on program entities to provide links to their associated documentation.
-
-[!code-csharp[AttributeDefined](../../../samples/snippets/csharp/tour/attributes/Program.cs#L3-L20)]
-
-All attribute classes derive from the base class provided by the standard library. Attributes can be applied by giving their name, along with any arguments, inside square brackets just before the associated declaration. If an attribute’s name ends in `Attribute`, that part of the name can be omitted when the attribute is referenced. For example, the `HelpAttribute` can be used as follows.
-
-[!code-csharp[AttributeApplied](../../../samples/snippets/csharp/tour/attributes/Program.cs#L22-L28)]
-
-This example attaches a `HelpAttribute` to the `Widget` class. It adds another `HelpAttribute` to the `Display` method in the class. The public constructors of an attribute class control the information that must be provided when the attribute is attached to a program entity. Additional information can be provided by referencing public read-write properties of the attribute class (such as the reference to the `Topic` property previously).
-
-The metadata defined by attributes can be read and manipulated at runtime using reflection. When a particular attribute is requested using this technique, the constructor for the attribute class is invoked with the information provided in the program source, and the resulting attribute instance is returned. If additional information was provided through properties, those properties are set to the given values before the attribute instance is returned.
-
-The following code sample demonstrates how to get the `HelpAttribute` instances associated to the `Widget` class and its `Display` method.
-
-[!code-csharp[AttributeRead](../../../samples/snippets/csharp/tour/attributes/Program.cs#ReadAttributes)]
-
->[!div class="step-by-step"]
->[Previous](delegates.md)
diff --git a/docs/csharp/tour-of-csharp/classes-and-objects.md b/docs/csharp/tour-of-csharp/classes-and-objects.md
deleted file mode 100644
index 072b3fdbd0699..0000000000000
--- a/docs/csharp/tour-of-csharp/classes-and-objects.md
+++ /dev/null
@@ -1,296 +0,0 @@
----
-title: Classes and Objects in C# - A tour of the C# Language
-description: New to C#? Read this overview of classes, objects, and inheritance
-ms.date: 02/27/2020
-ms.assetid: 63a89bde-0f05-4bc4-b0cd-4f693854f0cd
----
-
-# Classes and objects
-
-*Classes* are the most fundamental of C#’s types. A class is a data structure that combines state (fields) and actions (methods and other function members) in a single unit. A class provides a definition for dynamically created *instances* of the class, also known as *objects*. Classes support *inheritance* and *polymorphism*, mechanisms whereby *derived classes* can extend and specialize *base classes*.
-
-New classes are created using class declarations. A class declaration starts with a header that specifies the attributes and modifiers of the class, the name of the class, the base class (if given), and the interfaces implemented by the class. The header is followed by the class body, which consists of a list of member declarations written between the delimiters `{` and `}`.
-
-The following code shows a declaration of a simple class named `Point`:
-
-[!code-csharp[PointClass](~/samples/snippets/csharp/tour/classes-and-objects/Point.cs#L3-L11)]
-
-Instances of classes are created using the `new` operator, which allocates memory for a new instance, invokes a constructor to initialize the instance, and returns a reference to the instance. The following statements create two Point objects and store references to those objects in two variables:
-
-[!code-csharp[PointExample](~/samples/snippets/csharp/tour/classes-and-objects/Program.cs#L9-L10)]
-
-The memory occupied by an object is automatically reclaimed when the object is no longer reachable. It's neither necessary nor possible to explicitly deallocate objects in C#.
-
-## Members
-
-The members of a class are either static members or instance members. Static members belong to classes, and instance members belong to objects (instances of classes).
-
-The following list provides an overview of the kinds of members a class can contain.
-
-- Constants
- - Constant values associated with the class
-- Fields
- - Variables of the class
-- Methods
- - Computations and actions that can be performed by the class
-- Properties
- - Actions associated with reading and writing named properties of the class
-- Indexers
- - Actions associated with indexing instances of the class like an array
-- Events
- - Notifications that can be generated by the class
-- Operators
- - Conversions and expression operators supported by the class
-- Constructors
- - Actions required to initialize instances of the class or the class itself
-- Finalizers
- - Actions to perform before instances of the class are permanently discarded
-- Types
- - Nested types declared by the class
-
-## Accessibility
-
-Each member of a class has an associated accessibility, which controls the regions of program text that can access the member. There are six possible forms of accessibility. The access modifiers are summarized below.
-
-- `public`
- - Access isn't limited.
-- `protected`
- - Access is limited to this class or classes derived from this class.
-- `internal`
- - Access is limited to the current assembly (.exe, .dll, and so on.).
-- `protected internal`
- - Access is limited to the containing class, classes derived from the containing class, or classes within the same assembly.
-- `private`
- - Access is limited to this class.
-- `private protected`
- - Access is limited to the containing class or classes derived from the containing type within the same assembly.
-
-## Type parameters
-
-A class definition may specify a set of type parameters by following the class name with angle brackets enclosing a list of type parameter names. The type parameters can then be used in the body of the class declarations to define the members of the class. In the following example, the type parameters of `Pair` are `TFirst` and `TSecond`:
-
-[!code-csharp[Pair](~/samples/snippets/csharp/tour/classes-and-objects/Pair.cs#L3-L7)]
-
-A class type that is declared to take type parameters is called a *generic class type*. Struct, interface, and delegate types can also be generic.
-When the generic class is used, type arguments must be provided for each of the type parameters:
-
-[!code-csharp[PairExample](~/samples/snippets/csharp/tour/classes-and-objects/Program.cs#L15-L17)]
-
-A generic type with type arguments provided, like `Pair` above, is called a *constructed type*.
-
-## Base classes
-
-A class declaration may specify a base class by following the class name and type parameters with a colon and the name of the base class. Omitting a base class specification is the same as deriving from type `object`. In the following example, the base class of `Point3D` is `Point`, and the base class of `Point` is `object`:
-
-[!code-csharp[Point3DClass](~/samples/snippets/csharp/tour/classes-and-objects/Point.cs#L3-L20)]
-
-A class inherits the members of its base class. Inheritance means that a class implicitly contains all members of its base class, except for the instance and static constructors, and the finalizers of the base class. A derived class can add new members to those members it inherits, but it can't remove the definition of an inherited member. In the previous example, `Point3D` inherits the `x` and `y` fields from `Point`, and every `Point3D` instance contains three fields, `x`, `y`, and `z`.
-
-An implicit conversion exists from a class type to any of its base class types. A variable of a class type can reference an instance of that class or an instance of any derived class. For example, given the previous class declarations, a variable of type `Point` can reference either a `Point` or a `Point3D`:
-
-[!code-csharp[Point3DExample](~/samples/snippets/csharp/tour/classes-and-objects/Program.cs#L22-L23)]
-
-## Fields
-
-A *field* is a variable that is associated with a class or with an instance of a class.
-
-A field declared with the static modifier defines a static field. A static field identifies exactly one storage location. No matter how many instances of a class are created, there's only ever one copy of a static field.
-
-A field declared without the static modifier defines an instance field. Every instance of a class contains a separate copy of all the instance fields of that class.
-
-In the following example, each instance of the `Color` class has a separate copy of the `r`, `g`, and `b` instance fields, but there's only one copy of the `Black`, `White`, `Red`, `Green`, and `Blue` static fields:
-
-[!code-csharp[ColorClass](~/samples/snippets/csharp/tour/classes-and-objects/Color.cs#L3-L17)]
-
-As shown in the previous example, *read-only fields* may be declared with a `readonly` modifier. Assignment to a `readonly` field can only occur as part of the field’s declaration or in a constructor in the same class.
-
-## Methods
-
-A *method* is a member that implements a computation or action that can be performed by an object or class. *Static methods* are accessed through the class. *Instance methods* are accessed through instances of the class.
-
-Methods may have a list of *parameters*, which represent values or variable references passed to the method, and a *return type*, which specifies the type of the value computed and returned by the method. A method’s return type is `void` if it doesn't return a value.
-
-Like types, methods may also have a set of type parameters, for which type arguments must be specified when the method is called. Unlike types, the type arguments can often be inferred from the arguments of a method call and need not be explicitly given.
-
-The *signature* of a method must be unique in the class in which the method is declared. The signature of a method consists of the name of the method, the number of type parameters and the number, modifiers, and types of its parameters. The signature of a method doesn't include the return type.
-
-### Parameters
-
-Parameters are used to pass values or variable references to methods. The parameters of a method get their actual values from the *arguments* that are specified when the method is invoked. There are four kinds of parameters: value parameters, reference parameters, output parameters, and parameter arrays.
-
-A *value parameter* is used for passing input arguments. A value parameter corresponds to a local variable that gets its initial value from the argument that was passed for the parameter. Modifications to a value parameter don't affect the argument that was passed for the parameter.
-
-Value parameters can be optional, by specifying a default value so that corresponding arguments can be omitted.
-
-A *reference parameter* is used for passing arguments by reference. The argument passed for a reference parameter must be a variable with a definite value, and during execution of the method, the reference parameter represents the same storage location as the argument variable. A reference parameter is declared with the `ref` modifier. The following example shows the use of `ref` parameters.
-
-[!code-csharp[swapExample](~/samples/snippets/csharp/tour/classes-and-objects/RefExample.cs#L3-L18)]
-
-An *output parameter* is used for passing arguments by reference. It's similar to a reference parameter, except that it doesn't require that you explicitly assign a value to the caller-provided argument. An output parameter is declared with the `out` modifier. The following example shows the use of `out` parameters using the syntax introduced in C# 7.
-
-[!code-csharp[OutExample](~/samples/snippets/csharp/tour/classes-and-objects/OutExample.cs#L3-L17)]
-
-A *parameter array* permits a variable number of arguments to be passed to a method. A parameter array is declared with the `params` modifier. Only the last parameter of a method can be a parameter array, and the type of a parameter array must be a single-dimensional array type. The Write and WriteLine methods of the class are good examples of parameter array usage. They're declared as follows.
-
-[!code-csharp[ConsoleExample](~/samples/snippets/csharp/tour/classes-and-objects/Program.cs#L78-L83)]
-
-Within a method that uses a parameter array, the parameter array behaves exactly like a regular parameter of an array type. However, in an invocation of a method with a parameter array, it's possible to pass either a single argument of the parameter array type or any number of arguments of the element type of the parameter array. In the latter case, an array instance is automatically created and initialized with the given arguments. This example
-
-[!code-csharp[StringFormat](~/samples/snippets/csharp/tour/classes-and-objects/Program.cs#L55-L55)]
-
-is equivalent to writing the following.
-
-[!code-csharp[StringFormat2](~/samples/snippets/csharp/tour/classes-and-objects/Program.cs#L30-L35)]
-
-### Method body and local variables
-
-A method’s body specifies the statements to execute when the method is invoked.
-
-A method body can declare variables that are specific to the invocation of the method. Such variables are called *local variables*. A local variable declaration specifies a type name, a variable name, and possibly an initial value. The following example declares a local variable `i` with an initial value of zero and a local variable `j` with no initial value.
-
-[!code-csharp[Squares](~/samples/snippets/csharp/tour/classes-and-objects/Squares.cs#L3-L17)]
-
-C# requires a local variable to be *definitely assigned* before its value can be obtained. For example, if the declaration of the previous `i` didn't include an initial value, the compiler would report an error for the subsequent usages of `i` because `i` wouldn't be definitely assigned at those points in the program.
-
-A method can use `return` statements to return control to its caller. In a method returning `void`, `return` statements can't specify an expression. In a method returning non-void, `return` statements must include an expression that computes the return value.
-
-### Static and instance methods
-
-A method declared with a static modifier is a *static method*. A static method doesn't operate on a specific instance and can only directly access static members.
-
-A method declared without a static modifier is an *instance method*. An instance method operates on a specific instance and can access both static and instance members. The instance on which an instance method was invoked can be explicitly accessed as `this`. It's an error to refer to `this` in a static method.
-
-The following `Entity` class has both static and instance members.
-
-[!code-csharp[Entity](~/samples/snippets/csharp/tour/classes-and-objects/Entity.cs#L16-L36)]
-
-Each `Entity` instance contains a serial number (and presumably some other information that isn't shown here). The `Entity` constructor (which is like an instance method) initializes the new instance with the next available serial number. Because the constructor is an instance member, it's permitted to access both the `serialNo` instance field and the `nextSerialNo` static field.
-
-The `GetNextSerialNo` and `SetNextSerialNo` static methods can access the `nextSerialNo` static field, but it would be an error for them to directly access the `serialNo` instance field.
-
-The following example shows the use of the Entity class.
-
-[!code-csharp[EntityExample](~/samples/snippets/csharp/tour/classes-and-objects/Entity.cs#L3-L15)]
-
-The `SetNextSerialNo` and `GetNextSerialNo` static methods are invoked on the class whereas the `GetSerialNo` instance method is invoked on instances of the class.
-
-### Virtual, override, and abstract methods
-
-When an instance method declaration includes a `virtual` modifier, the method is said to be a *virtual method*. When no virtual modifier is present, the method is said to be a *nonvirtual method*.
-
-When a virtual method is invoked, the *run-time type* of the instance for which that invocation takes place determines the actual method implementation to invoke. In a nonvirtual method invocation, the *compile-time type* of the instance is the determining factor.
-
-A virtual method can be *overridden* in a derived class. When an instance method declaration includes an override modifier, the method overrides an inherited virtual method with the same signature. Whereas a virtual method declaration introduces a new method, an override method declaration specializes an existing inherited virtual method by providing a new implementation of that method.
-
-An *abstract method* is a virtual method with no implementation. An abstract method is declared with the abstract modifier and is permitted only in a class that is also declared abstract. An abstract method must be overridden in every non-abstract derived class.
-
-The following example declares an abstract class, `Expression`, which represents an expression tree node, and three derived classes, `Constant`, `VariableReference`, and `Operation`, which implement expression tree nodes for constants, variable references, and arithmetic operations. (This example is similar to, but not to be confused with the expression tree types).
-
-[!code-csharp[ExpressionClass](~/samples/snippets/csharp/tour/classes-and-objects/Expressions.cs#L3-L61)]
-
-The previous four classes can be used to model arithmetic expressions. For example, using instances of these classes, the expression `x + 3` can be represented as follows.
-
-[!code-csharp[ExpressionExample](~/samples/snippets/csharp/tour/classes-and-objects/Program.cs#L40-L43)]
-
-The `Evaluate` method of an `Expression` instance is invoked to evaluate the given expression and produce a `double` value. The method takes a `Dictionary` argument that contains variable names (as keys of the entries) and values (as values of the entries). Because `Evaluate` is an abstract method, non-abstract classes derived from `Expression` must override `Evaluate`.
-
-A `Constant`'s implementation of `Evaluate` simply returns the stored constant. A `VariableReference`'s implementation looks up the variable name in the dictionary and returns the resulting value. An `Operation`'s implementation first evaluates the left and right operands (by recursively invoking their `Evaluate` methods) and then performs the given arithmetic operation.
-
-The following program uses the `Expression` classes to evaluate the expression `x * (y + 2)` for different values of `x` and `y`.
-
-[!code-csharp[ExpressionUsage](~/samples/snippets/csharp/tour/classes-and-objects/Expressions.cs#L66-L89)]
-
-### Method overloading
-
-Method *overloading* permits multiple methods in the same class to have the same name as long as they have unique signatures. When compiling an invocation of an overloaded method, the compiler uses *overload resolution* to determine the specific method to invoke. Overload resolution finds the one method that best matches the arguments or reports an error if no single best match can be found. The following example shows overload resolution in effect. The comment for each invocation in the `UsageExample` method shows which method is invoked.
-
-[!code-csharp[OverloadUsage](~/samples/snippets/csharp/tour/classes-and-objects/Overloading.cs#L3-L41)]
-
-As shown by the example, a particular method can always be selected by explicitly casting the arguments to the exact parameter types and/or explicitly supplying type arguments.
-
-## Other function members
-
-Members that contain executable code are collectively known as the *function members* of a class. The preceding section describes methods, which are the primary types of function members. This section describes the other kinds of function members supported by C#: constructors, properties, indexers, events, operators, and finalizers.
-
-The following example shows a generic class called `MyList`, which implements a growable list of objects. The class contains several examples of the most common kinds of function members.
-
-> [!NOTE]
-> This example creates a `MyList` class, which is not the same as the .NET standard . It does illustrate the concepts needed for this tour, but is not a replacement for that class.
-
-[!code-csharp[ListClass](~/samples/snippets/csharp/tour/classes-and-objects/ListBasedExamples.cs#L4-L89)]
-
-### Constructors
-
-C# supports both instance and static constructors. An *instance constructor* is a member that implements the actions required to initialize an instance of a class. A *static constructor* is a member that implements the actions required to initialize a class itself when it's first loaded.
-
-A constructor is declared like a method with no return type and the same name as the containing class. If a constructor declaration includes a static modifier, it declares a static constructor. Otherwise, it declares an instance constructor.
-
-Instance constructors can be overloaded and can have optional parameters. For example, the `MyList` class declares one instance constructor with a single optional `int` parameter. Instance constructors are invoked using the `new` operator. The following statements allocate two `MyList` instances using the constructor of the `MyList` class with and without the optional argument.
-
-[!code-csharp[ListExample1](~/samples/snippets/csharp/tour/classes-and-objects/ListBasedExamples.cs#L95-L96)]
-
-Unlike other members, instance constructors aren't inherited, and a class has no instance constructors other than those constructors actually declared in the class. If no instance constructor is supplied for a class, then an empty one with no parameters is automatically provided.
-
-### Properties
-
-*Properties* are a natural extension of fields. Both are named members with associated types, and the syntax for accessing fields and properties is the same. However, unlike fields, properties don't denote storage locations. Instead, properties have *accessors* that specify the statements to be executed when their values are read or written.
-
-A property is declared like a field, except that the declaration ends with a get accessor and/or a set accessor written between the delimiters `{` and `}` instead of ending in a semicolon. A property that has both a get accessor and a set accessor is a *read-write property*, a property that has only a get accessor is a *read-only property*, and a property that has only a set accessor is a *write-only property*.
-
-A get accessor corresponds to a parameterless method with a return value of the property type. Except as the target of an assignment, when a property is referenced in an expression, the get accessor of the property is invoked to compute the value of the property.
-
-A set accessor corresponds to a method with a single parameter named value and no return type. When a property is referenced as the target of an assignment or as the operand of ++ or --, the set accessor is invoked with an argument that provides the new value.
-
-The `MyList` class declares two properties, `Count` and `Capacity`, which are read-only and read-write, respectively. The following code is an example of use of these properties:
-
-[!code-csharp[ListExample2](~/samples/snippets/csharp/tour/classes-and-objects/ListBasedExamples.cs#L101-L104)]
-
-Similar to fields and methods, C# supports both instance properties and static properties. Static properties are declared with the static modifier, and instance properties are declared without it.
-
-The accessor(s) of a property can be virtual. When a property declaration includes a `virtual`, `abstract`, or `override` modifier, it applies to the accessor(s) of the property.
-
-### Indexers
-
-An *indexer* is a member that enables objects to be indexed in the same way as an array. An indexer is declared like a property except that the name of the member is `this` followed by a parameter list written between the delimiters `[` and `]`. The parameters are available in the accessor(s) of the indexer. Similar to properties, indexers can be read-write, read-only, and write-only, and the accessor(s) of an indexer can be virtual.
-
-The `MyList` class declares a single read-write indexer that takes an `int` parameter. The indexer makes it possible to index `MyList` instances with `int` values. For example:
-
-[!code-csharp[ListExample3](~/samples/snippets/csharp/tour/classes-and-objects/ListBasedExamples.cs#L109-L117)]
-
-Indexers can be overloaded, meaning that a class can declare multiple indexers as long as the number or types of their parameters differ.
-
-### Events
-
-An *event* is a member that enables a class or object to provide notifications. An event is declared like a field except that the declaration includes an event keyword and the type must be a delegate type.
-
-Within a class that declares an event member, the event behaves just like a field of a delegate type (provided the event isn't abstract and doesn't declare accessors). The field stores a reference to a delegate that represents the event handlers that have been added to the event. If no event handlers are present, the field is `null`.
-
-The `MyList` class declares a single event member called `Changed`, which indicates that a new item has been added to the list. The Changed event is raised by the `OnChanged` virtual method, which first checks whether the event is `null` (meaning that no handlers are present). The notion of raising an event is precisely equivalent to invoking the delegate represented by the event—thus, there are no special language constructs for raising events.
-
-Clients react to events through *event handlers*. Event handlers are attached using the `+=` operator and removed using the `-=` operator. The following example attaches an event handler to the `Changed` event of a `MyList`.
-
-[!code-csharp[EventExample](~/samples/snippets/csharp/tour/classes-and-objects/ListBasedExamples.cs#L132-L148)]
-
-For advanced scenarios where control of the underlying storage of an event is desired, an event declaration can explicitly provide `add` and `remove` accessors, which are similar to the `set` accessor of a property.
-
-### Operators
-
-An *operator* is a member that defines the meaning of applying a particular expression operator to instances of a class. Three kinds of operators can be defined: unary operators, binary operators, and conversion operators. All operators must be declared as `public` and `static`.
-
-The `MyList` class declares two operators, `operator ==` and `operator !=`, and thus gives new meaning to expressions that apply those operators to `MyList` instances. Specifically, the operators define equality of two `MyList` instances as comparing each of the contained objects using their Equals methods. The following example uses the `==` operator to compare two `MyList` instances.
-
-[!code-csharp[OperatorExample](~/samples/snippets/csharp/tour/classes-and-objects/ListBasedExamples.cs#L121-L129)]
-
-The first `Console.WriteLine` outputs `True` because the two lists contain the same number of objects with the same values in the same order. Had `MyList` not defined `operator ==`, the first `Console.WriteLine` would have output `False` because `a` and `b` reference different `MyList` instances.
-
-### Finalizers
-
-A *finalizer* is a member that implements the actions required to finalize an instance of a class. Finalizers can't have parameters, they can't have accessibility modifiers, and they can't be invoked explicitly. The finalizer for an instance is invoked automatically during garbage collection.
-
-The garbage collector is allowed wide latitude in deciding when to collect objects and run finalizers. Specifically, the timing of finalizer invocations isn't deterministic, and finalizers may be executed on any thread. For these and other reasons, classes should implement finalizers only when no other solutions are feasible.
-
-The `using` statement provides a better approach to object destruction.
-
-> [!div class="step-by-step"]
-> [Previous](statements.md)
-> [Next](arrays.md)
diff --git a/docs/csharp/tour-of-csharp/delegates.md b/docs/csharp/tour-of-csharp/delegates.md
deleted file mode 100644
index 111585c66b864..0000000000000
--- a/docs/csharp/tour-of-csharp/delegates.md
+++ /dev/null
@@ -1,28 +0,0 @@
----
-title: C# Delegates - A tour of the C# language
-description: Learn late binding with C# delegates
-ms.date: 02/27/2020
-ms.assetid: 3cc27357-3ac2-43a1-aad0-86a77b88f884
----
-
-# 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. Unlike function pointers, delegates are object-oriented and type-safe.
-
-The following example declares and uses a delegate type named `Function`.
-
-[!code-csharp[DelegateExample](../../../samples/snippets/csharp/tour/delegates/Program.cs#L3-L37)]
-
-An instance of the `Function` delegate type can reference any method that takes a `double` argument and returns a `double` value. The `Apply` method applies a given Function to the elements of a `double[]`, returning a `double[]` with the results. In the `Main` method, `Apply` is used to apply three different functions to a `double[]`.
-
-A delegate can reference either a static method (such as `Square` or `Math.Sin` in the previous example) or an instance method (such as `m.Multiply` in the previous example). A delegate that references an instance method also references a particular object, and when the instance method is invoked through the delegate, that object becomes `this` in the invocation.
-
-Delegates can also be created using anonymous functions, which are "inline methods" that are created when declared. Anonymous functions can see the local variables of the surrounding methods. The following example doesn't create a class:
-
-[!code-csharp[LambdaExample](../../../samples/snippets/csharp/tour/delegates/Program.cs#L44-L44)]
-
-A delegate doesn't know or care about the class of the method it references; all that matters is that the referenced method has the same parameters and return type as the delegate.
-
->[!div class="step-by-step"]
->[Previous](interfaces.md)
->[Next](attributes.md)
diff --git a/docs/csharp/tour-of-csharp/expressions.md b/docs/csharp/tour-of-csharp/expressions.md
deleted file mode 100644
index 542d72a7c0df4..0000000000000
--- a/docs/csharp/tour-of-csharp/expressions.md
+++ /dev/null
@@ -1,28 +0,0 @@
----
-title: C# Expressions - A tour of the C# language
-description: Expressions, operands, and operators are building blocks of the C# language
-ms.date: 02/27/2020
-ms.assetid: 20d5eb10-7381-47b9-ad90-f1cc895aa27e
----
-# Expressions
-
-*Expressions* are constructed from *operands* and *operators*. The operators of an expression indicate which operations to apply to the operands. Examples of operators include `+`, `-`, `*`, `/`, and `new`. Examples of operands include literals, fields, local variables, and expressions.
-
-When an expression contains multiple operators, the *precedence* of the operators controls the order in which the individual operators are evaluated. For example, the expression `x + y * z` is evaluated as `x + (y * z)` because the `*` operator has higher precedence than the `+` operator.
-
-When an operand occurs between two operators with the same precedence, the *associativity* of the operators controls the order in which the operations are performed:
-
-* Except for the assignment and null-coalescing operators, all binary operators are *left-associative*, meaning that operations are performed from left to right. For example, `x + y + z` is evaluated as `(x + y) + z`.
-* The assignment operators, the null-coalescing `??` and `??=` operators, and the conditional operator `?:` are *right-associative*, meaning that operations are performed from right to left. For example, `x = y = z` is evaluated as `x = (y = z)`.
-
-Precedence and associativity can be controlled using parentheses. For example, `x + y * z` first multiplies `y` by `z` and then adds the result to `x`, but `(x + y) * z` first adds `x` and `y` and then multiplies the result by `z`.
-
-Most operators can be [*overloaded*](../language-reference/operators/operator-overloading.md). Operator overloading permits user-defined operator implementations to be specified for operations where one or both of the operands are of a user-defined class or struct type.
-
-C# provides a number of operators to perform [arithmetic](../language-reference/operators/arithmetic-operators.md), [logical](../language-reference/operators/boolean-logical-operators.md), [bitwise and shift](../language-reference/operators/bitwise-and-shift-operators.md) operations and [equality](../language-reference/operators/equality-operators.md) and [order](../language-reference/operators/comparison-operators.md) comparisons.
-
-For the complete list of C# operators ordered by precedence level, see [C# operators](../language-reference/operators/index.md).
-
-> [!div class="step-by-step"]
-> [Previous](types-and-variables.md)
-> [Next](statements.md)
diff --git a/docs/csharp/tour-of-csharp/features.md b/docs/csharp/tour-of-csharp/features.md
new file mode 100644
index 0000000000000..72d0294520ef7
--- /dev/null
+++ b/docs/csharp/tour-of-csharp/features.md
@@ -0,0 +1,118 @@
+---
+title: A Tour of C# - Major language areas
+description: New to C#? Learn the basics of the language.
+ms.date: 08/06/2020
+---
+# Major language areas
+
+## Arrays, collections, and LINQ
+
+C# and .NET provide many different collection types. Arrays have syntax defined by the language. Generic collection types are listed in the namespace. Specialized collections include for accessing continuous memory on the stack frame, and for accessing continuous memory on the managed heap. All collections, including arrays, , and share a unifying principle for iteration. You use the interface. This unifying principle means that any of the collection types can be used with LINQ queries or other algorithms. You write methods using and those algorithms work with any collection.
+
+### Arrays
+
+An [***array***](../programming-guide/arrays/index.md) is a data structure that contains a number of variables that are accessed through computed indices. The variables contained in an array, also called the ***elements*** of the array, are all of the same type. This type is called the ***element type*** of the array.
+
+Array types are reference types, and the declaration of an array variable simply sets aside space for a reference to an array instance. Actual array instances are created dynamically at runtime using the `new` operator. The `new` operation specifies the ***length*** of the new array instance, which is then fixed for the lifetime of the instance. The indices of the elements of an array range from `0` to `Length - 1`. The `new` operator automatically initializes the elements of an array to their default value, which, for example, is zero for all numeric types and `null` for all reference types.
+
+The following example creates an array of `int` elements, initializes the array, and prints out the contents of the array.
+
+:::code language="csharp" source="./snippets/shared/Features.cs" ID="ArraysSample":::
+
+This example creates and operates on a ***single-dimensional array***. C# also supports ***multi-dimensional arrays***. The number of dimensions of an array type, also known as the ***rank*** of the array type, is one plus the number of commas written between the square brackets of the array type. The following example allocates a single-dimensional, a two-dimensional, and a three-dimensional array, respectively.
+
+:::code language="csharp" source="./snippets/shared/Features.cs" ID="DeclareArrays":::
+
+The `a1` array contains 10 elements, the `a2` array contains 50 (10 × 5) elements, and the `a3` array contains 100 (10 × 5 × 2) elements.
+The element type of an array can be any type, including an array type. An array with elements of an array type is sometimes called a ***jagged array*** because the lengths of the element arrays don't all have to be the same. The following example allocates an array of arrays of `int`:
+
+:::code language="csharp" source="./snippets/shared/Features.cs" ID="ArrayOfArrays":::
+
+The first line creates an array with three elements, each of type `int[]` and each with an initial value of `null`. The next lines then initialize the three elements with references to individual array instances of varying lengths.
+
+The `new` operator permits the initial values of the array elements to be specified using an ***array initializer***, which is a list of expressions written between the delimiters `{` and `}`. The following example allocates and initializes an `int[]` with three elements.
+
+:::code language="csharp" source="./snippets/shared/Features.cs" ID="InitializeArray":::
+
+The length of the array is inferred from the number of expressions between `{` and `}`. Local variable and field declarations can be shortened further such that the array type doesn't have to be restated.
+
+:::code language="csharp" source="./snippets/shared/Features.cs" ID="InitializeShortened":::
+
+Both of the previous examples are equivalent to the following code:
+
+:::code language="csharp" source="./snippets/shared/Features.cs" ID="InitializeGenerated":::
+
+The `foreach` statement can be used to enumerate the elements of any collection. The following code enumerates the array from the preceding example:
+
+:::code language="csharp" source="./snippets/shared/Features.cs" ID="EnumerateArray":::
+
+The `foreach` statement uses the interface, so can work with any collection.
+
+## String interpolation
+
+C# [***string interpolation***](../language-reference/tokens/interpolated.md) enables you to format strings by defining expressions whose results are placed in a format string. For example, the following example prints the temperature on a given day from a set of weather data:
+
+:::code language="csharp" source="./snippets/shared/Features.cs" ID="StringInterpolation":::
+
+An interpolated string is declared using the `$` token. String interpolation evaluates the expressions between `{` and `}`, then converts the result to a `string`, and replaces the text between the brackets with the string result of the expression. The `:` in the first expression, `{weatherData.Data:MM-DD-YYYY}` specifies the *format string*. In the preceding example, it specifies that the date should be printed in "MM-DD-YYYY" format.
+
+## Pattern matching
+
+The C# language provides [***pattern matching***](../pattern-matching.md) expressions to query the state of an object and execute code based on that state. You can inspect types and the values of properties and fields to determine which action to take. The `switch` expression is the primary expression for pattern matching.
+
+## Delegates and lambda expressions
+
+A [***delegate type***](../delegates-overview.md) 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. Unlike function pointers, delegates are object-oriented and type-safe.
+
+The following example declares and uses a delegate type named `Function`.
+
+:::code language="csharp" source="./snippets/shared/Features.cs" ID="DelegateExample":::
+
+An instance of the `Function` delegate type can reference any method that takes a `double` argument and returns a `double` value. The `Apply` method applies a given `Function` to the elements of a `double[]`, returning a `double[]` with the results. In the `Main` method, `Apply` is used to apply three different functions to a `double[]`.
+
+A delegate can reference either a static method (such as `Square` or `Math.Sin` in the previous example) or an instance method (such as `m.Multiply` in the previous example). A delegate that references an instance method also references a particular object, and when the instance method is invoked through the delegate, that object becomes `this` in the invocation.
+
+Delegates can also be created using anonymous functions, which are "inline methods" that are created when declared. Anonymous functions can see the local variables of the surrounding methods. The following example doesn't create a class:
+
+:::code language="csharp" source="./snippets/shared/Features.cs" ID="UseDelegate":::
+
+A delegate doesn't know or care about the class of the method it references. All that matters is that the referenced method has the same parameters and return type as the delegate.
+
+## async / await
+
+C# supports asynchronous programs with two keywords: `async` and `await`. You add the `async` modifier to a method declaration to declare the method is asynchronous. The `await` operator tells the compiler to asynchronously await for a result to finish. Control is returned to the caller, and the method returns a structure that manages the state of the asynchronous work. The structure is typically a , but can be any type that supports the awaiter pattern. These features enable you to write code that reads as its synchronous counterpart, but executes asynchronously. For example, the following code downloads the home page for [Microsoft docs](https://docs.microsoft.com):
+
+:::code language="csharp" source="./snippets/shared/Features.cs" ID="AsyncExample":::
+
+This small sample shows the major features for asynchronous programming:
+
+- The method declaration includes the `async` modifier.
+- The body of the method `await`s the return of the `GetByteArrayAsync` method.
+- The type specified in the `return` statement matches the type argument in the `Task` declaration for the method. (A method that returns a `Task` would use `return` statements without any argument).
+
+## Attributes
+
+Types, members, and other entities in a C# program support modifiers that control certain aspects of their behavior. For example, the accessibility of a method is controlled using the `public`, `protected`, `internal`, and `private` modifiers. C# generalizes this capability such that user-defined types of declarative information can be attached to program entities and retrieved at run-time. Programs specify this additional declarative information by defining and using [***attributes***](../programming-guide/concepts/attributes/index.md).
+
+The following example declares a `HelpAttribute` attribute that can be placed on program entities to provide links to their associated documentation.
+
+:::code language="csharp" source="./snippets/shared/Features.cs" ID="DefineAttribute":::
+
+All attribute classes derive from the base class provided by the .NET library. Attributes can be applied by giving their name, along with any arguments, inside square brackets just before the associated declaration. If an attribute’s name ends in `Attribute`, that part of the name can be omitted when the attribute is referenced. For example, the `HelpAttribute` can be used as follows.
+
+:::code language="csharp" source="./snippets/shared/Features.cs" ID="UseAttributes":::
+
+This example attaches a `HelpAttribute` to the `Widget` class. It adds another `HelpAttribute` to the `Display` method in the class. The public constructors of an attribute class control the information that must be provided when the attribute is attached to a program entity. Additional information can be provided by referencing public read-write properties of the attribute class (such as the reference to the `Topic` property previously).
+
+The metadata defined by attributes can be read and manipulated at runtime using reflection. When a particular attribute is requested using this technique, the constructor for the attribute class is invoked with the information provided in the program source, and the resulting attribute instance is returned. If additional information was provided through properties, those properties are set to the given values before the attribute instance is returned.
+
+The following code sample demonstrates how to get the `HelpAttribute` instances associated to the `Widget` class and its `Display` method.
+
+:::code language="csharp" source="./snippets/shared/Features.cs" ID="ReadAttributes":::
+
+## Learn more
+
+You can explore more about C# by trying one of our [tutorials](../tutorials/index.md).
+
+>[!div class="step-by-step"]
+>[Previous](program-building-blocks.md)
diff --git a/docs/csharp/tour-of-csharp/index.md b/docs/csharp/tour-of-csharp/index.md
index fb918d10608bd..a99316eb5dff2 100644
--- a/docs/csharp/tour-of-csharp/index.md
+++ b/docs/csharp/tour-of-csharp/index.md
@@ -1,75 +1,131 @@
---
title: A Tour of C# - C# Guide
description: New to C#? Learn the basics of the language.
-ms.date: 02/26/2020
+ms.date: 08/06/2020
---
# A tour of the C# language
-C# (pronounced "See Sharp") is a 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# (pronounced "See Sharp") is a 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. This tour provides an overview of the major components of the language in C# 8 and earlier. If you want to explore the language through interactive examples, try the [introduction to C#](../tutorials/intro-to-csharp/index.md) tutorials.
-This tour provides an overview of the major components of the language in C# 8 and earlier. If you want to explore the language through interactive examples, try the [introduction to C#](../tutorials/intro-to-csharp/index.md) tutorials.
+C# is an object-oriented, ***component-oriented*** programming language. C# provides language constructs to directly support these concepts, making C# a natural language in which to create and use software components. Since its origin, C# has added features to support new workloads and emerging software design practices.
-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. They incorporate their own documentation. C# provides language constructs to support directly these concepts, making C# a natural language in which to create and use software components.
+Several C# features aid in the construction of robust and durable applications. [***Garbage collection***](../../standard/garbage-collection/index.md) automatically reclaims memory occupied by unreachable unused objects. [***Exception handling***](../programming-guide/exceptions/index.md) provides a structured and extensible approach to error detection and recovery. [***Lambda expressions***](../programming-guide/statements-expressions-operators/lambda-expressions.md) support functional programming techniques. [***Query syntax***](../linq/index.md) creates a common pattern for working with data from any source. Language support for [***asynchronous operations***](../programming-guide/concepts/async/index.md) provides syntax for building distributed systems. [***Pattern matching***](..//pattern-matching.md) provides syntax to easily separate data from algorithms in modern distributed systems. C# has a [***unified type system***](../programming-guide/types/index.md). All C# types, including primitive types such as `int` and `double`, inherit from a single root `object` type. All types share a set of common operations. 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. C# allows dynamic allocation of objects and in-line storage of lightweight structures.
-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. 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# emphasizes ***versioning*** to ensure programs and libraries can evolve over time in a compatible manner. 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.
-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.
+## Hello world
-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. As a result, programs written in those other 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.
+The "Hello, World" program is traditionally used to introduce a programming language. Here it is in C#:
-In more recent versions, C# has embraced other programming paradigms. C# has included features that support functional programming techniques like lambda expressions. Other new features support separating data and algorithms, like pattern matching.
+:::code language="csharp" interactive="try-dotnet" source="./snippets/shared/HelloWorld.cs":::
-## Hello world
+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, World" program is traditionally used to introduce a programming language. Here it is in C#:
+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 C# program.
-[!code-csharp[Hello World](~/samples/snippets/csharp/tour/hello/Program.cs)]
+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.
-C# source files typically have the file extension `.cs`. To create this program, first download and install the [.NET Core SDK](https://dotnet.microsoft.com/download). Then, execute the command `dotnet new console -o hello` to create a new program and a build script. The program and build script are in the files `Program.cs` and `hello.csproj`, respectively. You build and run the application with the `run` commands:
+## Types and variables
-```dotnetcli
-cd hello
-dotnet run
-```
+There are two kinds of types in C#: *value types* and *reference types*. Variables of value types directly contain their data whereas variables of reference types store references to their data, the latter being known as objects. With reference types, it's possible for two variables to reference the same object and possible for operations on one variable to affect the object referenced by the other variable. With value types, the variables each have their own copy of the data, and it isn't possible for operations on one to affect the other (except for `ref` and `out` parameter variables).
-The program produces the following output:
+An ***identifier*** is a variable name. An identifier is a sequence of unicode characters without any whitespace. An identifier may be a C# reserved word, if it is prefixed by `@`. That can be useful when interacting with other languages.
-```dotnetcli
-Hello, World!
-```
+C#'s value types are further divided into *simple types*, *enum types*, *struct types*, and *nullable value types*. C#'s reference types are further divided into *class types*, *interface types*, *array types*, and *delegate types*.
-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 following outline provides an overview of C#'s type system.
-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.
+- [Value types](../language-reference/builtin-types/value-types.md)
+ - [Simple types](../language-reference/builtin-types/value-types.md#built-in-value-types)
+ - [Signed integral](../language-reference/builtin-types/integral-numeric-types.md): `sbyte`, `short`, `int`, `long`
+ - [Unsigned integral](../language-reference/builtin-types/integral-numeric-types.md): `byte`, `ushort`, `uint`, `ulong`
+ - [Unicode characters](/dotnet/standard/base-types/character-encoding-introduction): `char`, which represents a UTF-16 code unit
+ - [IEEE binary floating-point](../language-reference/builtin-types/floating-point-numeric-types.md): `float`, `double`
+ - [High-precision decimal floating-point](../language-reference/builtin-types/floating-point-numeric-types.md): `decimal`
+ - Boolean: `bool`, which represents Boolean values—values that are either `true` or `false`
+ - [Enum types](../language-reference/builtin-types/enum.md)
+ - User-defined types of the form `enum E {...}`. An `enum` type is a distinct type with named constants. Every `enum` type has an underlying type, which must be one of the eight integral types. The set of values of an `enum` type is the same as the set of values of the underlying type.
+ - [Struct types](../language-reference/builtin-types/struct.md)
+ - User-defined types of the form `struct S {...}`
+ - [Nullable value types](../language-reference/builtin-types/nullable-value-types.md)
+ - Extensions of all other value types with a `null` value
+ - [Tuple value types](../tuples.md)
+ - User-defined types of the form `(T1, T2, ...)`
+- [Reference types](../language-reference/keywords/reference-types.md)
+ - [Class types](../language-reference/keywords/class.md)
+ - Ultimate base class of all other types: `object`
+ - [Unicode strings](/dotnet/standard/base-types/character-encoding-introduction): `string`, which represents a sequence of UTF-16 code units
+ - User-defined types of the form `class C {...}`
+ - [Interface types](../language-reference/keywords/interface.md)
+ - User-defined types of the form `interface I {...}`
+ - [Array types](../programming-guide/arrays/index.md)
+ - Single- and multi-dimensional and jagged, for example, `int[]`, `int[,]`, and `int[][]`
+ - [Delegate types](../language-reference/keywords/delegate.md)
+ - User-defined types of the form `delegate int D(...)`
-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.
+C# programs use *type declarations* to create new types. A type declaration specifies the name and the members of the new type. Five of C#'s categories of types are user-definable: class types, struct types, interface types, enum types, and delegate types.
+
+- A `class` type defines a data structure that contains data members (fields) and function members (methods, properties, and others). Class types support single inheritance and polymorphism, mechanisms whereby derived classes can extend and specialize base classes.
+- A `struct` type is similar to a class type in that it represents a structure with data members and function members. However, unlike classes, structs are value types and don't typically require heap allocation. Struct types don't support user-specified inheritance, and all struct types implicitly inherit from type `object`.
+- An `interface` type defines a contract as a named set of public members. A `class` or `struct` that implements an `interface` must provide implementations of the interface's members. An `interface` may inherit from multiple base interfaces, and a `class` or `struct` may implement multiple interfaces.
+- 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 analogous to function types provided by functional languages. They're also similar to the concept of function pointers found in some other languages. Unlike function pointers, delegates are object-oriented and type-safe.
+
+The `class`, `struct`, `interface`, and `delegate` types all support generics, whereby they can be parameterized with other types.
+
+C# supports single- and multi-dimensional arrays of any type. Unlike the types listed above, array types don't have to be declared before they can be used. Instead, array types are constructed by following a type name with square brackets. For example, `int[]` is a single-dimensional array of `int`, `int[,]` is a two-dimensional array of `int`, and `int[][]` is a single-dimensional array of single-dimensional array or "jagged" array of `int`.
+
+Nullable types don't require a separate definition. For each non-nullable type `T`, there's a corresponding nullable type `T?`, which can hold an additional value, `null`. For instance, `int?` is a type that can hold any 32-bit integer or the value `null`, and `string?` is a type that can hold any `string` or the value `null`.
+
+C#'s type system is unified such that a value of any type can be treated as an `object`. Every type in C# directly or indirectly derives from the `object` class type, and `object` is the ultimate base class of all types. Values of reference types are treated as objects simply by viewing the values as type `object`. Values of value types are treated as objects by performing *boxing* and *unboxing operations*. In the following example, an `int` value is converted to `object` and back again to `int`.
+
+:::code language="csharp" source="./snippets/shared/Program.cs" ID="boxing" :::
+
+When a value of a value type is assigned to an `object` reference, a "box" is allocated to hold the value. That box is an instance of a reference type, and the value is copied into that box. Conversely, when an `object` reference is cast to a value type, a check is made that the referenced `object` is a box of the correct value type. If the check succeeds, the value in the box is copied to the value type.
+
+C#'s unified type system effectively means that value types are treated as `object` references "on demand." Because of the unification, general-purpose libraries that use type `object` can be used with all types that derive from `object`, including both reference types and value types.
+
+There are several kinds of *variables* in C#, including fields, array elements, local variables, and parameters. Variables represent storage locations. Every variable has a type that determines what values can be stored in the variable, as shown below.
+
+- Non-nullable value type
+ - A value of that exact type
+- Nullable value type
+ - A `null` value or a value of that exact type
+- object
+ - A `null` reference, a reference to an object of any reference type, or a reference to a boxed value of any value type
+- Class type
+ - A `null` reference, a reference to an instance of that class type, or a reference to an instance of a class derived from that class type
+- Interface type
+ - A `null` reference, a reference to an instance of a class type that implements that interface type, or a reference to a boxed value of a value type that implements that interface type
+- Array type
+ - A `null` reference, a reference to an instance of that array type, or a reference to an instance of a compatible array type
+- Delegate type
+ - A `null` reference or a reference to an instance of a compatible delegate type
+
+## Program structure
+
+The key organizational concepts in C# are [***programs***](../programming-guide/inside-a-program/index.md), [***namespaces***](../programming-guide/namespaces/index.md), [***types***](../programming-guide/types/index.md), [***members***](../programming-guide/classes-and-structs/members.md), and [***assemblies***](../../standard/assembly/index.md). Programs declare types, which contain members and can be organized into namespaces. Classes, structs, and interfaces are examples of types. Fields, methods, properties, and events are examples of members. When C# programs are compiled, they're physically packaged into assemblies. Assemblies typically have the file extension `.exe` or `.dll`, depending on whether they implement ***applications*** or ***libraries***, respectively.
+
+As a small example, consider an assembly that contains the following code:
+
+:::code language="csharp" source="./snippets/shared/AcmeStack.cs":::
+
+The fully qualified name of this class is `Acme.Collections.Stack`. The class contains several members: a field named `top`, two methods named `Push` and `Pop`, and a nested class named `Entry`. The `Entry` class further contains three members: a field named `next`, a field named `data`, and a constructor. The `Stack` is a *generic* class. It has one type parameter, `T` that is replaced with a concrete type when it's used.
-## Elements of the C# language
-
-There's a lot more to learn about C#. The following topics provide an overview of the elements of the C# language. These overviews provide basic information about all elements of the language and give you the information necessary to dive deeper:
-
-- [Program Structure](program-structure.md)
- - Learn the key organizational concepts in the C# language: ***programs***, ***namespaces***, ***types***, ***members***, and ***assemblies***.
-- [Types and Variables](types-and-variables.md)
- - Learn about ***value types***, ***reference types***, and ***variables*** in the C# language.
-- [Expressions](expressions.md)
- - ***Expressions*** are constructed from ***operands*** and ***operators***. Expressions produce a value.
-- [Statements](statements.md)
- - You use ***statements*** to express the actions of a program.
-- [Classes and objects](classes-and-objects.md)
- - ***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.
-- [Arrays](arrays.md)
- - An ***array*** is a data structure that contains a number of variables that are accessed through computed indices.
-- [Interfaces](interfaces.md)
- - An ***interface*** defines a contract that can be implemented by classes and structs. An interface can contain methods, properties, events, and indexers. An interface doesn't provide implementations of the members it defines—it merely specifies the members that must be supplied by classes or structs that implement the interface.
-- [Delegates](delegates.md)
- - 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.md)
- - ***Attributes*** enable programs to specify additional declarative information about types, members, and other entities.
-
> [!NOTE]
-> These articles apply to C# 7.0 and later. Some features may not be available in earlier versions.
+> A *stack* is a "first in - last out" (FILO) collection. New elements are added to the top of the stack. When an element is removed, it is removed from the top of the stack.
+
+Assemblies contain executable code in the form of Intermediate Language (IL) instructions, and symbolic information in the form of metadata. Before it's executed, the Just-In-Time (JIT) compiler of .NET Common Language Runtime converts the IL code in an assembly to processor-specific code.
+
+Because an assembly is a self-describing unit of functionality containing both code and metadata, there's no need for `#include` directives and header files in C#. The public types and members contained in a particular assembly are made available in a C# program simply by referencing that assembly when compiling the program. For example, this program uses the `Acme.Collections.Stack` class from the `acme.dll` assembly:
+
+:::code language="csharp" source="./snippets/shared/StackUsage.cs":::
+
+To compile this program, you would need to *reference* the assembly containing the stack class defined in the earlier example.
+
+C# programs can be stored in several source files. When a C# program is compiled, all of the source files are processed together, and the source files can freely reference each other. Conceptually, it's as if all the source files were concatenated into one large file before being processed. Forward declarations are never needed in C# because, with few exceptions, declaration order is insignificant. C# doesn't limit a source file to declaring only one public type nor does it require the name of the source file to match a type declared in the source file.
+
+Further articles in this tour explain these organizational blocks.
-> [!div class="step-by-step"]
-> [Next](program-structure.md)
+>[!div class="step-by-step"]
+>[Next](types.md)
diff --git a/docs/csharp/tour-of-csharp/interfaces.md b/docs/csharp/tour-of-csharp/interfaces.md
deleted file mode 100644
index b5f1eba9dcd45..0000000000000
--- a/docs/csharp/tour-of-csharp/interfaces.md
+++ /dev/null
@@ -1,38 +0,0 @@
----
-title: C# Interfaces - A tour of the C# language
-description: Interfaces define contracts implemented by types in C#
-ms.date: 02/27/2020
-ms.assetid: a9bf82f4-efd1-4216-bd34-4ef0fa48c968
----
-
-# 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 doesn't provide implementations of the members it defines—it merely specifies the members that must be supplied by classes or structs that implement the interface.
-
-Interfaces may employ ***multiple inheritance***. In the following example, the interface `IComboBox` inherits from both `ITextBox` and `IListBox`.
-
-[!code-csharp[InterfacesOne](../../../samples/snippets/csharp/tour/interfaces/Program.cs#L5-L17)]
-
-Classes and structs can implement multiple interfaces. In the following example, the class `EditBox` implements both `IControl` and `IDataBound`.
-
-[!code-csharp[InterfacesTwo](../../../samples/snippets/csharp/tour/interfaces/Program.cs#L19-L27)]
-
-When a class or struct implements a particular interface, instances of that class or struct can be implicitly converted to that interface type. For example
-
-[!code-csharp[InterfacesThree](../../../samples/snippets/csharp/tour/interfaces/Program.cs#L33-L35)]
-
-In cases where an instance isn't statically known to implement a particular interface, dynamic type casts can be used. For example, the following statements use dynamic type casts to obtain an object’s `IControl` and `IDataBound` interface implementations. Because the run-time actual type of the object is `EditBox`, the casts succeed.
-
-[!code-csharp[InterfacesFour](../../../samples/snippets/csharp/tour/interfaces/Program.cs#L40-L42)]
-
-In the previous `EditBox` class, the `Paint` method from the `IControl` interface and the `Bind` method from the `IDataBound` interface are implemented using public members. C# also supports explicit ***interface member implementations***, enabling the class or struct to avoid making the members public. An explicit interface member implementation is written using the fully qualified interface member name. For example, the `EditBox` class could implement the `IControl.Paint` and `IDataBound.Bind` methods using explicit interface member implementations as follows.
-
-[!code-csharp[InterfacesFive](../../../samples/snippets/csharp/tour/interfaces/Program.cs#L60-L64)]
-
-Explicit interface members can only be accessed via the interface type. For example, the implementation of `IControl.Paint` provided by the previous EditBox class can only be invoked by first converting the `EditBox` reference to the `IControl` interface type.
-
-[!code-csharp[InterfacesFive](../../../samples/snippets/csharp/tour/interfaces/Program.cs#L71-L74)]
-
->[!div class="step-by-step"]
->[Previous](arrays.md)
->[Next](delegates.md)
diff --git a/docs/csharp/tour-of-csharp/program-building-blocks.md b/docs/csharp/tour-of-csharp/program-building-blocks.md
new file mode 100644
index 0000000000000..1218cff3c45fc
--- /dev/null
+++ b/docs/csharp/tour-of-csharp/program-building-blocks.md
@@ -0,0 +1,299 @@
+---
+title: The building blocks of C# programs"
+description: Learn about C# members, expressions, and statements. Types contain members you write. Those members are built from statements and expressions.
+ms.date: 08/06/2020
+---
+# Program building blocks
+
+The types described in the previous article are built using these building blocks: [***members***](../programming-guide/classes-and-structs/members.md), [***expressions***, and ***statements***](../programming-guide/statements-expressions-operators/index.md).
+
+## Members
+
+The members of a `class` are either ***static members*** or ***instance members***. Static members belong to classes, and instance members belong to objects (instances of classes).
+
+The following list provides an overview of the kinds of members a class can contain.
+
+- **Constants**: Constant values associated with the class
+- **Fields**: Variables that are associated of the class
+- **Methods**: Actions that can be performed by the class
+- **Properties**: Actions associated with reading and writing named properties of the class
+- **Indexers**: Actions associated with indexing instances of the class like an array
+- **Events**: Notifications that can be generated by the class
+- **Operators**: Conversions and expression operators supported by the class
+- **Constructors**: Actions required to initialize instances of the class or the class itself
+- **Finalizers**: Actions performed before instances of the class are permanently discarded
+- **Types**: Nested types declared by the class
+
+## Accessibility
+
+Each member of a class has an associated accessibility, which controls the regions of program text that can access the member. There are six possible forms of accessibility. The access modifiers are summarized below.
+
+- `public`: Access isn't limited.
+- `private`: Access is limited to this class.
+- `protected`: Access is limited to this class or classes derived from this class.
+- `internal`: Access is limited to the current assembly (`.exe` or `.dll`).
+- `protected internal`: Access is limited to this class, classes derived from this class, or classes within the same assembly.
+- `private protected`: Access is limited to this class or classes derived from this type within the same assembly.
+
+## Fields
+
+A *field* is a variable that is associated with a class or with an instance of a class.
+
+A field declared with the static modifier defines a static field. A static field identifies exactly one storage location. No matter how many instances of a class are created, there's only ever one copy of a static field.
+
+A field declared without the static modifier defines an instance field. Every instance of a class contains a separate copy of all the instance fields of that class.
+
+In the following example, each instance of the `Color` class has a separate copy of the `r`, `g`, and `b` instance fields, but there's only one copy of the `Black`, `White`, `Red`, `Green`, and `Blue` static fields:
+
+:::code language="csharp" source="./snippets/shared/ClassesObjects.cs" ID="ColorClassDefinition":::
+
+As shown in the previous example, *read-only fields* may be declared with a `readonly` modifier. Assignment to a read-only field can only occur as part of the field’s declaration or in a constructor in the same class.
+
+## Methods
+
+A *method* is a member that implements a computation or action that can be performed by an object or class. *Static methods* are accessed through the class. *Instance methods* are accessed through instances of the class.
+
+Methods may have a list of *parameters*, which represent values or variable references passed to the method. Methods have a *return type*, which specifies the type of the value computed and returned by the method. A method’s return type is `void` if it doesn't return a value.
+
+Like types, methods may also have a set of type parameters, for which type arguments must be specified when the method is called. Unlike types, the type arguments can often be inferred from the arguments of a method call and need not be explicitly given.
+
+The *signature* of a method must be unique in the class in which the method is declared. The signature of a method consists of the name of the method, the number of type parameters, and the number, modifiers, and types of its parameters. The signature of a method doesn't include the return type.
+
+When a method body is a single expression, the method can be defined using a compact expression format, as shown in the following example:
+
+```csharp
+public override ToString() => "This is an object";
+```
+
+### Parameters
+
+Parameters are used to pass values or variable references to methods. The parameters of a method get their actual values from the *arguments* that are specified when the method is invoked. There are four kinds of parameters: value parameters, reference parameters, output parameters, and parameter arrays.
+
+A *value parameter* is used for passing input arguments. A value parameter corresponds to a local variable that gets its initial value from the argument that was passed for the parameter. Modifications to a value parameter don't affect the argument that was passed for the parameter.
+
+Value parameters can be optional, by specifying a default value so that corresponding arguments can be omitted.
+
+A *reference parameter* is used for passing arguments by reference. The argument passed for a reference parameter must be a variable with a definite value. During execution of the method, the reference parameter represents the same storage location as the argument variable. A reference parameter is declared with the `ref` modifier. The following example shows the use of `ref` parameters.
+
+:::code language="csharp" source="./snippets/shared/ClassesObjects.cs" ID="RefExample":::
+
+An *output parameter* is used for passing arguments by reference. It's similar to a reference parameter, except that it doesn't require that you explicitly assign a value to the caller-provided argument. An output parameter is declared with the `out` modifier. The following example shows the use of `out` parameters using the syntax introduced in C# 7.
+
+:::code language="csharp" source="./snippets/shared/ClassesObjects.cs" ID="OutExample":::
+
+A *parameter array* permits a variable number of arguments to be passed to a method. A parameter array is declared with the `params` modifier. Only the last parameter of a method can be a parameter array, and the type of a parameter array must be a single-dimensional array type. The `Write` and `WriteLine` methods of the class are good examples of parameter array usage. They're declared as follows.
+
+:::code language="csharp" source="./snippets/shared/ClassesObjects.cs" ID="ConsoleExtract":::
+
+Within a method that uses a parameter array, the parameter array behaves exactly like a regular parameter of an array type. However, in an invocation of a method with a parameter array, it's possible to pass either a single argument of the parameter array type or any number of arguments of the element type of the parameter array. In the latter case, an array instance is automatically created and initialized with the given arguments. This example
+
+:::code language="csharp" source="./snippets/shared/ClassesObjects.cs" ID="UseParamsArgs":::
+
+is equivalent to writing the following.
+
+:::code language="csharp" source="./snippets/shared/ClassesObjects.cs" ID="CompilerParams":::
+
+### Method body and local variables
+
+A method’s body specifies the statements to execute when the method is invoked.
+
+A method body can declare variables that are specific to the invocation of the method. Such variables are called *local variables*. A local variable declaration specifies a type name, a variable name, and possibly an initial value. The following example declares a local variable `i` with an initial value of zero and a local variable `j` with no initial value.
+
+:::code language="csharp" source="./snippets/shared/ClassesObjects.cs" ID="SquaresClass":::
+
+C# requires a local variable to be *definitely assigned* before its value can be obtained. For example, if the declaration of the previous `i` didn't include an initial value, the compiler would report an error for the later usages of `i` because `i` wouldn't be definitely assigned at those points in the program.
+
+A method can use `return` statements to return control to its caller. In a method returning `void`, `return` statements can't specify an expression. In a method returning non-void, `return` statements must include an expression that computes the return value.
+
+### Static and instance methods
+
+A method declared with a `static` modifier is a *static method*. A static method doesn't operate on a specific instance and can only directly access static members.
+
+A method declared without a `static` modifier is an *instance method*. An instance method operates on a specific instance and can access both static and instance members. The instance on which an instance method was invoked can be explicitly accessed as `this`. It's an error to refer to `this` in a static method.
+
+The following `Entity` class has both static and instance members.
+
+:::code language="csharp" source="./snippets/shared/ClassesObjects.cs" ID="EntityClass":::
+
+Each `Entity` instance contains a serial number (and presumably some other information that isn't shown here). The `Entity` constructor (which is like an instance method) initializes the new instance with the next available serial number. Because the constructor is an instance member, it's permitted to access both the `_serialNo` instance field and the `s_nextSerialNo` static field.
+
+The `GetNextSerialNo` and `SetNextSerialNo` static methods can access the `s_nextSerialNo` static field, but it would be an error for them to directly access the `_serialNo` instance field.
+
+The following example shows the use of the `Entity` class.
+
+:::code language="csharp" source="./snippets/shared/ClassesObjects.cs" ID="UsingEntity":::
+
+The `SetNextSerialNo` and `GetNextSerialNo` static methods are invoked on the class whereas the `GetSerialNo` instance method is invoked on instances of the class.
+
+### Virtual, override, and abstract methods
+
+When an instance method declaration includes a `virtual` modifier, the method is said to be a *virtual method*. When no virtual modifier is present, the method is said to be a *nonvirtual method*.
+
+When a virtual method is invoked, the *run-time type* of the instance for which that invocation takes place determines the actual method implementation to invoke. In a nonvirtual method invocation, the *compile-time type* of the instance is the determining factor.
+
+A virtual method can be *overridden* in a derived class. When an instance method declaration includes an override modifier, the method overrides an inherited virtual method with the same signature. Aa virtual method declaration introduces a new method. An override method declaration specializes an existing inherited virtual method by providing a new implementation of that method.
+
+An *abstract method* is a virtual method with no implementation. An abstract method is declared with the `abstract` modifier and is permitted only in an abstract class. An abstract method must be overridden in every non-abstract derived class.
+
+The following example declares an abstract class, `Expression`, which represents an expression tree node, and three derived classes, `Constant`, `VariableReference`, and `Operation`, which implement expression tree nodes for constants, variable references, and arithmetic operations. (This example is similar to, but not related to the expression tree types).
+
+:::code language="csharp" source="./snippets/shared/ClassesObjects.cs" ID="WorkingWithExpressions":::
+
+The previous four classes can be used to model arithmetic expressions. For example, using instances of these classes, the expression `x + 3` can be represented as follows.
+
+:::code language="csharp" source="./snippets/shared/ClassesObjects.cs" ID="UseExpressions":::
+
+The `Evaluate` method of an `Expression` instance is invoked to evaluate the given expression and produce a `double` value. The method takes a `Dictionary` argument that contains variable names (as keys of the entries) and values (as values of the entries). Because `Evaluate` is an abstract method, non-abstract classes derived from `Expression` must override `Evaluate`.
+
+A `Constant`'s implementation of `Evaluate` simply returns the stored constant. A `VariableReference`'s implementation looks up the variable name in the dictionary and returns the resulting value. An `Operation`'s implementation first evaluates the left and right operands (by recursively invoking their `Evaluate` methods) and then performs the given arithmetic operation.
+
+The following program uses the `Expression` classes to evaluate the expression `x * (y + 2)` for different values of `x` and `y`.
+
+:::code language="csharp" source="./snippets/shared/ClassesObjects.cs" ID="UsingExpressions":::
+
+### Method overloading
+
+Method *overloading* permits multiple methods in the same class to have the same name as long as they have unique signatures. When compiling an invocation of an overloaded method, the compiler uses *overload resolution* to determine the specific method to invoke. Overload resolution finds the one method that best matches the arguments. If no single best match can be found, an error is reported. The following example shows overload resolution in effect. The comment for each invocation in the `UsageExample` method shows which method is invoked.
+
+:::code language="csharp" source="./snippets/shared/ClassesObjects.cs" ID="Overloading":::
+
+As shown by the example, a particular method can always be selected by explicitly casting the arguments to the exact parameter types and type arguments.
+
+## Other function members
+
+Members that contain executable code are collectively known as the *function members* of a class. The preceding section describes methods, which are the primary types of function members. This section describes the other kinds of function members supported by C#: constructors, properties, indexers, events, operators, and finalizers.
+
+The following example shows a generic class called `MyList`, which implements a growable list of objects. The class contains several examples of the most common kinds of function members.
+
+:::code language="csharp" source="./snippets/shared/ClassesObjects.cs" ID="ListExample":::
+
+### Constructors
+
+C# supports both instance and static constructors. An *instance constructor* is a member that implements the actions required to initialize an instance of a class. A *static constructor* is a member that implements the actions required to initialize a class itself when it's first loaded.
+
+A constructor is declared like a method with no return type and the same name as the containing class. If a constructor declaration includes a `static` modifier, it declares a static constructor. Otherwise, it declares an instance constructor.
+
+Instance constructors can be overloaded and can have optional parameters. For example, the `MyList` class declares one instance constructor with a single optional `int` parameter. Instance constructors are invoked using the `new` operator. The following statements allocate two `MyList` instances using the constructor of the `MyList` class with and without the optional argument.
+
+:::code language="csharp" source="./snippets/shared/ClassesObjects.cs" ID="CreateLists":::
+
+Unlike other members, instance constructors aren't inherited. A class has no instance constructors other than those constructors actually declared in the class. If no instance constructor is supplied for a class, then an empty one with no parameters is automatically provided.
+
+### Properties
+
+*Properties* are a natural extension of fields. Both are named members with associated types, and the syntax for accessing fields and properties is the same. However, unlike fields, properties don't denote storage locations. Instead, properties have *accessors* that specify the statements executed when their values are read or written.
+
+A property is declared like a field, except that the declaration ends with a get accessor or a set accessor written between the delimiters `{` and `}` instead of ending in a semicolon. A property that has both a get accessor and a set accessor is a *read-write property*, a property that has only a get accessor is a *read-only property*, and a property that has only a set accessor is a *write-only property*.
+
+A get accessor corresponds to a parameterless method with a return value of the property type. A set accessor corresponds to a method with a single parameter named value and no return type. The get accessor computes the value of the property. The set accessor provides a new value for the property. When the property is the target of an assignment, or the operand of `++` or `--`, the set accessor is invoked. In other cases where the property is referenced, the get accessor is invoked.
+
+ When a property is referenced as the target of an assignment or as the operand of ++ or --, the set accessor is invoked with an argument that provides the new value.
+
+The `MyList` class declares two properties, `Count` and `Capacity`, which are read-only and read-write, respectively. The following code is an example of use of these properties:
+
+:::code language="csharp" source="./snippets/shared/ClassesObjects.cs" ID="AccessProperties":::
+
+Similar to fields and methods, C# supports both instance properties and static properties. Static properties are declared with the static modifier, and instance properties are declared without it.
+
+The accessor(s) of a property can be virtual. When a property declaration includes a `virtual`, `abstract`, or `override` modifier, it applies to the accessor(s) of the property.
+
+### Indexers
+
+An *indexer* is a member that enables objects to be indexed in the same way as an array. An indexer is declared like a property except that the name of the member is `this` followed by a parameter list written between the delimiters `[` and `]`. The parameters are available in the accessor(s) of the indexer. Similar to properties, indexers can be read-write, read-only, and write-only, and the accessor(s) of an indexer can be virtual.
+
+The `MyList` class declares a single read-write indexer that takes an `int` parameter. The indexer makes it possible to index `MyList` instances with `int` values. For example:
+
+:::code language="csharp" source="./snippets/shared/ClassesObjects.cs" ID="ListAddition":::
+
+Indexers can be overloaded. A class can declare multiple indexers as long as the number or types of their parameters differ.
+
+### Events
+
+An *event* is a member that enables a class or object to provide notifications. An event is declared like a field except that the declaration includes an `event` keyword and the type must be a delegate type.
+
+Within a class that declares an event member, the event behaves just like a field of a delegate type (provided the event isn't abstract and doesn't declare accessors). The field stores a reference to a delegate that represents the event handlers that have been added to the event. If no event handlers are present, the field is `null`.
+
+The `MyList` class declares a single event member called `Changed`, which indicates that a new item has been added to the list. The Changed event is raised by the `OnChanged` virtual method, which first checks whether the event is `null` (meaning that no handlers are present). The notion of raising an event is precisely equivalent to invoking the delegate represented by the event. There are no special language constructs for raising events.
+
+Clients react to events through *event handlers*. Event handlers are attached using the `+=` operator and removed using the `-=` operator. The following example attaches an event handler to the `Changed` event of a `MyList`.
+
+:::code language="csharp" source="./snippets/shared/ClassesObjects.cs" ID="RespondToEvents":::
+
+For advanced scenarios where control of the underlying storage of an event is desired, an event declaration can explicitly provide `add` and `remove` accessors, which are similar to the `set` accessor of a property.
+
+### Operators
+
+An *operator* is a member that defines the meaning of applying a particular expression operator to instances of a class. Three kinds of operators can be defined: unary operators, binary operators, and conversion operators. All operators must be declared as `public` and `static`.
+
+The `MyList` class declares two operators, `operator ==` and `operator !=`. These overridden operators give new meaning to expressions that apply those operators to `MyList` instances. Specifically, the operators define equality of two `MyList` instances as comparing each of the contained objects using their `Equals` methods. The following example uses the `==` operator to compare two `MyList` instances.
+
+:::code language="csharp" source="./snippets/shared/ClassesObjects.cs" ID="ListAddition":::
+
+The first `Console.WriteLine` outputs `True` because the two lists contain the same number of objects with the same values in the same order. Had `MyList` not defined `operator ==`, the first `Console.WriteLine` would have output `False` because `a` and `b` reference different `MyList` instances.
+
+### Finalizers
+
+A *finalizer* is a member that implements the actions required to finalize an instance of a class. Typically, a finalizer is needed to release unmanaged resources. Finalizers can't have parameters, they can't have accessibility modifiers, and they can't be invoked explicitly. The finalizer for an instance is invoked automatically during garbage collection. For more details, see the article on [finalizers](../programming-guide/classes-and-structs/destructors.md).
+
+The garbage collector is allowed wide latitude in deciding when to collect objects and run finalizers. Specifically, the timing of finalizer invocations isn't deterministic, and finalizers may be executed on any thread. For these and other reasons, classes should implement finalizers only when no other solutions are feasible.
+
+The `using` statement provides a better approach to object destruction.
+
+## Expressions
+
+*Expressions* are constructed from *operands* and *operators*. The operators of an expression indicate which operations to apply to the operands. Examples of operators include `+`, `-`, `*`, `/`, and `new`. Examples of operands include literals, fields, local variables, and expressions.
+
+When an expression contains multiple operators, the *precedence* of the operators controls the order in which the individual operators are evaluated. For example, the expression `x + y * z` is evaluated as `x + (y * z)` because the `*` operator has higher precedence than the `+` operator.
+
+When an operand occurs between two operators with the same precedence, the *associativity* of the operators controls the order in which the operations are performed:
+
+* Except for the assignment and null-coalescing operators, all binary operators are *left-associative*, meaning that operations are performed from left to right. For example, `x + y + z` is evaluated as `(x + y) + z`.
+* The assignment operators, the null-coalescing `??` and `??=` operators, and the conditional operator `?:` are *right-associative*, meaning that operations are performed from right to left. For example, `x = y = z` is evaluated as `x = (y = z)`.
+
+Precedence and associativity can be controlled using parentheses. For example, `x + y * z` first multiplies `y` by `z` and then adds the result to `x`, but `(x + y) * z` first adds `x` and `y` and then multiplies the result by `z`.
+
+Most operators can be [*overloaded*](../language-reference/operators/operator-overloading.md). Operator overloading permits user-defined operator implementations to be specified for operations where one or both of the operands are of a user-defined class or struct type.
+
+C# provides a number of operators to perform [arithmetic](../language-reference/operators/arithmetic-operators.md), [logical](../language-reference/operators/boolean-logical-operators.md), [bitwise and shift](../language-reference/operators/bitwise-and-shift-operators.md) operations and [equality](../language-reference/operators/equality-operators.md) and [order](../language-reference/operators/comparison-operators.md) comparisons.
+
+For the complete list of C# operators ordered by precedence level, see [C# operators](../language-reference/operators/index.md).
+
+## Statements
+
+The actions of a program are expressed using *statements*. C# supports several different kinds of statements, a number of which are defined in terms of embedded statements.
+
+- A *block* permits multiple statements to be written in contexts where a single statement is allowed. A block consists of a list of statements written between the delimiters `{` and `}`.
+- *Declaration statements* are used to declare local variables and constants.
+- *Expression statements* are used to evaluate expressions. Expressions that can be used as statements include method invocations, object allocations using the `new` operator, assignments using `=` and the compound assignment operators, increment and decrement operations using the `++` and `--` operators and `await` expressions.
+- *Selection statements* are used to select one of a number of possible statements for execution based on the value of some expression. This group contains the `if` and `switch` statements.
+- *Iteration statements* are used to execute repeatedly an embedded statement. This group contains the `while`, `do`, `for`, and `foreach` statements.
+- *Jump statements* are used to transfer control. This group contains the `break`, `continue`, `goto`, `throw`, `return`, and `yield` statements.
+- The `try`...`catch` statement is used to catch exceptions that occur during execution of a block, and the `try`...`finally` statement is used to specify finalization code that is always executed, whether an exception occurred or not.
+- The `checked` and `unchecked` statements are used to control the overflow-checking context for integral-type arithmetic operations and conversions.
+- The `lock` statement is used to obtain the mutual-exclusion lock for a given object, execute a statement, and then release the lock.
+- The `using` statement is used to obtain a resource, execute a statement, and then dispose of that resource.
+
+The following lists the kinds of statements that can be used:
+
+* Local variable declaration.
+* Local constant declaration.
+* Expression statement.
+* `if` statement.
+* `switch` statement.
+* `while` statement.
+* `do` statement.
+* `for` statement.
+* `foreach` statement.
+* `break` statement.
+* `continue` statement.
+* `goto` statement.
+* `return` statement.
+* `yield` statement.
+* `throw` statements and `try` statements.
+* `checked` and `unchecked` statements.
+* `lock` statement.
+* `using` statement.
+
+>[!div class="step-by-step"]
+>[Previous](types.md)
+>[Next](features.md)
diff --git a/docs/csharp/tour-of-csharp/program-structure.md b/docs/csharp/tour-of-csharp/program-structure.md
deleted file mode 100644
index afeb04421f7c3..0000000000000
--- a/docs/csharp/tour-of-csharp/program-structure.md
+++ /dev/null
@@ -1,56 +0,0 @@
----
-title: C# Program Structure - A Tour of the C# Language
-description: Learn the basic building blocks of a C# program
-ms.date: 02/25/2020
-ms.assetid: 984f0314-507f-47a0-af56-9011243f5e65
----
-
-# Program Structure
-
-The key organizational concepts in C# are ***programs***, ***namespaces***, ***types***, ***members***, and ***assemblies***. C# programs consist of one or more source files. Programs declare types, which contain members and can be organized into namespaces. Classes and interfaces are examples of types. Fields, methods, properties, and events are examples of members. When C# programs are compiled, they're physically packaged into assemblies. Assemblies typically have the file extension `.exe` or `.dll`, depending on whether they implement ***applications*** or ***libraries***, respectively.
-
-You can create a library project named *acme* using the `dotnet new` command:
-
-```dotnetcli
-dotnet new classlib -o acme
-```
-
-In that project, declare a class named `Stack` in a namespace called `Acme.Collections`:
-
-[!code-csharp[Stack](../../../samples/snippets/csharp/tour/program-structure/program.cs#L1-L34)]
-
-The fully qualified name of this class is `Acme.Collections.Stack`. The class contains several members: a field named `top`, two methods named `Push` and `Pop`, and a nested class named `Entry`. The `Entry` class further contains three members: a field named `next`, a field named `data`, and a constructor. The command:
-
-```dotnetcli
-dotnet build
-```
-
-compiles the example as a library (code without a `Main` entry point) and produces an assembly named `acme.dll`.
-
-Assemblies contain executable code in the form of Intermediate Language (IL) instructions, and symbolic information in the form of metadata. Before it's executed, the Just-In-Time (JIT) compiler of .NET Common Language Runtime converts the IL code in an assembly to processor-specific code.
-
-Because an assembly is a self-describing unit of functionality containing both code and metadata, there's no need for `#include` directives and header files in C#. The public types and members contained in a particular assembly are made available in a C# program simply by referencing that assembly when compiling the program. For example, this program uses the `Acme.Collections.Stack` class from the `acme.dll` assembly:
-
-[!code-csharp[UsingStack](../../../samples/snippets/csharp/tour/program-structure/Program.cs#L38-L52)]
-
-The *csproj* file for the preceding program's project must include a reference node for the C# compiler to resolve references to the classes in the `acme.dll` assembly:
-
-```xml
-
-
-
-```
-
-After that addition, `dotnet build` creates an executable assembly named `example.exe`, which, when run, produces the output:
-
-```dotnetcli
-100
-10
-1
-```
-
-C# permits the source text of a program to be stored in several source files. When a multi-file C# program is compiled, all of the source files are processed together, and the source files can freely reference each other—conceptually, it is as if all the source files were concatenated into one large file before being processed. Forward declarations are never needed in C# because, with few exceptions, declaration order is insignificant. C# does not limit a source file to declaring only one public type nor does it require the name of the source file to match a type declared in the source file.
-
->[!div class="step-by-step"]
->[Previous](index.md)
->[Next](types-and-variables.md)
diff --git a/docs/csharp/tour-of-csharp/snippets/shared/AcmeStack.cs b/docs/csharp/tour-of-csharp/snippets/shared/AcmeStack.cs
new file mode 100644
index 0000000000000..b36528952627f
--- /dev/null
+++ b/docs/csharp/tour-of-csharp/snippets/shared/AcmeStack.cs
@@ -0,0 +1,38 @@
+using System;
+
+namespace Acme.Collections
+{
+ public class Stack
+ {
+ Entry _top;
+
+ public void Push(T data)
+ {
+ _top = new Entry(_top, data);
+ }
+
+ public T Pop()
+ {
+ if (_top == null)
+ {
+ throw new InvalidOperationException();
+ }
+ T result = _top.Data;
+ _top = _top.Next;
+
+ return result;
+ }
+
+ class Entry
+ {
+ public Entry Next { get; set; }
+ public T Data { get; set; }
+
+ public Entry(Entry next, T data)
+ {
+ Next = next;
+ Data = data;
+ }
+ }
+ }
+}
diff --git a/docs/csharp/tour-of-csharp/snippets/shared/ClassesObjects.cs b/docs/csharp/tour-of-csharp/snippets/shared/ClassesObjects.cs
new file mode 100644
index 0000000000000..0f13c56890a0d
--- /dev/null
+++ b/docs/csharp/tour-of-csharp/snippets/shared/ClassesObjects.cs
@@ -0,0 +1,443 @@
+using System;
+using System.Collections.Generic;
+
+namespace Snippets
+{
+ //
+ public class Console
+ {
+ public static void Write(string fmt, params object[] args) { }
+ public static void WriteLine(string fmt, params object[] args) { }
+ // ...
+ }
+ //
+}
+
+namespace TourOfCsharp
+{
+ //
+ public class Color
+ {
+ public static readonly Color Black = new Color(0, 0, 0);
+ public static readonly Color White = new Color(255, 255, 255);
+ public static readonly Color Red = new Color(255, 0, 0);
+ public static readonly Color Green = new Color(0, 255, 0);
+ public static readonly Color Blue = new Color(0, 0, 255);
+
+ public byte R { get; }
+ public byte G { get; }
+ public byte B { get; }
+
+ public Color(byte r, byte g, byte b)
+ {
+ R = r;
+ G = g;
+ B = b;
+ }
+ }
+ //
+
+ //
+ class Squares
+ {
+ public static void WriteSquares()
+ {
+ int i = 0;
+ int j;
+ while (i < 10)
+ {
+ j = i * i;
+ Console.WriteLine($"{i} x {i} = {j}");
+ i = i + 1;
+ }
+ }
+ }
+ //
+
+ //
+ class Entity
+ {
+ static int s_nextSerialNo;
+ int _serialNo;
+
+ public Entity()
+ {
+ _serialNo = s_nextSerialNo++;
+ }
+
+ public int GetSerialNo()
+ {
+ return _serialNo;
+ }
+
+ public static int GetNextSerialNo()
+ {
+ return s_nextSerialNo;
+ }
+
+ public static void SetNextSerialNo(int value)
+ {
+ s_nextSerialNo = value;
+ }
+ }
+ //
+
+ //
+ public abstract class Expression
+ {
+ public abstract double Evaluate(Dictionary vars);
+ }
+
+ public class Constant : Expression
+ {
+ double _value;
+
+ public Constant(double value)
+ {
+ _value = value;
+ }
+
+ public override double Evaluate(Dictionary vars)
+ {
+ return _value;
+ }
+ }
+
+ public class VariableReference : Expression
+ {
+ string _name;
+
+ public VariableReference(string name)
+ {
+ _name = name;
+ }
+
+ public override double Evaluate(Dictionary vars)
+ {
+ object value = vars[_name] ?? throw new Exception($"Unknown variable: {_name}");
+ return Convert.ToDouble(value);
+ }
+ }
+
+ public class Operation : Expression
+ {
+ Expression _left;
+ char _op;
+ Expression _right;
+
+ public Operation(Expression left, char op, Expression right)
+ {
+ _left = left;
+ _op = op;
+ _right = right;
+ }
+
+ public override double Evaluate(Dictionary vars)
+ {
+ double x = _left.Evaluate(vars);
+ double y = _right.Evaluate(vars);
+ switch (_op)
+ {
+ case '+': return x + y;
+ case '-': return x - y;
+ case '*': return x * y;
+ case '/': return x / y;
+
+ default: throw new Exception("Unknown operator");
+ }
+ }
+ }
+ //
+
+ //
+ class OverloadingExample
+ {
+ static void F() => Console.WriteLine("F()");
+ static void F(object x) => Console.WriteLine("F(object)");
+ static void F(int x) => Console.WriteLine("F(int)");
+ static void F(double x) => Console.WriteLine("F(double)");
+ static void F(T x) => Console.WriteLine("F(T)");
+ static void F(double x, double y) => Console.WriteLine("F(double, double)");
+
+ public static void UsageExample()
+ {
+ F(); // Invokes F()
+ F(1); // Invokes F(int)
+ F(1.0); // Invokes F(double)
+ F("abc"); // Invokes F(string)
+ F((double)1); // Invokes F(double)
+ F((object)1); // Invokes F(object)
+ F(1); // Invokes F(int)
+ F(1, 1); // Invokes F(double, double)
+ }
+ //
+ }
+
+ //
+ public class MyList
+ {
+ const int DefaultCapacity = 4;
+
+ T[] _items;
+ int _count;
+
+ public MyList(int capacity = DefaultCapacity)
+ {
+ _items = new T[capacity];
+ }
+
+ public int Count => _count;
+
+ public int Capacity
+ {
+ get => _items.Length;
+ set
+ {
+ if (value < _count) value = _count;
+ if (value != _items.Length)
+ {
+ T[] newItems = new T[value];
+ Array.Copy(_items, 0, newItems, 0, _count);
+ _items = newItems;
+ }
+ }
+ }
+
+ public T this[int index]
+ {
+ get => _items[index];
+ set
+ {
+ _items[index] = value;
+ OnChanged();
+ }
+ }
+
+ public void Add(T item)
+ {
+ if (_count == Capacity) Capacity = _count * 2;
+ _items[_count] = item;
+ _count++;
+ OnChanged();
+ }
+ protected virtual void OnChanged() =>
+ Changed?.Invoke(this, EventArgs.Empty);
+
+ public override bool Equals(object other) =>
+ Equals(this, other as MyList);
+
+ static bool Equals(MyList a, MyList b)
+ {
+ if (Object.ReferenceEquals(a, null)) return Object.ReferenceEquals(b, null);
+ if (Object.ReferenceEquals(b, null) || a._count != b._count)
+ return false;
+ for (int i = 0; i < a._count; i++)
+ {
+ if (!object.Equals(a._items[i], b._items[i]))
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public event EventHandler Changed;
+
+ public static bool operator ==(MyList a, MyList b) =>
+ Equals(a, b);
+
+ public static bool operator !=(MyList a, MyList b) =>
+ !Equals(a, b);
+ }
+ //
+
+ //
+ class EventExample
+ {
+ static int s_changeCount;
+
+ static void ListChanged(object sender, EventArgs e)
+ {
+ s_changeCount++;
+ }
+
+ public static void Usage()
+ {
+ var names = new MyList();
+ names.Changed += new EventHandler(ListChanged);
+ names.Add("Liz");
+ names.Add("Martha");
+ names.Add("Beth");
+ Console.WriteLine(s_changeCount); // "3"
+ }
+ }
+ //
+
+
+ class ClassesObjects
+ {
+ //
+ static void Swap(ref int x, ref int y)
+ {
+ int temp = x;
+ x = y;
+ y = temp;
+ }
+
+ public static void SwapExample()
+ {
+ int i = 1, j = 2;
+ Swap(ref i, ref j);
+ Console.WriteLine($"{i} {j}"); // "2 1"
+ }
+ //
+
+ //
+ static void Divide(int x, int y, out int result, out int remainder)
+ {
+ result = x / y;
+ remainder = x % y;
+ }
+
+ public static void OutUsage()
+ {
+ Divide(10, 3, out int res, out int rem);
+ Console.WriteLine($"{res} {rem}"); // "3 1"
+ }
+ //
+
+ private static void UseParamArgs()
+ {
+ //
+ int x, y, z;
+ x = 3;
+ y = 4;
+ z = 5;
+ Console.WriteLine("x={0} y={1} z={2}", x, y, z);
+ //
+ }
+
+
+ private static void CompilerParams()
+ {
+ //
+ int x = 3, y = 4, z = 5;
+
+ string s = "x={0} y={1} z={2}";
+ object[] args = new object[3];
+ args[0] = x;
+ args[1] = y;
+ args[2] = z;
+ Console.WriteLine(s, args);
+ //
+ }
+
+ private static void UsingEntity()
+ {
+ //
+ Entity.SetNextSerialNo(1000);
+ Entity e1 = new Entity();
+ Entity e2 = new Entity();
+ Console.WriteLine(e1.GetSerialNo()); // Outputs "1000"
+ Console.WriteLine(e2.GetSerialNo()); // Outputs "1001"
+ Console.WriteLine(Entity.GetNextSerialNo()); // Outputs "1002"
+ //
+ }
+
+ private static void UseExpressions()
+ {
+ //
+ Expression e = new Operation(
+ new VariableReference("x"),
+ '+',
+ new Constant(3));
+ //
+ }
+
+ private static void UsingExpressions()
+ {
+ //
+ Expression e = new Operation(
+ new VariableReference("x"),
+ '*',
+ new Operation(
+ new VariableReference("y"),
+ '+',
+ new Constant(2)
+ )
+ );
+ Dictionary vars = new Dictionary();
+ vars["x"] = 3;
+ vars["y"] = 5;
+ Console.WriteLine(e.Evaluate(vars)); // "21"
+ vars["x"] = 1.5;
+ vars["y"] = 9;
+ Console.WriteLine(e.Evaluate(vars)); // "16.5"
+ //
+ }
+
+ private static void ListExampleOne()
+ {
+ //
+ MyList list1 = new MyList();
+ MyList list2 = new MyList(10);
+ //
+
+ //
+ MyList names = new MyList();
+ names.Capacity = 100; // Invokes set accessor
+ int i = names.Count; // Invokes get accessor
+ int j = names.Capacity; // Invokes get accessor
+ //
+ }
+
+ private static void ListAddition()
+ {
+ //
+ MyList a = new MyList();
+ a.Add(1);
+ a.Add(2);
+ MyList b = new MyList();
+ b.Add(1);
+ b.Add(2);
+ Console.WriteLine(a == b); // Outputs "True"
+ b.Add(3);
+ Console.WriteLine(a == b); // Outputs "False"
+ //
+ }
+
+ private static void ListAccess()
+ {
+ //
+ MyList names = new MyList();
+ names.Add("Liz");
+ names.Add("Martha");
+ names.Add("Beth");
+ for (int i = 0; i < names.Count; i++)
+ {
+ string s = names[i];
+ names[i] = s.ToUpper();
+ }
+ //
+ }
+
+
+ public static void Examples()
+ {
+ SwapExample();
+ OutUsage();
+ UseParamArgs();
+ CompilerParams();
+ UsingEntity();
+ UseExpressions();
+ UsingExpressions();
+
+ ListExampleOne();
+ ListAddition();
+ EventExample.Usage();
+ ListAccess();
+
+ }
+
+ }
+}
diff --git a/docs/csharp/tour-of-csharp/snippets/shared/Features.cs b/docs/csharp/tour-of-csharp/snippets/shared/Features.cs
new file mode 100644
index 0000000000000..eccf3efebbc58
--- /dev/null
+++ b/docs/csharp/tour-of-csharp/snippets/shared/Features.cs
@@ -0,0 +1,211 @@
+using System;
+using System.Net.Http;
+using System.Threading.Tasks;
+
+namespace TourOfCsharp
+{
+
+ //
+ delegate double Function(double x);
+
+ class Multiplier
+ {
+ double _factor;
+
+ public Multiplier(double factor) => _factor = factor;
+
+ public double Multiply(double x) => x * _factor;
+ }
+
+ class DelegateExample
+ {
+ static double[] Apply(double[] a, Function f)
+ {
+ var result = new double[a.Length];
+ for (int i = 0; i < a.Length; i++) result[i] = f(a[i]);
+ return result;
+ }
+
+ public static void Main()
+ {
+ double[] a = { 0.0, 0.5, 1.0 };
+ double[] squares = Apply(a, (x) => x * x);
+ double[] sines = Apply(a, Math.Sin);
+ Multiplier m = new Multiplier(2.0);
+ double[] doubles = Apply(a, m.Multiply);
+ }
+ }
+ //
+
+ //
+ public class HelpAttribute : Attribute
+ {
+ string _url;
+ string _topic;
+
+ public HelpAttribute(string url) => _url = url;
+
+ public string Url => _url;
+
+ public string Topic
+ {
+ get => _topic;
+ set => _topic = value;
+ }
+ }
+ //
+
+ //
+ [Help("https://docs.microsoft.com/dotnet/csharp/tour-of-csharp/features")]
+ public class Widget
+ {
+ [Help("https://docs.microsoft.com/dotnet/csharp/tour-of-csharp/features",
+ Topic = "Display")]
+ public void Display(string text) { }
+ }
+ //
+
+
+ class Features
+ {
+ public static void Examples()
+ {
+ ArraysSamples();
+ DeclareArrays();
+ ArrayOfArrays();
+ InitializeArray();
+
+ var weatherData = (Date: DateTime.Now, LowTemp: 5, HighTemp: 30);
+ //
+ Console.WriteLine($"The low and high temperature on {weatherData.Date:MM-DD-YYYY}");
+ Console.WriteLine($" was {weatherData.LowTemp} and {weatherData.HighTemp}.");
+ // Output (similar to):
+ // The low and high temperature on 08-11-2020
+ // was 5 and 30.
+ //
+ DelegateExample.Main();
+
+ ReadAttributes();
+
+ }
+
+ //
+ public async Task RetrieveDocsHomePage()
+ {
+ var client = new HttpClient();
+ byte[] content = await client.GetByteArrayAsync("https://docs.microsoft.com/");
+
+ Console.WriteLine($"{nameof(RetrieveDocsHomePage)}: Finished downloading.");
+ return content.Length;
+ }
+ //
+
+
+ private static void ReadAttributes()
+ {
+ //
+ Type widgetType = typeof(Widget);
+
+ object[] widgetClassAttributes = widgetType.GetCustomAttributes(typeof(HelpAttribute), false);
+
+ if (widgetClassAttributes.Length > 0)
+ {
+ HelpAttribute attr = (HelpAttribute)widgetClassAttributes[0];
+ Console.WriteLine($"Widget class help URL : {attr.Url} - Related topic : {attr.Topic}");
+ }
+
+ System.Reflection.MethodInfo displayMethod = widgetType.GetMethod(nameof(Widget.Display));
+
+ object[] displayMethodAttributes = displayMethod.GetCustomAttributes(typeof(HelpAttribute), false);
+
+ if (displayMethodAttributes.Length > 0)
+ {
+ HelpAttribute attr = (HelpAttribute)displayMethodAttributes[0];
+ Console.WriteLine($"Display method help URL : {attr.Url} - Related topic : {attr.Topic}");
+ }
+ //
+ }
+
+ static double[] Apply(double[] a, Function f)
+ {
+ double[] result = new double[a.Length];
+ for (int i = 0; i < a.Length; i++) result[i] = f(a[i]);
+ return result;
+ }
+
+
+ static void ApplyDelegate()
+ {
+ double[] a = { 0.0, 0.5, 1.0 };
+ //
+ double[] doubles = Apply(a, (double x) => x * 2.0);
+ //
+ }
+
+
+ private static void InitializeArray()
+ {
+ {
+ //
+ int[] a = new int[] { 1, 2, 3 };
+ //
+ }
+ {
+ //
+ int[] a = { 1, 2, 3 };
+ //
+ }
+ {
+ //
+ int[] t = new int[3];
+ t[0] = 1;
+ t[1] = 2;
+ t[2] = 3;
+ int[] a = t;
+ //
+
+ //
+ foreach (int item in a)
+ {
+ Console.WriteLine(item);
+ }
+ //
+ }
+
+ }
+
+ private static void ArrayOfArrays()
+ {
+ //
+ int[][] a = new int[3][];
+ a[0] = new int[10];
+ a[1] = new int[5];
+ a[2] = new int[20];
+ //
+ }
+
+ private static void DeclareArrays()
+ {
+ //
+ int[] a1 = new int[10];
+ int[,] a2 = new int[10, 5];
+ int[,,] a3 = new int[10, 5, 2];
+ //
+ }
+
+ private static void ArraysSamples()
+ {
+ //
+ int[] a = new int[10];
+ for (int i = 0; i < a.Length; i++)
+ {
+ a[i] = i * i;
+ }
+ for (int i = 0; i < a.Length; i++)
+ {
+ Console.WriteLine($"a[{i}] = {a[i]}");
+ }
+ //
+ }
+ }
+}
diff --git a/samples/snippets/csharp/tour/hello/Program.cs b/docs/csharp/tour-of-csharp/snippets/shared/HelloWorld.cs
similarity index 100%
rename from samples/snippets/csharp/tour/hello/Program.cs
rename to docs/csharp/tour-of-csharp/snippets/shared/HelloWorld.cs
diff --git a/docs/csharp/tour-of-csharp/snippets/shared/Program.cs b/docs/csharp/tour-of-csharp/snippets/shared/Program.cs
new file mode 100644
index 0000000000000..76131f68a8a93
--- /dev/null
+++ b/docs/csharp/tour-of-csharp/snippets/shared/Program.cs
@@ -0,0 +1,23 @@
+namespace TourOfCsharp
+{
+ class Program
+ {
+ static void Main(string[] args)
+ {
+ global::Example.Main();
+ Boxing();
+ Types.Examples();
+ ClassesObjects.Examples();
+ Features.Examples();
+ }
+
+ private static void Boxing()
+ {
+ //
+ int i = 123;
+ object o = i; // Boxing
+ int j = (int)o; // Unboxing
+ //
+ }
+ }
+}
diff --git a/docs/csharp/tour-of-csharp/snippets/shared/StackUsage.cs b/docs/csharp/tour-of-csharp/snippets/shared/StackUsage.cs
new file mode 100644
index 0000000000000..fd5b6b53a9730
--- /dev/null
+++ b/docs/csharp/tour-of-csharp/snippets/shared/StackUsage.cs
@@ -0,0 +1,16 @@
+using System;
+using Acme.Collections;
+
+class Example
+{
+ public static void Main()
+ {
+ var s = new Stack();
+ s.Push(1); // stack contains 1
+ s.Push(10); // stack contains 1, 10
+ s.Push(100); // stack contains 1, 10, 100
+ Console.WriteLine(s.Pop()); // stack contains 1, 10
+ Console.WriteLine(s.Pop()); // stack contains 1
+ Console.WriteLine(s.Pop()); // stack is empty
+ }
+}
diff --git a/samples/snippets/csharp/tour/arrays/arrays.csproj b/docs/csharp/tour-of-csharp/snippets/shared/TourOfCsharp.csproj
similarity index 60%
rename from samples/snippets/csharp/tour/arrays/arrays.csproj
rename to docs/csharp/tour-of-csharp/snippets/shared/TourOfCsharp.csproj
index 9acff6d2afa81..5f1457441d0b3 100644
--- a/samples/snippets/csharp/tour/arrays/arrays.csproj
+++ b/docs/csharp/tour-of-csharp/snippets/shared/TourOfCsharp.csproj
@@ -1,8 +1,9 @@
-
+
Exe
netcoreapp3.1
+ TourOfCsharp.Program
diff --git a/docs/csharp/tour-of-csharp/snippets/shared/Types.cs b/docs/csharp/tour-of-csharp/snippets/shared/Types.cs
new file mode 100644
index 0000000000000..b6196fbbfce9a
--- /dev/null
+++ b/docs/csharp/tour-of-csharp/snippets/shared/Types.cs
@@ -0,0 +1,155 @@
+using System;
+using System.Reflection;
+
+namespace DeclareTypes
+{
+ //
+ public struct Point
+ {
+ public double X { get; }
+ public double Y { get; }
+
+ public Point(double x, double y) => (X, Y) = (x, y);
+ }
+ //
+}
+namespace TourOfCsharp
+{
+ //
+ public class Point
+ {
+ public int X { get; }
+ public int Y { get; }
+
+ public Point(int x, int y) => (X, Y) = (x, y);
+ }
+ //
+
+ //
+ public class Pair
+ {
+ public TFirst First { get; }
+ public TSecond Second { get; }
+
+ public Pair(TFirst first, TSecond second) =>
+ (First, Second) = (first, second);
+ }
+ //
+
+ //
+ public class Point3D : Point
+ {
+ public int Z { get; set; }
+
+ public Point3D(int x, int y, int z) : base(x, y)
+ {
+ Z = z;
+ }
+ }
+ //
+
+ //
+ interface IControl
+ {
+ void Paint();
+ }
+
+ interface ITextBox : IControl
+ {
+ void SetText(string text);
+ }
+
+ interface IListBox : IControl
+ {
+ void SetItems(string[] items);
+ }
+
+ interface IComboBox : ITextBox, IListBox { }
+ //
+
+ //
+ interface IDataBound
+ {
+ void Bind(Binder b);
+ }
+
+ public class EditBox : IControl, IDataBound
+ {
+ public void Paint() { }
+ public void Bind(Binder b) { }
+ }
+ //
+
+ //
+ public enum SomeRootVegetables
+ {
+ HorseRadish,
+ Radish,
+ Turnip
+ }
+ //
+
+ //
+ [Flags]
+ public enum Seasons
+ {
+ None = 0,
+ Summer = 1,
+ Autumn = 2,
+ Winter = 4,
+ Spring = 8,
+ All = Summer | Autumn | Winter | Spring
+ }
+ //
+
+
+ public static class Types
+ {
+ public static void Examples()
+ {
+ //
+ var p1 = new Point(0, 0);
+ var p2 = new Point(10, 20);
+ //
+
+ //
+ var pair = new Pair(1, "two");
+ int i = pair.First; // TFirst int
+ string s = pair.Second; // TSecond string
+ //
+
+ //
+ Point a = new Point(10, 20);
+ Point b = new Point3D(10, 20, 30);
+ //
+
+ //
+ EditBox editBox = new EditBox();
+ IControl control = editBox;
+ IDataBound dataBound = editBox;
+ //
+
+ //
+ var turnip = SomeRootVegetables.Turnip;
+
+ var spring = Seasons.Spring;
+ var startingOnEquinox = Seasons.Spring | Seasons.Autumn;
+ var theYear = Seasons.All;
+ //
+
+ //
+ int? optionalInt = default;
+ optionalInt = 5;
+ string? optionalText = default;
+ optionalText = "Hello World.";
+ //
+
+ //
+ (double Sum, int Count) t2 = (4.5, 3);
+ Console.WriteLine($"Sum of {t2.Count} elements is {t2.Sum}.");
+ // Output:
+ // Sum of 3 elements is 4.5.
+ //
+ }
+ }
+}
diff --git a/docs/csharp/tour-of-csharp/statements.md b/docs/csharp/tour-of-csharp/statements.md
deleted file mode 100644
index cbbcd1b954669..0000000000000
--- a/docs/csharp/tour-of-csharp/statements.md
+++ /dev/null
@@ -1,108 +0,0 @@
----
-title: C# Statements - A tour of the C# language
-description: You create the actions of a C# program using statements
-ms.date: 02/27/2020
-ms.assetid: 5409c379-5622-4fae-88b5-1654276ea8d4
----
-
-# Statements
-
-The actions of a program are expressed using *statements*. C# supports several different kinds of statements, a number of which are defined in terms of embedded statements.
-
-A *block* permits multiple statements to be written in contexts where a single statement is allowed. A block consists of a list of statements written between the delimiters `{` and `}`.
-
-*Declaration statements* are used to declare local variables and constants.
-
-*Expression statements* are used to evaluate expressions. Expressions that can be used as statements include method invocations, object allocations using the `new` operator, assignments using `=` and the compound assignment operators, increment and decrement operations using the `++` and `--` operators and `await` expressions.
-
-*Selection statements* are used to select one of a number of possible statements for execution based on the value of some expression. This group contains the `if` and `switch` statements.
-
-*Iteration statements* are used to execute repeatedly an embedded statement. This group contains the `while`, `do`, `for`, and `foreach` statements.
-
-*Jump statements* are used to transfer control. This group contains the `break`, `continue`, `goto`, `throw`, `return`, and `yield` statements.
-
-The `try`...`catch` statement is used to catch exceptions that occur during execution of a block, and the `try`...`finally` statement is used to specify finalization code that is always executed, whether an exception occurred or not.
-
-The `checked` and `unchecked` statements are used to control the overflow-checking context for integral-type arithmetic operations and conversions.
-
-The `lock` statement is used to obtain the mutual-exclusion lock for a given object, execute a statement, and then release the lock.
-
-The `using` statement is used to obtain a resource, execute a statement, and then dispose of that resource.
-
-The following lists the kinds of statements that can be used, and provides an example for each.
-
-* Local variable declaration:
-
- [!code-csharp[Declarations](../../../samples/snippets/csharp/tour/statements/Program.cs#L9-L15)]
-
-* Local constant declaration:
-
- [!code-csharp[ConstantDeclarations](../../../samples/snippets/csharp/tour/statements/Program.cs#L17-L22)]
-
-* Expression statement:
-
- [!code-csharp[Expressions](../../../samples/snippets/csharp/tour/statements/Program.cs#L24-L31)]
-
-* `if` statement:
-
- [!code-csharp[IfStatement](../../../samples/snippets/csharp/tour/statements/Program.cs#L33-L43)]
-
-* `switch` statement:
-
- [!code-csharp[SwitchStatement](../../../samples/snippets/csharp/tour/statements/Program.cs#L45-L60)]
-
-* `while` statement:
-
- [!code-csharp[WhileStatement](../../../samples/snippets/csharp/tour/statements/Program.cs#L62-L70)]
-
-* `do` statement:
-
- [!code-csharp[DoStatement](../../../samples/snippets/csharp/tour/statements/Program.cs#L72-L81)]
-
-* `for` statement:
-
- [!code-csharp[ForStatement](../../../samples/snippets/csharp/tour/statements/Program.cs#L83-L89)]
-
-* `foreach` statement:
-
- [!code-csharp[ForEachStatement](../../../samples/snippets/csharp/tour/statements/Program.cs#L91-L97)]
-
-* `break` statement:
-
- [!code-csharp[BreakStatement](../../../samples/snippets/csharp/tour/statements/Program.cs#L99-L108)]
-
-* `continue` statement:
-
- [!code-csharp[ContinueStatement](../../../samples/snippets/csharp/tour/statements/Program.cs#L110-L118)]
-
-* `goto` statement:
-
- [!code-csharp[GotoStatement](../../../samples/snippets/csharp/tour/statements/Program.cs#L120-L129)]
-
-* `return` statement:
-
- [!code-csharp[ReturnStatement](../../../samples/snippets/csharp/tour/statements/Program.cs#L131-L139)]
-
-* `yield` statement:
-
- [!code-csharp[YieldStatement](../../../samples/snippets/csharp/tour/statements/Program.cs#L141-L155)]
-
-* `throw` statements and `try` statements:
-
- [!code-csharp[TryThrow](../../../samples/snippets/csharp/tour/statements/Program.cs#L157-L183)]
-
-* `checked` and `unchecked` statements:
-
- [!code-csharp[CheckedUncheckedStatement](../../../samples/snippets/csharp/tour/statements/Program.cs#L185-L196)]
-
-* `lock` statement:
-
- [!code-csharp[LockStatement](../../../samples/snippets/csharp/tour/statements/Program.cs#L257-L273)]
-
-* `using` statement:
-
- [!code-csharp[UsingStatement](../../../samples/snippets/csharp/tour/statements/Program.cs#L198-L206)]
-
->[!div class="step-by-step"]
->[Previous](expressions.md)
->[Next](classes-and-objects.md)
diff --git a/docs/csharp/tour-of-csharp/types-and-variables.md b/docs/csharp/tour-of-csharp/types-and-variables.md
deleted file mode 100644
index 3682fa4c8358b..0000000000000
--- a/docs/csharp/tour-of-csharp/types-and-variables.md
+++ /dev/null
@@ -1,107 +0,0 @@
----
-title: C# Types and Variables - A tour of the C# language
-description: Learn about defining types and declaring variables in C#
-ms.date: 04/24/2020
-ms.assetid: f8a8051e-0049-43f1-b594-9c84cc7b1224
----
-
-# Types and variables
-
-There are two kinds of types in C#: *value types* and *reference types*. Variables of value types directly contain their data whereas variables of reference types store references to their data, the latter being known as objects. With reference types, it's possible for two variables to reference the same object and thus possible for operations on one variable to affect the object referenced by the other variable. With value types, the variables each have their own copy of the data, and it isn't possible for operations on one to affect the other (except for `ref` and `out` parameter variables).
-
-C#'s value types are further divided into *simple types*, *enum types*, *struct types*, and *nullable value types*. C#'s reference types are further divided into *class types*, *interface types*, *array types*, and *delegate types*.
-
-The following outline provides an overview of C#'s type system.
-
-- [Value types][ValueTypes]
- - [Simple types][SimpleTypes]
- - Signed integral: `sbyte`, `short`, `int`, `long`
- - Unsigned integral: `byte`, `ushort`, `uint`, `ulong`
- - Unicode characters: `char`
- - IEEE binary floating-point: `float`, `double`
- - High-precision decimal floating-point: `decimal`
- - Boolean: `bool`
- - [Enum types][EnumTypes]
- - User-defined types of the form `enum E {...}`
- - [Struct types][StructTypes]
- - User-defined types of the form `struct S {...}`
- - [Nullable value types][NullableTypes]
- - Extensions of all other value types with a `null` value
- - [Tuple value types][TupleTypes]
- - User-defined types of the form `(T1, T2, ...)`
-- [Reference types][ReferenceTypes]
- - [Class types][ClassTypes]
- - Ultimate base class of all other types: `object`
- - Unicode strings: `string`
- - User-defined types of the form `class C {...}`
- - [Interface types][InterfaceTypes]
- - User-defined types of the form `interface I {...}`
- - [Array types][ArrayTypes]
- - Single- and multi-dimensional, for example, `int[]` and `int[,]`
- - [Delegate types][DelegateTypes]
- - User-defined types of the form `delegate int D(...)`
-
-[ValueTypes]: ../language-reference/builtin-types/value-types.md
-[SimpleTypes]: ../language-reference/builtin-types/value-types.md#built-in-value-types
-[EnumTypes]: ../language-reference/builtin-types/enum.md
-[StructTypes]: ../language-reference/builtin-types/struct.md
-[NullableTypes]: ../language-reference/builtin-types/nullable-value-types.md
-[TupleTypes]: ../language-reference/builtin-types/value-tuples.md
-[ReferenceTypes]: ../language-reference/keywords/reference-types.md
-[ClassTypes]: ../language-reference/keywords/class.md
-[InterfaceTypes]: ../language-reference/keywords/interface.md
-[DelegateTypes]: ../language-reference/keywords/delegate.md
-[ArrayTypes]: ../programming-guide/arrays/index.md
-
-For more information about numeric types, see [Integral types](../language-reference/builtin-types/integral-numeric-types.md) and [Floating-point types table](../language-reference/builtin-types/floating-point-numeric-types.md).
-
-C#'s `bool` type is used to represent Boolean values—values that are either `true` or `false`.
-
-Character and string processing in C# uses Unicode encoding. The `char` type represents a UTF-16 code unit, and the `string` type represents a sequence of UTF-16 code units.
-
-C# programs use *type declarations* to create new types. A type declaration specifies the name and the members of the new type. Five of C#'s categories of types are user-definable: class types, struct types, interface types, enum types, and delegate types.
-
-A `class` type defines a data structure that contains data members (fields) and function members (methods, properties, and others). Class types support single inheritance and polymorphism, mechanisms whereby derived classes can extend and specialize base classes.
-
-A `struct` type is similar to a class type in that it represents a structure with data members and function members. However, unlike classes, structs are value types and don't typically require heap allocation. Struct types don't support user-specified inheritance, and all struct types implicitly inherit from type `object`.
-
-An `interface` type defines a contract as a named set of public function members. A `class` or `struct` that implements an `interface` must provide implementations of the interface's function members. An `interface` may inherit from multiple base interfaces, and a `class` or `struct` may implement multiple interfaces.
-
-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 analogous to function types provided by functional languages. They're also similar to the concept of function pointers found in some other languages. Unlike function pointers, delegates are object-oriented and type-safe.
-
-The `class`, `struct`, `interface`, and `delegate` types all support generics, whereby they can be parameterized with other types.
-
-An `enum` type is a distinct type with named constants. Every `enum` type has an underlying type, which must be one of the eight integral types. The set of values of an `enum` type is the same as the set of values of the underlying type.
-
-C# supports single- and multi-dimensional arrays of any type. Unlike the types listed above, array types don't have to be declared before they can be used. Instead, array types are constructed by following a type name with square brackets. For example, `int[]` is a single-dimensional array of `int`, `int[,]` is a two-dimensional array of `int`, and `int[][]` is a single-dimensional array of single-dimensional array of `int`.
-
-Nullable value types also don't have to be declared before they can be used. For each non-nullable value type `T`, there is a corresponding nullable value type `T?`, which can hold an additional value, `null`. For instance, `int?` is a type that can hold any 32-bit integer or the value `null`.
-
-C#'s type system is unified such that a value of any type can be treated as an `object`. Every type in C# directly or indirectly derives from the `object` class type, and `object` is the ultimate base class of all types. Values of reference types are treated as objects simply by viewing the values as type `object`. Values of value types are treated as objects by performing *boxing* and *unboxing operations*. In the following example, an `int` value is converted to `object` and back again to `int`.
-
-[!code-csharp[Boxing](../../../samples/snippets/csharp/tour/types-and-variables/Program.cs#L1-L10)]
-
-When a value of a value type is assigned to an `object` reference, a "box" is allocated to hold the value. That box is an instance of a reference type, and the value is copied into that box. Conversely, when an `object` reference is cast to a value type, a check is made that the referenced `object` is a box of the correct value type. If the check succeeds, the value in the box is copied to the value type.
-
-C#'s unified type system effectively means that value types are treated as `object` references "on demand." Because of the unification, general-purpose libraries that use type `object` can be used with all types that derive from `object`, including both reference types and value types.
-
-There are several kinds of *variables* in C#, including fields, array elements, local variables, and parameters. Variables represent storage locations, and every variable has a type that determines what values can be stored in the variable, as shown below.
-
-- Non-nullable value type
- - A value of that exact type
-- Nullable value type
- - A `null` value or a value of that exact type
-- object
- - A `null` reference, a reference to an object of any reference type, or a reference to a boxed value of any value type
-- Class type
- - A `null` reference, a reference to an instance of that class type, or a reference to an instance of a class derived from that class type
-- Interface type
- - A `null` reference, a reference to an instance of a class type that implements that interface type, or a reference to a boxed value of a value type that implements that interface type
-- Array type
- - A `null` reference, a reference to an instance of that array type, or a reference to an instance of a compatible array type
-- Delegate type
- - A `null` reference or a reference to an instance of a compatible delegate type
-
-> [!div class="step-by-step"]
-> [Previous](program-structure.md)
-> [Next](expressions.md)
diff --git a/docs/csharp/tour-of-csharp/types.md b/docs/csharp/tour-of-csharp/types.md
new file mode 100644
index 0000000000000..ecc47860558f0
--- /dev/null
+++ b/docs/csharp/tour-of-csharp/types.md
@@ -0,0 +1,108 @@
+---
+title: Define types and their members - A tour of C#
+description: The building blocks of programs are types. Learn how to create classes, structs, interfaces, and more in C#.
+ms.date: 08/06/2020
+---
+# Types and members
+
+## Classes and objects
+
+*Classes* are the most fundamental of C#’s types. A class is a data structure that combines state (fields) and actions (methods and other function members) in a single unit. A class provides a definition for *instances* of the class, also known as *objects*. Classes support *inheritance* and *polymorphism*, mechanisms whereby *derived classes* can extend and specialize *base classes*.
+
+New classes are created using class declarations. A class declaration starts with a header. The header specifies:
+
+- The attributes and modifiers of the class
+- The name of the class
+- The base class (when inheriting from a [base class](#base-classes))
+- The interfaces implemented by the class.
+
+The header is followed by the class body, which consists of a list of member declarations written between the delimiters `{` and `}`.
+
+The following code shows a declaration of a simple class named `Point`:
+
+:::code language="csharp" source="./snippets/shared/Types.cs" ID="PointClass":::
+
+Instances of classes are created using the `new` operator, which allocates memory for a new instance, invokes a constructor to initialize the instance, and returns a reference to the instance. The following statements create two `Point` objects and store references to those objects in two variables:
+
+:::code language="csharp" source="./snippets/shared/Types.cs" ID="CreatePoints":::
+
+The memory occupied by an object is automatically reclaimed when the object is no longer reachable. It's neither necessary nor possible to explicitly deallocate objects in C#.
+
+### Type parameters
+
+Generic classes define [***type parameters***](../programming-guide/generics/index.md). Type parameters are a list of type parameter names enclosed in angle brackets. Type parameters follow the class name. The type parameters can then be used in the body of the class declarations to define the members of the class. In the following example, the type parameters of `Pair` are `TFirst` and `TSecond`:
+
+:::code language="csharp" source="./snippets/shared/Types.cs" ID="DefinePairClass":::
+
+A class type that is declared to take type parameters is called a *generic class type*. Struct, interface, and delegate types can also be generic.
+When the generic class is used, type arguments must be provided for each of the type parameters:
+
+:::code language="csharp" source="./snippets/shared/Types.cs" ID="CreatePairObject":::
+
+A generic type with type arguments provided, like `Pair` above, is called a *constructed type*.
+
+### Base classes
+
+A class declaration may specify a base class. Follow the class name and type parameters with a colon and the name of the base class. Omitting a base class specification is the same as deriving from type `object`. In the following example, the base class of `Point3D` is `Point`. From the first example, the base class of `Point` is `object`:
+
+:::code language="csharp" source="./snippets/shared/Types.cs" ID="Create3DPoint":::
+
+A class inherits the members of its base class. Inheritance means that a class implicitly contains almost all members of its base class. A class doesn't inherit the instance and static constructors, and the finalizer. A derived class can add new members to those members it inherits, but it can't remove the definition of an inherited member. In the previous example, `Point3D` inherits the `X` and `Y` members from `Point`, and every `Point3D` instance contains three properties, `X`, `Y`, and `Z`.
+
+An implicit conversion exists from a class type to any of its base class types. A variable of a class type can reference an instance of that class or an instance of any derived class. For example, given the previous class declarations, a variable of type `Point` can reference either a `Point` or a `Point3D`:
+
+:::code language="csharp" source="./snippets/shared/Types.cs" ID="ImplicitCastToBase":::
+
+## Structs
+
+Classes define types that support inheritance and polymorphism. They enable you to create sophisticated behaviors based on hierarchies of derived classes. By contrast, [***struct***](../language-reference/builtin-types/struct.md) types are simpler types whose primary purpose is to store data values. Structs can't declare a base type; they implicitly derive from . You can't derive other `struct` types from a `struct` type. They're implicitly sealed.
+
+:::code language="csharp" source="./snippets/shared/Types.cs" ID="PointStruct":::
+
+## Interfaces
+
+An [***interface***](../programming-guide/interfaces/index.md) defines a contract that can be implemented by classes and structs. An interface can contain methods, properties, events, and indexers. An interface typically doesn't provide implementations of the members it defines—it merely specifies the members that must be supplied by classes or structs that implement the interface.
+
+Interfaces may employ ***multiple inheritance***. In the following example, the interface `IComboBox` inherits from both `ITextBox` and `IListBox`.
+
+:::code language="csharp" source="./snippets/shared/Types.cs" ID="FirstInterfaces":::
+
+Classes and structs can implement multiple interfaces. In the following example, the class `EditBox` implements both `IControl` and `IDataBound`.
+
+:::code language="csharp" source="./snippets/shared/Types.cs" ID="ImplementInterfaces":::
+
+When a class or struct implements a particular interface, instances of that class or struct can be implicitly converted to that interface type. For example
+
+:::code language="csharp" source="./snippets/shared/Types.cs" ID="UseInterfaces":::
+
+## Enums
+
+An [***Enum***](../language-reference/builtin-types/enum.md) type defines a set of constant values. The following `enum` declares constants that define different root vegetables:
+
+:::code language="csharp" source="./snippets/shared/Types.cs" ID="EnumDeclaration":::
+
+You can also define an `enum` to be used in combination as flags. The following declaration declares a set of flags for the four seasons. Any combination of the seasons may be applied, including an `All` value that includes all seasons:
+
+:::code language="csharp" source="./snippets/shared/Types.cs" ID="FlagsEnumDeclaration":::
+
+The following example shows declarations of both the preceding enums:
+
+:::code language="csharp" source="./snippets/shared/Types.cs" ID="UsingEnums":::
+
+## Nullable types
+
+Variables of any type may be declared as ***non-nullable*** or ***nullable***. A nullable variable can hold an additional `null` value, indicating no value. Nullable Value types (structs or enums) are represented by . Non-nullable and Nullable Reference types are both represented by the underlying reference type. The distinction is represented by metadata read by the compiler and some libraries. The compiler provides warnings when nullable references are dereferenced without first checking their value against `null`. The compiler also provides warnings when non-nullable references are assigned to a value that may be `null`. The following example declares a ***nullable int***, initializing it to `null`. Then, it sets the value to `5`. It demonstrates the same concept with a ***nullable string***. For more information, see [nullable value types](../language-reference/builtin-types/nullable-value-types.md) and [nullable reference types](../nullable-references.md).
+
+:::code language="csharp" source="./snippets/shared/Types.cs" ID="DeclareNullable":::
+
+## Tuples
+
+C# supports [***tuples***](../language-reference/builtin-types/value-tuples.md), which provides concise syntax to group multiple data elements in a lightweight data structure. You instantiate a tuple by declaring the types and names of the members between `(` and `)`, as shown in the following example:
+
+:::code language="csharp" source="./snippets/shared/Types.cs" ID="DeclareTuples":::
+
+Tuples provide an alternative for data structure with multiple members, without using the building blocks described in the next article.
+
+>[!div class="step-by-step"]
+>[Previous](index.md)
+>[Next](program-building-blocks.md)
diff --git a/docs/csharp/tutorials/inheritance.md b/docs/csharp/tutorials/inheritance.md
index 8fd3efe9580a8..4725a92209ccc 100644
--- a/docs/csharp/tutorials/inheritance.md
+++ b/docs/csharp/tutorials/inheritance.md
@@ -291,5 +291,4 @@ The following example uses objects derived from `Shape`. It instantiates an arra
## See also
-- [Classes and objects](../tour-of-csharp/classes-and-objects.md)
- [Inheritance (C# Programming Guide)](../programming-guide/classes-and-structs/inheritance.md)
diff --git a/samples/snippets/csharp/tour/arrays/Program.cs b/samples/snippets/csharp/tour/arrays/Program.cs
deleted file mode 100644
index c5f4f90aa9cf0..0000000000000
--- a/samples/snippets/csharp/tour/arrays/Program.cs
+++ /dev/null
@@ -1,56 +0,0 @@
-namespace ArraySample
-{
- using System;
- class ArrayExample
- {
- static void Main()
- {
- int[] a = new int[10];
- for (int i = 0; i < a.Length; i++)
- {
- a[i] = i * i;
- }
- for (int i = 0; i < a.Length; i++)
- {
- Console.WriteLine($"a[{i}] = {a[i]}");
- }
- }
- }
-
- class SampleCode
- {
- static void ExampleOne()
- {
- int[] a1 = new int[10];
- int[,] a2 = new int[10, 5];
- int[,,] a3 = new int[10, 5, 2];
- }
-
- static void ExampleTwo()
- {
- int[][] a = new int[3][];
- a[0] = new int[10];
- a[1] = new int[5];
- a[2] = new int[20];
- }
-
- static void ExampleThree()
- {
- int[] a = new int[] {1, 2, 3};
- }
-
- static void ExampleFour()
- {
- int[] a = {1, 2, 3};
- }
-
- static void ExampleFive()
- {
- int[] t = new int[3];
- t[0] = 1;
- t[1] = 2;
- t[2] = 3;
- int[] a = t;
- }
- }
-}
diff --git a/samples/snippets/csharp/tour/arrays/access-by-line.txt b/samples/snippets/csharp/tour/arrays/access-by-line.txt
deleted file mode 100644
index 06b7ddbca1f5c..0000000000000
--- a/samples/snippets/csharp/tour/arrays/access-by-line.txt
+++ /dev/null
@@ -1 +0,0 @@
-Program.cs: ~/docs/csharp/tour-of-csharp/arrays.md
diff --git a/samples/snippets/csharp/tour/attributes/Program.cs b/samples/snippets/csharp/tour/attributes/Program.cs
deleted file mode 100644
index 343feb80d97e0..0000000000000
--- a/samples/snippets/csharp/tour/attributes/Program.cs
+++ /dev/null
@@ -1,61 +0,0 @@
-namespace AttributeSample
-{
- using System;
-
- public class HelpAttribute: Attribute
- {
- string url;
- string topic;
- public HelpAttribute(string url)
- {
- this.url = url;
- }
-
- public string Url => url;
-
- public string Topic {
- get { return topic; }
- set { topic = value; }
- }
- }
-
- [Help("https://docs.microsoft.com/dotnet/csharp/tour-of-csharp/attributes")]
- public class Widget
- {
- [Help("https://docs.microsoft.com/dotnet/csharp/tour-of-csharp/attributes",
- Topic = "Display")]
- public void Display(string text) {}
- }
-
- public class Program
- {
- public static void Main(string[] args)
- {
- //
- Type widgetType = typeof(Widget);
-
- //Gets every HelpAttribute defined for the Widget type
- object[] widgetClassAttributes = widgetType.GetCustomAttributes(typeof(HelpAttribute), false);
-
- if (widgetClassAttributes.Length > 0)
- {
- HelpAttribute attr = (HelpAttribute)widgetClassAttributes[0];
- Console.WriteLine($"Widget class help URL : {attr.Url} - Related topic : {attr.Topic}");
- }
-
- System.Reflection.MethodInfo displayMethod = widgetType.GetMethod(nameof(Widget.Display));
-
- //Gets every HelpAttribute defined for the Widget.Display method
- object[] displayMethodAttributes = displayMethod.GetCustomAttributes(typeof(HelpAttribute), false);
-
- if (displayMethodAttributes.Length > 0)
- {
- HelpAttribute attr = (HelpAttribute)displayMethodAttributes[0];
- Console.WriteLine($"Display method help URL : {attr.Url} - Related topic : {attr.Topic}");
- }
-
- Console.ReadLine();
- //
- }
- }
-}
diff --git a/samples/snippets/csharp/tour/attributes/access-by-line.txt b/samples/snippets/csharp/tour/attributes/access-by-line.txt
deleted file mode 100644
index 6e06a08dd8ecb..0000000000000
--- a/samples/snippets/csharp/tour/attributes/access-by-line.txt
+++ /dev/null
@@ -1 +0,0 @@
-Program.cs: ~/docs/csharp/tour-of-csharp/attributes.md
diff --git a/samples/snippets/csharp/tour/attributes/attributes.csproj b/samples/snippets/csharp/tour/attributes/attributes.csproj
deleted file mode 100644
index 9acff6d2afa81..0000000000000
--- a/samples/snippets/csharp/tour/attributes/attributes.csproj
+++ /dev/null
@@ -1,8 +0,0 @@
-
-
-
- Exe
- netcoreapp3.1
-
-
-
diff --git a/samples/snippets/csharp/tour/classes-and-objects/Color.cs b/samples/snippets/csharp/tour/classes-and-objects/Color.cs
deleted file mode 100644
index a1278407e2626..0000000000000
--- a/samples/snippets/csharp/tour/classes-and-objects/Color.cs
+++ /dev/null
@@ -1,18 +0,0 @@
-namespace ClassesAndObjects
-{
- public class Color
- {
- public static readonly Color Black = new Color(0, 0, 0);
- public static readonly Color White = new Color(255, 255, 255);
- public static readonly Color Red = new Color(255, 0, 0);
- public static readonly Color Green = new Color(0, 255, 0);
- public static readonly Color Blue = new Color(0, 0, 255);
- private byte r, g, b;
- public Color(byte r, byte g, byte b)
- {
- this.r = r;
- this.g = g;
- this.b = b;
- }
- }
-}
diff --git a/samples/snippets/csharp/tour/classes-and-objects/Entity.cs b/samples/snippets/csharp/tour/classes-and-objects/Entity.cs
deleted file mode 100644
index f6e911da8ce95..0000000000000
--- a/samples/snippets/csharp/tour/classes-and-objects/Entity.cs
+++ /dev/null
@@ -1,37 +0,0 @@
-namespace ClassesAndObjects
-{
- using System;
- class EntityExample
- {
- public static void Usage()
- {
- Entity.SetNextSerialNo(1000);
- Entity e1 = new Entity();
- Entity e2 = new Entity();
- Console.WriteLine(e1.GetSerialNo()); // Outputs "1000"
- Console.WriteLine(e2.GetSerialNo()); // Outputs "1001"
- Console.WriteLine(Entity.GetNextSerialNo()); // Outputs "1002"
- }
- }
- class Entity
- {
- static int nextSerialNo;
- int serialNo;
- public Entity()
- {
- serialNo = nextSerialNo++;
- }
- public int GetSerialNo()
- {
- return serialNo;
- }
- public static int GetNextSerialNo()
- {
- return nextSerialNo;
- }
- public static void SetNextSerialNo(int value)
- {
- nextSerialNo = value;
- }
- }
-}
\ No newline at end of file
diff --git a/samples/snippets/csharp/tour/classes-and-objects/Expressions.cs b/samples/snippets/csharp/tour/classes-and-objects/Expressions.cs
deleted file mode 100644
index f3c2ee5c12c26..0000000000000
--- a/samples/snippets/csharp/tour/classes-and-objects/Expressions.cs
+++ /dev/null
@@ -1,90 +0,0 @@
-namespace ClassesAndObjects
-{
- using System;
- using System.Collections.Generic;
- public abstract class Expression
- {
- public abstract double Evaluate(Dictionary vars);
- }
- public class Constant: Expression
- {
- double value;
- public Constant(double value)
- {
- this.value = value;
- }
- public override double Evaluate(Dictionary vars)
- {
- return value;
- }
- }
- public class VariableReference: Expression
- {
- string name;
- public VariableReference(string name)
- {
- this.name = name;
- }
- public override double Evaluate(Dictionary vars)
- {
- object value = vars[name];
- if (value == null)
- {
- throw new Exception("Unknown variable: " + name);
- }
- return Convert.ToDouble(value);
- }
- }
- public class Operation: Expression
- {
- Expression left;
- char op;
- Expression right;
- public Operation(Expression left, char op, Expression right)
- {
- this.left = left;
- this.op = op;
- this.right = right;
- }
- public override double Evaluate(Dictionary vars)
- {
- double x = left.Evaluate(vars);
- double y = right.Evaluate(vars);
- switch (op) {
- case '+': return x + y;
- case '-': return x - y;
- case '*': return x * y;
- case '/': return x / y;
- }
- throw new Exception("Unknown operator");
- }
- }
-}
-
-namespace ClassesAndObjects
-{
- using System;
- using System.Collections.Generic;
- class InheritanceExample
- {
- public static void ExampleUsage()
- {
- Expression e = new Operation(
- new VariableReference("x"),
- '*',
- new Operation(
- new VariableReference("y"),
- '+',
- new Constant(2)
- )
- );
- Dictionary vars = new Dictionary();
- vars["x"] = 3;
- vars["y"] = 5;
- Console.WriteLine(e.Evaluate(vars)); // Outputs "21"
- vars["x"] = 1.5;
- vars["y"] = 9;
- Console.WriteLine(e.Evaluate(vars)); // Outputs "16.5"
- }
- }
-}
\ No newline at end of file
diff --git a/samples/snippets/csharp/tour/classes-and-objects/ListBasedExamples.cs b/samples/snippets/csharp/tour/classes-and-objects/ListBasedExamples.cs
deleted file mode 100644
index a11a133134bb5..0000000000000
--- a/samples/snippets/csharp/tour/classes-and-objects/ListBasedExamples.cs
+++ /dev/null
@@ -1,149 +0,0 @@
-namespace ListExamples
-{
- using System;
- public class MyList
- {
- // Constant
- const int defaultCapacity = 4;
-
- // Fields
- T[] items;
- int count;
-
- // Constructor
- public MyList(int capacity = defaultCapacity)
- {
- items = new T[capacity];
- }
-
- // Properties
- public int Count => count;
-
- public int Capacity
- {
- get { return items.Length; }
- set
- {
- if (value < count) value = count;
- if (value != items.Length)
- {
- T[] newItems = new T[value];
- Array.Copy(items, 0, newItems, 0, count);
- items = newItems;
- }
- }
- }
-
- // Indexer
- public T this[int index]
- {
- get
- {
- return items[index];
- }
- set
- {
- items[index] = value;
- OnChanged();
- }
- }
-
- // Methods
- public void Add(T item)
- {
- if (count == Capacity) Capacity = count * 2;
- items[count] = item;
- count++;
- OnChanged();
- }
- protected virtual void OnChanged() =>
- Changed?.Invoke(this, EventArgs.Empty);
-
- public override bool Equals(object other) =>
- Equals(this, other as MyList);
-
- static bool Equals(MyList a, MyList b)
- {
- if (Object.ReferenceEquals(a, null)) return Object.ReferenceEquals(b, null);
- if (Object.ReferenceEquals(b, null) || a.count != b.count)
- return false;
- for (int i = 0; i < a.count; i++)
- {
- if (!object.Equals(a.items[i], b.items[i]))
- {
- return false;
- }
- }
- return true;
- }
-
- // Event
- public event EventHandler Changed;
-
- // Operators
- public static bool operator ==(MyList a, MyList b) =>
- Equals(a, b);
-
- public static bool operator !=(MyList a, MyList b) =>
- !Equals(a, b);
- }
-
- public class ExampleCode
- {
- public static void ListExampleOne()
- {
- MyList list1 = new MyList();
- MyList list2 = new MyList(10);
- }
-
- public static void ListExampleTwo()
- {
- MyList names = new MyList();
- names.Capacity = 100; // Invokes set accessor
- int i = names.Count; // Invokes get accessor
- int j = names.Capacity; // Invokes get accessor
- }
-
- public static void ListExampleThree()
- {
- MyList names = new MyList();
- names.Add("Liz");
- names.Add("Martha");
- names.Add("Beth");
- for (int i = 0; i < names.Count; i++)
- {
- string s = names[i];
- names[i] = s.ToUpper();
- }
- }
- public static void ListExampleFour()
- {
- MyList a = new MyList();
- a.Add(1);
- a.Add(2);
- MyList b = new MyList();
- b.Add(1);
- b.Add(2);
- Console.WriteLine(a == b); // Outputs "True"
- b.Add(3);
- Console.WriteLine(a == b); // Outputs "False"
- }
- }
- class EventExample
- {
- static int changeCount;
- static void ListChanged(object sender, EventArgs e)
- {
- changeCount++;
- }
- public static void Usage()
- {
- MyList names = new MyList();
- names.Changed += new EventHandler(ListChanged);
- names.Add("Liz");
- names.Add("Martha");
- names.Add("Beth");
- Console.WriteLine(changeCount); // Outputs "3"
- }
- }
-}
\ No newline at end of file
diff --git a/samples/snippets/csharp/tour/classes-and-objects/OutExample.cs b/samples/snippets/csharp/tour/classes-and-objects/OutExample.cs
deleted file mode 100644
index 998135fb3d8a6..0000000000000
--- a/samples/snippets/csharp/tour/classes-and-objects/OutExample.cs
+++ /dev/null
@@ -1,17 +0,0 @@
-namespace ClassesAndObjects
-{
- using System;
- class OutExample
- {
- static void Divide(int x, int y, out int result, out int remainder)
- {
- result = x / y;
- remainder = x % y;
- }
- public static void OutUsage()
- {
- Divide(10, 3, out int res, out int rem);
- Console.WriteLine("{0} {1}", res, rem); // Outputs "3 1"
- }
- }
-}
diff --git a/samples/snippets/csharp/tour/classes-and-objects/Overloading.cs b/samples/snippets/csharp/tour/classes-and-objects/Overloading.cs
deleted file mode 100644
index 0866c39913f39..0000000000000
--- a/samples/snippets/csharp/tour/classes-and-objects/Overloading.cs
+++ /dev/null
@@ -1,43 +0,0 @@
-namespace ClassesAndObjects
-{
- using System;
- class OverloadingExample
- {
- static void F()
- {
- Console.WriteLine("F()");
- }
- static void F(object x)
- {
- Console.WriteLine("F(object)");
- }
- static void F(int x)
- {
- Console.WriteLine("F(int)");
- }
- static void F(double x)
- {
- Console.WriteLine("F(double)");
- }
- static void F(T x)
- {
- Console.WriteLine("F(T)");
- }
- static void F(double x, double y)
- {
- Console.WriteLine("F(double, double)");
- }
- public static void UsageExample()
- {
- F(); // Invokes F()
- F(1); // Invokes F(int)
- F(1.0); // Invokes F(double)
- F("abc"); // Invokes F(string)
- F((double)1); // Invokes F(double)
- F((object)1); // Invokes F(object)
- F(1); // Invokes F(int)
- F(1, 1); // Invokes F(double, double)
- }
- }
-
-}
\ No newline at end of file
diff --git a/samples/snippets/csharp/tour/classes-and-objects/Pair.cs b/samples/snippets/csharp/tour/classes-and-objects/Pair.cs
deleted file mode 100644
index ce091cd72d8dd..0000000000000
--- a/samples/snippets/csharp/tour/classes-and-objects/Pair.cs
+++ /dev/null
@@ -1,8 +0,0 @@
-namespace ClassesAndObjects
-{
- public class Pair
- {
- public TFirst First;
- public TSecond Second;
- }
-}
\ No newline at end of file
diff --git a/samples/snippets/csharp/tour/classes-and-objects/Point.cs b/samples/snippets/csharp/tour/classes-and-objects/Point.cs
deleted file mode 100644
index 2e83b13b6fc53..0000000000000
--- a/samples/snippets/csharp/tour/classes-and-objects/Point.cs
+++ /dev/null
@@ -1,21 +0,0 @@
-namespace ClassesAndObjects
-{
- public class Point
- {
- public int x, y;
- public Point(int x, int y)
- {
- this.x = x;
- this.y = y;
- }
- }
- public class Point3D: Point
- {
- public int z;
- public Point3D(int x, int y, int z) :
- base(x, y)
- {
- this.z = z;
- }
- }
-}
\ No newline at end of file
diff --git a/samples/snippets/csharp/tour/classes-and-objects/Program.cs b/samples/snippets/csharp/tour/classes-and-objects/Program.cs
deleted file mode 100644
index dd7ab6425d886..0000000000000
--- a/samples/snippets/csharp/tour/classes-and-objects/Program.cs
+++ /dev/null
@@ -1,85 +0,0 @@
-using System;
-
-namespace ClassesAndObjects
-{
- public class Program
- {
- static void PointExample()
- {
- Point p1 = new Point(0, 0);
- Point p2 = new Point(10, 20);
- }
-
- static void PairExample()
- {
- Pair pair = new Pair { First = 1, Second = "two" };
- int i = pair.First; // TFirst is int
- string s = pair.Second; // TSecond is string
- }
-
- static void Point3DExample()
- {
- Point a = new Point(10, 20);
- Point b = new Point3D(10, 20, 30);
- }
-
- static void StringFormatExample()
- {
- int x = 3, y = 4, z = 5;
-
- string s = "x={0} y={1} z={2}";
- object[] args = new object[3];
- args[0] = x;
- args[1] = y;
- args[2] = z;
- Console.WriteLine(s, args);
- }
-
- static void ExpressionExample()
- {
- Expression e = new Operation(
- new VariableReference("x"),
- '+',
- new Constant(3));
- }
-
- public static void Main(string[] args)
- {
- PointExample();
- PairExample();
- Point3DExample();
- RefExample.SwapExample();
- OutExample.OutUsage();
-
- int x = 3, y = 4, z = 5;
- Console.WriteLine("x={0} y={1} z={2}", x, y, z);
-
- Squares.WriteSquares();
-
- EntityExample.Usage();
-
- ExpressionExample();
-
- InheritanceExample.ExampleUsage();
-
- OverloadingExample.UsageExample();
-
- ListExamples.ExampleCode.ListExampleOne();
- ListExamples.ExampleCode.ListExampleTwo();
- ListExamples.ExampleCode.ListExampleThree();
- ListExamples.EventExample.Usage();
- ListExamples.ExampleCode.ListExampleFour();
- }
- }
-}
-
-namespace Snippets
-{
- public class Console
- {
- public static void Write(string fmt, params object[] args) { }
- public static void WriteLine(string fmt, params object[] args) { }
- // ...
- }
-
-}
diff --git a/samples/snippets/csharp/tour/classes-and-objects/RefExample.cs b/samples/snippets/csharp/tour/classes-and-objects/RefExample.cs
deleted file mode 100644
index c95895780400a..0000000000000
--- a/samples/snippets/csharp/tour/classes-and-objects/RefExample.cs
+++ /dev/null
@@ -1,19 +0,0 @@
-namespace ClassesAndObjects
-{
- using System;
- class RefExample
- {
- static void Swap(ref int x, ref int y)
- {
- int temp = x;
- x = y;
- y = temp;
- }
- public static void SwapExample()
- {
- int i = 1, j = 2;
- Swap(ref i, ref j);
- Console.WriteLine($"{i} {j}"); // Outputs "2 1"
- }
- }
-}
\ No newline at end of file
diff --git a/samples/snippets/csharp/tour/classes-and-objects/Squares.cs b/samples/snippets/csharp/tour/classes-and-objects/Squares.cs
deleted file mode 100644
index 097aa782869ef..0000000000000
--- a/samples/snippets/csharp/tour/classes-and-objects/Squares.cs
+++ /dev/null
@@ -1,18 +0,0 @@
-namespace ClassesAndObjects
-{
- using System;
- class Squares
- {
- public static void WriteSquares()
- {
- int i = 0;
- int j;
- while (i < 10)
- {
- j = i * i;
- Console.WriteLine($"{i} x {i} = {j}");
- i = i + 1;
- }
- }
- }
-}
\ No newline at end of file
diff --git a/samples/snippets/csharp/tour/classes-and-objects/access-by-line.txt b/samples/snippets/csharp/tour/classes-and-objects/access-by-line.txt
deleted file mode 100644
index 0e8c4457f4924..0000000000000
--- a/samples/snippets/csharp/tour/classes-and-objects/access-by-line.txt
+++ /dev/null
@@ -1,12 +0,0 @@
-Program.cs: ~/docs/csharp/tour-of-csharp/classes-and-objects.md
-Pair.cs: ~/docs/csharp/tour-of-csharp/classes-and-objects.md
-Point.cs: ~/docs/csharp/tour-of-csharp/classes-and-objects.md
-Color.cs: ~/docs/csharp/tour-of-csharp/classes-and-objects.md
-RefExample.cs: ~/docs/csharp/tour-of-csharp/classes-and-objects.md
-OutExample.cs: ~/docs/csharp/tour-of-csharp/classes-and-objects.md
-Squares.cs: ~/docs/csharp/tour-of-csharp/classes-and-objects.md
-Entity.cs: ~/docs/csharp/tour-of-csharp/classes-and-objects.md
-Expressions.cs: ~/docs/csharp/tour-of-csharp/classes-and-objects.md
-Overloading.cs: ~/docs/csharp/tour-of-csharp/classes-and-objects.md
-ListBasedExamples.cs: ~/docs/csharp/tour-of-csharp/classes-and-objects.md
-
diff --git a/samples/snippets/csharp/tour/classes-and-objects/classes-and-objects.csproj b/samples/snippets/csharp/tour/classes-and-objects/classes-and-objects.csproj
deleted file mode 100644
index 9acff6d2afa81..0000000000000
--- a/samples/snippets/csharp/tour/classes-and-objects/classes-and-objects.csproj
+++ /dev/null
@@ -1,8 +0,0 @@
-
-
-
- Exe
- netcoreapp3.1
-
-
-
diff --git a/samples/snippets/csharp/tour/delegates/Program.cs b/samples/snippets/csharp/tour/delegates/Program.cs
deleted file mode 100644
index 016220efc1c1e..0000000000000
--- a/samples/snippets/csharp/tour/delegates/Program.cs
+++ /dev/null
@@ -1,53 +0,0 @@
-namespace DelegateTour
-{
- using System;
- delegate double Function(double x);
- class Multiplier
- {
- double factor;
- public Multiplier(double factor)
- {
- this.factor = factor;
- }
- public double Multiply(double x)
- {
- return x * factor;
- }
- }
- class DelegateExample
- {
- static double Square(double x)
- {
- return x * x;
- }
- static double[] Apply(double[] a, Function f)
- {
- double[] result = new double[a.Length];
- for (int i = 0; i < a.Length; i++) result[i] = f(a[i]);
- return result;
- }
- static void Main()
- {
- double[] a = {0.0, 0.5, 1.0};
- double[] squares = Apply(a, Square);
- double[] sines = Apply(a, Math.Sin);
- Multiplier m = new Multiplier(2.0);
- double[] doubles = Apply(a, m.Multiply);
- }
- }
-
- class Lambda
- {
- static void ApplyDelegate()
- {
- double[] a = {0.0, 0.5, 1.0};
- double[] doubles = Apply(a, (double x) => x * 2.0);
- }
- static double[] Apply(double[] a, Function f)
- {
- double[] result = new double[a.Length];
- for (int i = 0; i < a.Length; i++) result[i] = f(a[i]);
- return result;
- }
- }
-}
diff --git a/samples/snippets/csharp/tour/delegates/access-by-line.txt b/samples/snippets/csharp/tour/delegates/access-by-line.txt
deleted file mode 100644
index af6897c364fe0..0000000000000
--- a/samples/snippets/csharp/tour/delegates/access-by-line.txt
+++ /dev/null
@@ -1 +0,0 @@
-Program.cs: ~/docs/csharp/tour-of-csharp/delegates.md
diff --git a/samples/snippets/csharp/tour/delegates/delegates.csproj b/samples/snippets/csharp/tour/delegates/delegates.csproj
deleted file mode 100644
index 9acff6d2afa81..0000000000000
--- a/samples/snippets/csharp/tour/delegates/delegates.csproj
+++ /dev/null
@@ -1,8 +0,0 @@
-
-
-
- Exe
- netcoreapp3.1
-
-
-
diff --git a/samples/snippets/csharp/tour/hello/hello.csproj b/samples/snippets/csharp/tour/hello/hello.csproj
deleted file mode 100644
index 9acff6d2afa81..0000000000000
--- a/samples/snippets/csharp/tour/hello/hello.csproj
+++ /dev/null
@@ -1,8 +0,0 @@
-
-
-
- Exe
- netcoreapp3.1
-
-
-
diff --git a/samples/snippets/csharp/tour/interfaces/Program.cs b/samples/snippets/csharp/tour/interfaces/Program.cs
deleted file mode 100644
index 91d76186d0a06..0000000000000
--- a/samples/snippets/csharp/tour/interfaces/Program.cs
+++ /dev/null
@@ -1,79 +0,0 @@
-using System;
-
-namespace Interfaces
-{
- interface IControl
- {
- void Paint();
- }
- interface ITextBox: IControl
- {
- void SetText(string text);
- }
- interface IListBox: IControl
- {
- void SetItems(string[] items);
- }
- interface IComboBox: ITextBox, IListBox {}
-
- interface IDataBound
- {
- void Bind(Binder b);
- }
- public class EditBox: IControl, IDataBound
- {
- public void Paint() { }
- public void Bind(Binder b) { }
- }
-
- public class Program
- {
- static void UsageOne()
- {
- EditBox editBox = new EditBox();
- IControl control = editBox;
- IDataBound dataBound = editBox;
- }
-
- static void UsageTwo()
- {
- object obj = new EditBox();
- IControl control = (IControl)obj;
- IDataBound dataBound = (IDataBound)obj;
- }
-
- public static void Main(string[] args)
- {
-
- }
-
-
- }
-
- public class Binder {}
-}
-
-namespace ExplicitInterface
-{
- using Interfaces;
-
- public class EditBox: IControl, IDataBound
- {
- void IControl.Paint() { }
- void IDataBound.Bind(Binder b) { }
- }
-
- class UsageCode
- {
- static void Example()
- {
- /*
- EditBox editBox = new EditBox();
- editBox.Paint(); // Error, no such method
- IControl control = editBox;
- control.Paint(); // Ok
- */
- }
- }
-
-}
diff --git a/samples/snippets/csharp/tour/interfaces/access-by-line.txt b/samples/snippets/csharp/tour/interfaces/access-by-line.txt
deleted file mode 100644
index 510ab4b324d96..0000000000000
--- a/samples/snippets/csharp/tour/interfaces/access-by-line.txt
+++ /dev/null
@@ -1 +0,0 @@
-Program.cs: ~/docs/csharp/tour-of-csharp/interfaces.md
diff --git a/samples/snippets/csharp/tour/interfaces/interfaces.csproj b/samples/snippets/csharp/tour/interfaces/interfaces.csproj
deleted file mode 100644
index 9acff6d2afa81..0000000000000
--- a/samples/snippets/csharp/tour/interfaces/interfaces.csproj
+++ /dev/null
@@ -1,8 +0,0 @@
-
-
-
- Exe
- netcoreapp3.1
-
-
-
diff --git a/samples/snippets/csharp/tour/program-structure/Program.cs b/samples/snippets/csharp/tour/program-structure/Program.cs
deleted file mode 100644
index 5a0a175a966e6..0000000000000
--- a/samples/snippets/csharp/tour/program-structure/Program.cs
+++ /dev/null
@@ -1,53 +0,0 @@
-using System;
-namespace Acme.Collections
-{
- public class Stack
- {
- Entry top;
- public void Push(object data)
- {
- top = new Entry(top, data);
- }
-
- public object Pop()
- {
- if (top == null)
- {
- throw new InvalidOperationException();
- }
- object result = top.data;
- top = top.next;
- return result;
- }
-
- class Entry
- {
- public Entry next;
- public object data;
- public Entry(Entry next, object data)
- {
- this.next = next;
- this.data = data;
- }
- }
- }
-}
-
-namespace StackExample
-{
-using System;
-using Acme.Collections;
-class Example
-{
- static void Main()
- {
- Stack s = new Stack();
- s.Push(1);
- s.Push(10);
- s.Push(100);
- Console.WriteLine(s.Pop());
- Console.WriteLine(s.Pop());
- Console.WriteLine(s.Pop());
- }
-}
-}
diff --git a/samples/snippets/csharp/tour/program-structure/access-by-line.txt b/samples/snippets/csharp/tour/program-structure/access-by-line.txt
deleted file mode 100644
index d4560c2d84721..0000000000000
--- a/samples/snippets/csharp/tour/program-structure/access-by-line.txt
+++ /dev/null
@@ -1 +0,0 @@
-program.cs: ~/docs/csharp/tour-of-csharp/program-structure.md
diff --git a/samples/snippets/csharp/tour/program-structure/program-structure.csproj b/samples/snippets/csharp/tour/program-structure/program-structure.csproj
deleted file mode 100644
index 9acff6d2afa81..0000000000000
--- a/samples/snippets/csharp/tour/program-structure/program-structure.csproj
+++ /dev/null
@@ -1,8 +0,0 @@
-
-
-
- Exe
- netcoreapp3.1
-
-
-
diff --git a/samples/snippets/csharp/tour/statements/Program.cs b/samples/snippets/csharp/tour/statements/Program.cs
deleted file mode 100644
index f3a0e67787852..0000000000000
--- a/samples/snippets/csharp/tour/statements/Program.cs
+++ /dev/null
@@ -1,274 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.IO;
-
-namespace Statements
-{
- public class Program
- {
- static void Declarations(string[] args)
- {
- int a;
- int b = 2, c = 3;
- a = 1;
- Console.WriteLine(a + b + c);
- }
-
- static void ConstantDeclarations(string[] args)
- {
- const float pi = 3.1415927f;
- const int r = 25;
- Console.WriteLine(pi * r * r);
- }
-
- static void Expressions(string[] args)
- {
- int i;
- i = 123; // Expression statement
- Console.WriteLine(i); // Expression statement
- i++; // Expression statement
- Console.WriteLine(i); // Expression statement
- }
-
- static void IfStatement(string[] args)
- {
- if (args.Length == 0)
- {
- Console.WriteLine("No arguments");
- }
- else
- {
- Console.WriteLine("One or more arguments");
- }
- }
-
- static void SwitchStatement(string[] args)
- {
- int n = args.Length;
- switch (n)
- {
- case 0:
- Console.WriteLine("No arguments");
- break;
- case 1:
- Console.WriteLine("One argument");
- break;
- default:
- Console.WriteLine($"{n} arguments");
- break;
- }
- }
-
- static void WhileStatement(string[] args)
- {
- int i = 0;
- while (i < args.Length)
- {
- Console.WriteLine(args[i]);
- i++;
- }
- }
-
- static void DoStatement(string[] args)
- {
- string s;
- do
- {
- s = Console.ReadLine();
- Console.WriteLine(s);
- } while (!string.IsNullOrEmpty(s));
- }
-
-
- static void ForStatement(string[] args)
- {
- for (int i = 0; i < args.Length; i++)
- {
- Console.WriteLine(args[i]);
- }
- }
-
- static void ForEachStatement(string[] args)
- {
- foreach (string s in args)
- {
- Console.WriteLine(s);
- }
- }
-
- static void BreakStatement(string[] args)
- {
- while (true)
- {
- string s = Console.ReadLine();
- if (string.IsNullOrEmpty(s))
- break;
- Console.WriteLine(s);
- }
- }
-
- static void ContinueStatement(string[] args)
- {
- for (int i = 0; i < args.Length; i++)
- {
- if (args[i].StartsWith("/"))
- continue;
- Console.WriteLine(args[i]);
- }
- }
-
- static void GoToStatement(string[] args)
- {
- int i = 0;
- goto check;
- loop:
- Console.WriteLine(args[i++]);
- check:
- if (i < args.Length)
- goto loop;
- }
-
- static int Add(int a, int b)
- {
- return a + b;
- }
- static void ReturnStatement(string[] args)
- {
- Console.WriteLine(Add(1, 2));
- return;
- }
-
- static System.Collections.Generic.IEnumerable Range(int start, int end)
- {
- for (int i = start; i < end; i++)
- {
- yield return i;
- }
- yield break;
- }
- static void YieldStatement(string[] args)
- {
- foreach (int i in Range(-10,10))
- {
- Console.WriteLine(i);
- }
- }
-
- static double Divide(double x, double y)
- {
- if (y == 0)
- throw new DivideByZeroException();
- return x / y;
- }
- static void TryCatch(string[] args)
- {
- try
- {
- if (args.Length != 2)
- {
- throw new InvalidOperationException("Two numbers required");
- }
- double x = double.Parse(args[0]);
- double y = double.Parse(args[1]);
- Console.WriteLine(Divide(x, y));
- }
- catch (InvalidOperationException e)
- {
- Console.WriteLine(e.Message);
- }
- finally
- {
- Console.WriteLine("Good bye!");
- }
- }
-
- static void CheckedUnchecked(string[] args)
- {
- int x = int.MaxValue;
- unchecked
- {
- Console.WriteLine(x + 1); // Overflow
- }
- checked
- {
- Console.WriteLine(x + 1); // Exception
- }
- }
-
- static void UsingStatement(string[] args)
- {
- using (TextWriter w = File.CreateText("test.txt"))
- {
- w.WriteLine("Line one");
- w.WriteLine("Line two");
- w.WriteLine("Line three");
- }
- }
-
- public static void Main(string[] args)
- {
- Declarations(args);
-
- ConstantDeclarations(args);
-
- Expressions(args);
-
- IfStatement(args);
-
- SwitchStatement(args);
-
- WhileStatement(args);
-
- Console.WriteLine("Type Mesages. Enter a blank line to end");
- DoStatement(args);
-
- ForStatement(args);
-
- ForEachStatement(args);
-
- Console.WriteLine("Type Mesages. Enter a blank line to end");
- BreakStatement(args);
-
- ContinueStatement(args);
-
- GoToStatement(args);
-
- ReturnStatement(args);
-
- YieldStatement(args);
-
- TryCatch(args);
-
- try {
- CheckedUnchecked(args);
- } catch (OverflowException)
- {
- Console.WriteLine("Caught Expected Exception");
- }
-
- var a = new Account();
- a.Withdraw(-5);
- a.Withdraw(2);
-
- UsingStatement(args);
- }
- }
-
- class Account
- {
- decimal balance;
- private readonly object sync = new object();
- public void Withdraw(decimal amount)
- {
- lock (sync)
- {
- if (amount > balance)
- {
- throw new Exception(
- "Insufficient funds");
- }
- balance -= amount;
- }
- }
- }
-}
diff --git a/samples/snippets/csharp/tour/statements/access-by-line.txt b/samples/snippets/csharp/tour/statements/access-by-line.txt
deleted file mode 100644
index 03bf6dd65cb16..0000000000000
--- a/samples/snippets/csharp/tour/statements/access-by-line.txt
+++ /dev/null
@@ -1 +0,0 @@
-program.cs: ~/docs/csharp/tour-of-csharp/statements.md
diff --git a/samples/snippets/csharp/tour/statements/statements.csproj b/samples/snippets/csharp/tour/statements/statements.csproj
deleted file mode 100644
index 9acff6d2afa81..0000000000000
--- a/samples/snippets/csharp/tour/statements/statements.csproj
+++ /dev/null
@@ -1,8 +0,0 @@
-
-
-
- Exe
- netcoreapp3.1
-
-
-
diff --git a/samples/snippets/csharp/tour/types-and-variables/Program.cs b/samples/snippets/csharp/tour/types-and-variables/Program.cs
deleted file mode 100644
index 2907c00b16967..0000000000000
--- a/samples/snippets/csharp/tour/types-and-variables/Program.cs
+++ /dev/null
@@ -1,10 +0,0 @@
-using System;
-class BoxingExample
-{
- static void Main()
- {
- int i = 123;
- object o = i; // Boxing
- int j = (int)o; // Unboxing
- }
-}
diff --git a/samples/snippets/csharp/tour/types-and-variables/access-by-line.txt b/samples/snippets/csharp/tour/types-and-variables/access-by-line.txt
deleted file mode 100644
index e44a66eb0b656..0000000000000
--- a/samples/snippets/csharp/tour/types-and-variables/access-by-line.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-Program.cs: ~/docs/csharp/tour-of-csharp/types-and-variables.md
-
diff --git a/samples/snippets/csharp/tour/types-and-variables/types-and-variables.csproj b/samples/snippets/csharp/tour/types-and-variables/types-and-variables.csproj
deleted file mode 100644
index 9acff6d2afa81..0000000000000
--- a/samples/snippets/csharp/tour/types-and-variables/types-and-variables.csproj
+++ /dev/null
@@ -1,8 +0,0 @@
-
-
-
- Exe
- netcoreapp3.1
-
-
-