diff --git a/.openpublishing.redirection.json b/.openpublishing.redirection.json index b9d1d974869df..0bf8d48c642fa 100644 --- a/.openpublishing.redirection.json +++ b/.openpublishing.redirection.json @@ -1439,6 +1439,10 @@ "source_path": "docs/csharp/language-reference/keywords/global.md", "redirect_url": "/dotnet/csharp/language-reference/operators/namespace-alias-qualifier" }, + { + "source_path": "docs/csharp/language-reference/keywords/if-else.md", + "redirect_url": "/dotnet/csharp/language-reference/statements/selection-statements" + }, { "source_path": "docs/csharp/language-reference/keywords/implicit-numeric-conversions-table.md", "redirect_url": "/dotnet/csharp/language-reference/builtin-types/numeric-conversions" @@ -1521,7 +1525,7 @@ }, { "source_path": "docs/csharp/language-reference/keywords/selection-statements.md", - "redirect_url": "/dotnet/csharp/language-reference/keywords/statement-keywords" + "redirect_url": "/dotnet/csharp/language-reference/statements/selection-statements" }, { "source_path": "docs/csharp/language-reference/keywords/short.md", @@ -1543,6 +1547,10 @@ "source_path": "docs/csharp/language-reference/keywords/struct.md", "redirect_url": "/dotnet/csharp/language-reference/builtin-types/struct" }, + { + "source_path": "docs/csharp/language-reference/keywords/switch.md", + "redirect_url": "/dotnet/csharp/language-reference/statements/selection-statements" + }, { "source_path": "docs/csharp/language-reference/keywords/true-false-operators.md", "redirect_url": "/dotnet/csharp/language-reference/operators/true-false-operators" diff --git a/docs/csharp/fundamentals/functional/discards.md b/docs/csharp/fundamentals/functional/discards.md index 9c51dcaef8ed2..a8da04a2cadc0 100644 --- a/docs/csharp/fundamentals/functional/discards.md +++ b/docs/csharp/fundamentals/functional/discards.md @@ -79,4 +79,4 @@ Without assigning the task to a discard, the following code generates a compiler - [Deconstructing tuples and other types](deconstruct.md) - [`is` operator](../../language-reference/operators/is.md) -- [`switch` keyword](../../language-reference/keywords/switch.md) +- [`switch` expression](../../language-reference/operators/switch-expression.md) diff --git a/docs/csharp/fundamentals/tutorials/classes.md b/docs/csharp/fundamentals/tutorials/classes.md index 787039321701f..7bd1a5499a98e 100644 --- a/docs/csharp/fundamentals/tutorials/classes.md +++ b/docs/csharp/fundamentals/tutorials/classes.md @@ -215,5 +215,5 @@ You can continue with the [object oriented programming](oop.md) tutorial. You can learn more about these concepts in these articles: -- [If and else statement](../../language-reference/keywords/if-else.md) +- [Selection statements](../../language-reference/statements/selection-statements.md) - [Iteration statements](../../language-reference/statements/iteration-statements.md) diff --git a/docs/csharp/fundamentals/tutorials/pattern-matching.md b/docs/csharp/fundamentals/tutorials/pattern-matching.md index 7a0edebb06247..5910f7cdf7468 100644 --- a/docs/csharp/fundamentals/tutorials/pattern-matching.md +++ b/docs/csharp/fundamentals/tutorials/pattern-matching.md @@ -82,7 +82,7 @@ namespace toll_calculator } ``` -The preceding code uses a [`switch` expression](../../language-reference/operators/switch-expression.md) (not the same as a [`switch`](../../language-reference/keywords/switch.md) statement) that tests the [declaration pattern](../../language-reference/operators/patterns.md#declaration-and-type-patterns). A **switch expression** begins with the variable, `vehicle` in the preceding code, followed by the `switch` keyword. Next comes all the **switch arms** inside curly braces. The `switch` expression makes other refinements to the syntax that surrounds the `switch` statement. The `case` keyword is omitted, and the result of each arm is an expression. The last two arms show a new language feature. The `{ }` case matches any non-null object that didn't match an earlier arm. This arm catches any incorrect types passed to this method. The `{ }` case must follow the cases for each vehicle type. If the order were reversed, the `{ }` case would take precedence. Finally, the `null` [constant pattern](../../language-reference/operators/patterns.md#constant-pattern) detects when `null` is passed to this method. The `null` pattern can be last because the other patterns match only a non-null object of the correct type. +The preceding code uses a [`switch` expression](../../language-reference/operators/switch-expression.md) (not the same as a [`switch` statement](../../language-reference/statements/selection-statements.md#the-switch-statement)) that tests the [declaration pattern](../../language-reference/operators/patterns.md#declaration-and-type-patterns). A **switch expression** begins with the variable, `vehicle` in the preceding code, followed by the `switch` keyword. Next comes all the **switch arms** inside curly braces. The `switch` expression makes other refinements to the syntax that surrounds the `switch` statement. The `case` keyword is omitted, and the result of each arm is an expression. The last two arms show a new language feature. The `{ }` case matches any non-null object that didn't match an earlier arm. This arm catches any incorrect types passed to this method. The `{ }` case must follow the cases for each vehicle type. If the order were reversed, the `{ }` case would take precedence. Finally, the `null` [constant pattern](../../language-reference/operators/patterns.md#constant-pattern) detects when `null` is passed to this method. The `null` pattern can be last because the other patterns match only a non-null object of the correct type. You can test this code using the following code in `Program.cs`: diff --git a/docs/csharp/language-reference/builtin-types/bool.md b/docs/csharp/language-reference/builtin-types/bool.md index d0eb348d6c02b..c697b8cd5db03 100644 --- a/docs/csharp/language-reference/builtin-types/bool.md +++ b/docs/csharp/language-reference/builtin-types/bool.md @@ -18,7 +18,7 @@ ms.assetid: 551cfe35-2632-4343-af49-33ad12da08e2 The `bool` type keyword is an alias for the .NET structure type that represents a Boolean value, which can be either `true` or `false`. -To perform logical operations with values of the `bool` type, use [Boolean logical](../operators/boolean-logical-operators.md) operators. The `bool` type is the result type of [comparison](../operators/comparison-operators.md) and [equality](../operators/equality-operators.md) operators. A `bool` expression can be a controlling conditional expression in the [if](../keywords/if-else.md), [do](../statements/iteration-statements.md#the-do-statement), [while](../statements/iteration-statements.md#the-while-statement), and [for](../statements/iteration-statements.md#the-for-statement) statements and in the [conditional operator `?:`](../operators/conditional-operator.md). +To perform logical operations with values of the `bool` type, use [Boolean logical](../operators/boolean-logical-operators.md) operators. The `bool` type is the result type of [comparison](../operators/comparison-operators.md) and [equality](../operators/equality-operators.md) operators. A `bool` expression can be a controlling conditional expression in the [if](../statements/selection-statements.md#the-if-statement), [do](../statements/iteration-statements.md#the-do-statement), [while](../statements/iteration-statements.md#the-while-statement), and [for](../statements/iteration-statements.md#the-for-statement) statements and in the [conditional operator `?:`](../operators/conditional-operator.md). The default value of the `bool` type is `false`. diff --git a/docs/csharp/language-reference/builtin-types/enum.md b/docs/csharp/language-reference/builtin-types/enum.md index 934f5b0a654b5..8003766fbc2af 100644 --- a/docs/csharp/language-reference/builtin-types/enum.md +++ b/docs/csharp/language-reference/builtin-types/enum.md @@ -85,4 +85,5 @@ For more information, see the following sections of the [C# language specificati - [Enumeration format strings](../../../standard/base-types/enumeration-format-strings.md) - [Design guidelines - Enum design](../../../standard/design-guidelines/enum.md) - [Design guidelines - Enum naming conventions](../../../standard/design-guidelines/names-of-classes-structs-and-interfaces.md#naming-enumerations) -- [switch statement](../keywords/switch.md) +- [`switch` expression](../operators/switch-expression.md) +- [`switch` statement](../statements/selection-statements.md#the-switch-statement) diff --git a/docs/csharp/language-reference/compiler-messages/cs0151.md b/docs/csharp/language-reference/compiler-messages/cs0151.md index 31ab99e1c95bb..dcd026218ce10 100644 --- a/docs/csharp/language-reference/compiler-messages/cs0151.md +++ b/docs/csharp/language-reference/compiler-messages/cs0151.md @@ -46,25 +46,3 @@ public class MyClass } } ``` - -## Example of void method - -A [void](../builtin-types/void.md) method invocation in a [switch](../keywords/switch.md) match expression generates CS0151. You can fix the error by calling a method that returns an integral type such as [int](../builtin-types/integral-numeric-types.md) or [long](../builtin-types/integral-numeric-types.md) instead. - -```csharp -class C -{ - static void Main() - { - switch (M()) // CS0151 - { - default: - break; - } - } - - static void M() - { - } -} -``` diff --git a/docs/csharp/language-reference/compiler-messages/cs0163.md b/docs/csharp/language-reference/compiler-messages/cs0163.md index b13ed91c78f7e..088ae10f3dadc 100644 --- a/docs/csharp/language-reference/compiler-messages/cs0163.md +++ b/docs/csharp/language-reference/compiler-messages/cs0163.md @@ -12,7 +12,7 @@ ms.assetid: 00139dcf-33cd-45ea-bf80-d6f26b10a5d2 Control cannot fall through from one case label ('label') to another - When a [switch statement](../keywords/switch.md) contains more than one switch section, you must explicitly terminate each section, including the last one, by using one of the following keywords: + When a [switch statement](../statements/selection-statements.md#the-switch-statement) contains more than one switch section, you must explicitly terminate each section, including the last one, by using one of the following keywords: - [return](../keywords/return.md) @@ -22,9 +22,7 @@ Control cannot fall through from one case label ('label') to another - [throw](../keywords/throw.md) -- [continue](../keywords/continue.md) - - If you want to implement "fall through" behavior from one section to the next, use `goto case #`. For more information and examples, see [switch](../keywords/switch.md). + If you want to implement "fall through" behavior from one section to the next, use `goto case #`. The following sample generates CS0163. diff --git a/docs/csharp/language-reference/keywords/break.md b/docs/csharp/language-reference/keywords/break.md index 9e6f70f9bced8..bcf116e87d080 100644 --- a/docs/csharp/language-reference/keywords/break.md +++ b/docs/csharp/language-reference/keywords/break.md @@ -11,7 +11,7 @@ ms.assetid: be2571ed-efb0-4965-b122-81e5b09db0b9 --- # break (C# Reference) -The `break` statement terminates the closest enclosing loop or [switch](./switch.md) statement in which it appears. Control is passed to the statement that follows the terminated statement, if any. +The `break` statement terminates the closest enclosing loop or [`switch` statement](../statements/selection-statements.md#the-switch-statement) in which it appears. Control is passed to the statement that follows the terminated statement, if any. ## Example 1 @@ -21,7 +21,7 @@ In this example, the conditional statement contains a counter that is supposed t ## Example 2 -This example demonstrates the use of `break` in a [switch](./switch.md) statement. +This example demonstrates the use of `break` in a `switch` statement. [!code-csharp[csrefKeywordsJump#2](~/samples/snippets/csharp/VS_Snippets_VBCSharp/csrefKeywordsJump/CS/csrefKeywordsJump.cs#2)] @@ -40,7 +40,7 @@ In this example, the `break` statement is used to break out of an inner nested l ## Example 4 -In this example, the `break` statement is only used to break out of the current branch during each iteration of the loop. The loop itself is unaffected by the instances of `break` that belong to the nested [switch](./switch.md) statement. +In this example, the `break` statement is only used to break out of the current branch during each iteration of the loop. The loop itself is unaffected by the instances of `break` that belong to the nested `switch` statement. [!code-csharp[csrefKeywordsJump#8](~/samples/snippets/csharp/VS_Snippets_VBCSharp/csrefKeywordsJump/CS/csrefKeywordsJump.cs#8)] @@ -53,4 +53,4 @@ In this example, the `break` statement is only used to break out of the current - [C# Reference](../index.md) - [C# Programming Guide](../../programming-guide/index.md) - [C# Keywords](./index.md) -- [switch](./switch.md) +- [`switch` statement](../statements/selection-statements.md#the-switch-statement) diff --git a/docs/csharp/language-reference/keywords/default.md b/docs/csharp/language-reference/keywords/default.md index 85c7e9c1f16cb..95b0b7bc6cc0b 100644 --- a/docs/csharp/language-reference/keywords/default.md +++ b/docs/csharp/language-reference/keywords/default.md @@ -1,6 +1,6 @@ --- -description: "default - C# Reference" -title: "default - C# Reference" +description: "default - C# reference" +title: "default - C# reference" ms.date: 04/28/2021 f1_keywords: - "default" @@ -9,16 +9,15 @@ helpviewer_keywords: ms.assetid: 14c48aaa-7d35-4058-a1a4-f53353050579 --- -# default (C# Reference) +# default (C# reference) -The `default` keyword can be used in three ways: +You can use the `default` keyword in the following contexts: -- To specify the default label in the [`switch` statement](switch.md). +- To specify the default case in the [`switch` statement](../statements/selection-statements.md#the-switch-statement). - As the [default operator or literal](../operators/default.md) to produce the default value of a type. - As the [`default` type constraint](where-generic-type-constraint.md) on a generic method override or explicit interface implementation. ## See also -- [C# Reference](../index.md) -- [C# Programming Guide](../../programming-guide/index.md) -- [C# Keywords](index.md) +- [C# reference](../index.md) +- [C# keywords](index.md) diff --git a/docs/csharp/language-reference/keywords/goto.md b/docs/csharp/language-reference/keywords/goto.md index e441d9dd18b66..9091e12ccf03b 100644 --- a/docs/csharp/language-reference/keywords/goto.md +++ b/docs/csharp/language-reference/keywords/goto.md @@ -19,7 +19,7 @@ The `goto` statement is also useful to get out of deeply nested loops. ## Example 1 -The following example demonstrates using `goto` in a [switch](switch.md) statement. +The following example demonstrates using `goto` in a [`switch` statement](../statements/selection-statements.md#the-switch-statement). [!code-csharp[csrefKeywordsJump#4](~/samples/snippets/csharp/VS_Snippets_VBCSharp/csrefKeywordsJump/CS/csrefKeywordsJump.cs#4)] diff --git a/docs/csharp/language-reference/keywords/if-else.md b/docs/csharp/language-reference/keywords/if-else.md deleted file mode 100644 index 8724e1f30d9b2..0000000000000 --- a/docs/csharp/language-reference/keywords/if-else.md +++ /dev/null @@ -1,139 +0,0 @@ ---- -description: "if-else - C# Reference" -title: "if-else - C# Reference" -ms.date: 07/20/2015 -f1_keywords: - - "if_CSharpKeyword" - - "else" - - "else_CSharpKeyword" - - "if" -helpviewer_keywords: - - "else keyword [C#]" - - "if keyword [C#]" -ms.assetid: d9a1d562-8cf5-4bd4-9ba7-8ad970cd25b2 ---- -# if-else (C# Reference) - -An `if` statement identifies which statement to run based on the value of a Boolean expression. In the following example, the `bool` variable `condition` is set to `true` and then checked in the `if` statement. The output is `The variable is set to true.`. - -[!code-csharp[csrefKeywordsSelection#1](~/samples/snippets/csharp/VS_Snippets_VBCSharp/csrefKeywordsSelection/CS/csrefKeywordsSelection.cs#1)] - -You can run the examples in this topic by placing them in the `Main` method of a console app. - -An `if` statement in C# can take two forms, as the following example shows. - -```csharp -// if-else statement -if (condition) -{ - then-statement; -} -else -{ - else-statement; -} -// Next statement in the program. - -// if statement without an else -if (condition) -{ - then-statement; -} -// Next statement in the program. -``` - -In an `if-else` statement, if `condition` evaluates to true, the `then-statement` runs. If `condition` is false, the `else-statement` runs. Because `condition` can’t be simultaneously true and false, the `then-statement` and the `else-statement` of an `if-else` statement can never both run. After the `then-statement` or the `else-statement` runs, control is transferred to the next statement after the `if` statement. - -In an `if` statement that doesn’t include an `else` statement, if `condition` is true, the `then-statement` runs. If `condition` is false, control is transferred to the next statement after the `if` statement. - -Both the `then-statement` and the `else-statement` can consist of a single statement or multiple statements that are enclosed in braces (`{}`). For a single statement, the braces are optional but recommended. - -The statement or statements in the `then-statement` and the `else-statement` can be of any kind, including another `if` statement nested inside the original `if` statement. In nested `if` statements, each `else` clause belongs to the last `if` that doesn’t have a corresponding `else`. In the following example, `Result1` appears if both `m > 10` and `n > 20` evaluate to true. If `m > 10` is true but `n > 20` is false, `Result2` appears. - -[!code-csharp[csrefKeywordsSelection#2](~/samples/snippets/csharp/VS_Snippets_VBCSharp/csrefKeywordsSelection/CS/csrefKeywordsSelection.cs#2)] - -If, instead, you want `Result2` to appear when `(m > 10)` is false, you can specify that association by using braces to establish the start and end of the nested `if` statement, as the following example shows. - -[!code-csharp[csrefKeywordsSelection#3](~/samples/snippets/csharp/VS_Snippets_VBCSharp/csrefKeywordsSelection/CS/csrefKeywordsSelection.cs#3)] - -`Result2` appears if the condition `(m > 10)` evaluates to false. - -## Example 1 - -In the following example, you enter a character from the keyboard, and the program uses a nested `if` statement to determine whether the input character is an alphabetic character. If the input character is an alphabetic character, the program checks whether the input character is lowercase or uppercase. A message appears for each case. - -[!code-csharp[csrefKeywordsSelection#4](~/samples/snippets/csharp/VS_Snippets_VBCSharp/csrefKeywordsSelection/CS/csrefKeywordsSelection.cs#4)] - -## Example 2 - -You can also nest an `if` statement inside an else block, as the following partial code shows. The example nests `if` statements inside two else blocks and one then block. The comments specify which conditions are true or false in each block. - -[!code-csharp[csrefKeywordsSelection#5](~/samples/snippets/csharp/VS_Snippets_VBCSharp/csrefKeywordsSelection/CS/csrefKeywordsSelection.cs#5)] - -## Example 3 - -The following example determines whether an input character is a lowercase letter, an uppercase letter, or a number. If all three conditions are false, the character isn’t an alphanumeric character. The example displays a message for each case. - -[!code-csharp[csrefKeywordsSelection#6](~/samples/snippets/csharp/VS_Snippets_VBCSharp/csrefKeywordsSelection/CS/csrefKeywordsSelection.cs#6)] - -Just as a statement in the else block or the then block can be any valid statement, you can use any valid Boolean expression for the condition. You can use [logical operators](../operators/boolean-logical-operators.md) such as `!`, `&&`, `||`, `&`, `|`, and `^` to make compound conditions. The following code shows examples. - -```csharp -// NOT -bool result = true; -if (!result) -{ - Console.WriteLine("The condition is true (result is false)."); -} -else -{ - Console.WriteLine("The condition is false (result is true)."); -} - -// Short-circuit AND -int m = 9; -int n = 7; -int p = 5; -if (m >= n && m >= p) -{ - Console.WriteLine("Nothing is larger than m."); -} - -// AND and NOT -if (m >= n && !(p > m)) -{ - Console.WriteLine("Nothing is larger than m."); -} - -// Short-circuit OR -if (m > n || m > p) -{ - Console.WriteLine("m isn't the smallest."); -} - -// NOT and OR -m = 4; -if (!(m >= n || m >= p)) -{ - Console.WriteLine("Now m is the smallest."); -} -// Output: -// The condition is false (result is true). -// Nothing is larger than m. -// Nothing is larger than m. -// m isn't the smallest. -// Now m is the smallest. -``` - -## C# language specification - -[!INCLUDE[CSharplangspec](~/includes/csharplangspec-md.md)] - -## See also - -- [C# Reference](../index.md) -- [C# Programming Guide](../../programming-guide/index.md) -- [C# Keywords](index.md) -- [?: Operator](../operators/conditional-operator.md) -- [if-else Statement (C++)](/cpp/cpp/if-else-statement-cpp) -- [switch](switch.md) diff --git a/docs/csharp/language-reference/keywords/index.md b/docs/csharp/language-reference/keywords/index.md index 71030e7e5b620..0005b422a8247 100644 --- a/docs/csharp/language-reference/keywords/index.md +++ b/docs/csharp/language-reference/keywords/index.md @@ -25,7 +25,7 @@ The first table in this topic lists keywords that are reserved identifiers in an [bool](../builtin-types/bool.md) [break](break.md) [byte](../builtin-types/integral-numeric-types.md) - [case](switch.md) + [case](../statements/selection-statements.md#the-switch-statement) [catch](try-catch.md) [char](../builtin-types/char.md) [checked](checked.md) @@ -37,7 +37,7 @@ The first table in this topic lists keywords that are reserved identifiers in an [delegate](../builtin-types/reference-types.md) [do](../statements/iteration-statements.md#the-do-statement) [double](../builtin-types/floating-point-numeric-types.md) - [else](if-else.md) + [else](../statements/selection-statements.md#the-if-statement) [enum](../builtin-types/enum.md) :::column-end::: :::column::: @@ -51,7 +51,7 @@ The first table in this topic lists keywords that are reserved identifiers in an [for](../statements/iteration-statements.md#the-for-statement) [foreach](../statements/iteration-statements.md#the-foreach-statement) [goto](goto.md) - [if](if-else.md) + [if](../statements/selection-statements.md#the-if-statement) [implicit](../operators/user-defined-conversion-operators.md) [in](in.md) [int](../builtin-types/integral-numeric-types.md) @@ -86,7 +86,7 @@ The first table in this topic lists keywords that are reserved identifiers in an [static](static.md) [string](../builtin-types/reference-types.md) [struct](../builtin-types/struct.md) - [switch](switch.md) + [switch](../operators/switch-expression.md) [this](this.md) [throw](throw.md) [true](../builtin-types/bool.md) diff --git a/docs/csharp/language-reference/keywords/statement-keywords.md b/docs/csharp/language-reference/keywords/statement-keywords.md index 0c057b34ad645..70fe8e5857dd9 100644 --- a/docs/csharp/language-reference/keywords/statement-keywords.md +++ b/docs/csharp/language-reference/keywords/statement-keywords.md @@ -13,9 +13,9 @@ Statements are program instructions. Except as described in the topics reference |Category|C# keywords| |--------------|------------------| -|Selection statements|[if](if-else.md), [else](if-else.md), [switch](switch.md), [case](switch.md)| +|[Selection statements](../statements/selection-statements.md)|`if`, `switch`| |[Iteration statements](../statements/iteration-statements.md)|`do`, `for`, `foreach`, `while`| -|Jump statements|[break](break.md), [continue](continue.md), [default](switch.md), [goto](goto.md), [return](return.md), [yield](yield.md)| +|Jump statements|[break](break.md), [continue](continue.md), [goto](goto.md), [return](return.md), [yield](yield.md)| |Exception handling statements|[throw](throw.md), [try-catch](try-catch.md), [try-finally](try-finally.md), [try-catch-finally](try-catch-finally.md)| |[Checked and unchecked](checked-and-unchecked.md)|[checked](checked.md), [unchecked](unchecked.md)| |[fixed statement](fixed-statement.md)|[fixed](fixed-statement.md)| diff --git a/docs/csharp/language-reference/keywords/switch.md b/docs/csharp/language-reference/keywords/switch.md deleted file mode 100644 index b03b62789d627..0000000000000 --- a/docs/csharp/language-reference/keywords/switch.md +++ /dev/null @@ -1,204 +0,0 @@ ---- -description: "switch (C# reference)" -title: C# switch statement -ms.date: 04/09/2019 -f1_keywords: - - "switch_CSharpKeyword" - - "switch" - - "case" - - "case_CSharpKeyword" - - "defaultcase_CSharpKeyword" -helpviewer_keywords: - - "switch statement [C#]" - - "switch keyword [C#]" - - "case statement [C#]" - - "default keyword [C#]" -ms.assetid: 44bae8b8-8841-4d85-826b-8a94277daecb ---- -# switch (C# reference) - -This article covers the `switch` statement. For information on the `switch` expression (introduced in C# 8.0), see the article on [`switch` expressions](../operators/switch-expression.md) in the [expressions and operators](../operators/index.md) section. - -`switch` is a selection statement that chooses a single *switch section* to execute from a list of candidates based on a pattern match with the *match expression*. - -[!code-csharp[switch#1](~/samples/snippets/csharp/language-reference/keywords/switch/switch1.cs#1)] - -The `switch` statement is often used as an alternative to an [if-else](if-else.md) construct if a single expression is tested against three or more conditions. For example, the following `switch` statement determines whether a variable of type `Color` has one of three values: - -[!code-csharp[switch#3](~/samples/snippets/csharp/language-reference/keywords/switch/switch3.cs#1)] - -It's equivalent to the following example that uses an `if`-`else` construct. - -[!code-csharp[switch#3a](~/samples/snippets/csharp/language-reference/keywords/switch/switch3a.cs#1)] - -## The match expression - -The match expression provides the value to match against the patterns in `case` labels. Its syntax is: - -```csharp - switch (expr) -``` - -In C# 6 and earlier, the match expression must be an expression that returns a value of the following types: - -- a [char](../builtin-types/char.md). -- a [string](../builtin-types/reference-types.md). -- a [bool](../builtin-types/bool.md). -- an [integral](../builtin-types/integral-numeric-types.md) value, such as an `int` or a `long`. -- an [enum](../builtin-types/enum.md) value. - -Starting with C# 7.0, the match expression can be any non-null expression. - -## The switch section - -A `switch` statement includes one or more switch sections. Each switch section contains one or more *case labels* (either a case or default label) followed by one or more statements. The `switch` statement may include at most one default label placed in any switch section. The following example shows a simple `switch` statement that has three switch sections, each containing two statements. The second switch section contains the `case 2:` and `case 3:` labels. - -A `switch` statement can include any number of switch sections, and each section can have one or more case labels, as shown in the following example. However, no two case labels may contain the same expression. - -[!code-csharp[switch#2](~/samples/snippets/csharp/language-reference/keywords/switch/switch2.cs#1)] - -Only one switch section in a switch statement executes. C# doesn't allow execution to continue from one switch section to the next. Because of this, the following code generates a compiler error, CS0163: "Control cannot fall through from one case label (\) to another." - -```csharp -switch (caseSwitch) -{ - // The following switch section causes an error. - case 1: - Console.WriteLine("Case 1..."); - // Add a break or other jump statement here. - case 2: - Console.WriteLine("... and/or Case 2"); - break; -} -``` - -This requirement is usually met by explicitly exiting the switch section by using a [break](break.md), [goto](goto.md), or [return](return.md) statement. However, the following code is also valid, because it ensures that program control can't fall through to the `default` switch section. - -[!code-csharp[switch#4](~/samples/snippets/csharp/language-reference/keywords/switch/switch4.cs#1)] - -Execution of the statement list in the switch section with a case label that matches the match expression begins with the first statement and proceeds through the statement list, typically until a jump statement, such as a `break`, `goto case`, `goto label`, `return`, or `throw`, is reached. At that point, control is transferred outside the `switch` statement or to another case label. A `goto` statement, if it's used, must transfer control to a constant label. This restriction is necessary, since attempting to transfer control to a non-constant label can have undesirable side-effects, such transferring control to an unintended location in code or creating an endless loop. - -## Case labels - -Each case label specifies a pattern to compare to the match expression (the `caseSwitch` variable in the previous examples). If they match, control is transferred to the switch section that contains the **first** matching case label. If no case label pattern matches the match expression, control is transferred to the section with the `default` case label, if there's one. If there's no `default` case, no statements in any switch section are executed, and control is transferred outside the `switch` statement. - -For information on the `switch` statement and pattern matching, see the [Pattern matching with the `switch` statement](#pattern-matching-with-the-switch-statement) section. - -Because C# 6 supports only the constant pattern and doesn't allow the repetition of constant values, case labels define mutually exclusive values, and only one pattern can match the match expression. As a result, the order in which `case` statements appear is unimportant. - -In C# 7.0, however, because other patterns are supported, case labels need not define mutually exclusive values, and multiple patterns can match the match expression. Because only the statements in the first switch section that contains the matching pattern are executed, the order in which `case` statements appear is now important. If C# detects a switch section whose case statement or statements are equivalent to or are subsets of previous statements, it generates a compiler error, CS8120, "The switch case has already been handled by a previous case." - -The following example illustrates a `switch` statement that uses a variety of non-mutually exclusive patterns. If you move the `case 0:` switch section so that it's no longer the first section in the `switch` statement, C# generates a compiler error because an integer whose value is zero is a subset of all integers, which is the pattern defined by the `case int val` statement. - -[!code-csharp[switch#5](~/samples/snippets/csharp/language-reference/keywords/switch/switch5.cs#1)] - -You can correct this issue and eliminate the compiler warning in one of two ways: - -- By changing the order of the switch sections. - -- By using a [when clause](#the-case-statement-and-the-when-clause) in the `case` label. - -## The `default` case - -The `default` case specifies the switch section to execute if the match expression doesn't match any other `case` label. If a `default` case is not present and the match expression doesn't match any other `case` label, program flow falls through the `switch` statement. - -The `default` case can appear in any order in the `switch` statement. Regardless of its order in the source code, it's always evaluated last, after all `case` labels have been evaluated. - -## Pattern matching with the `switch` statement - -Each `case` statement defines a pattern that, if it matches the match expression, causes its containing switch section to be executed. All versions of C# support the constant pattern. The remaining patterns are supported beginning with C# 7.0. - -### Constant pattern - -The constant pattern tests whether the match expression equals a specified constant. Its syntax is: - -```csharp - case constant: -``` - -where *constant* is the value to test for. *constant* can be any of the following constant expressions: - -- A [bool](../builtin-types/bool.md) literal: either `true` or `false`. -- Any [integral](../builtin-types/integral-numeric-types.md) constant, such as an `int`, a `long`, or a `byte`. -- The name of a declared `const` variable. -- An enumeration constant. -- A [char](../builtin-types/char.md) literal. -- A [string](../builtin-types/reference-types.md) literal. - -The constant expression is evaluated as follows: - -- If *expr* and *constant* are integral types, the C# equality operator determines whether the expression returns `true` (that is, whether `expr == constant`). - -- Otherwise, the value of the expression is determined by a call to the static [Object.Equals(expr, constant)](xref:System.Object.Equals(System.Object,System.Object)) method. - -The following example uses the constant pattern to determine whether a particular date is a weekend, the first day of the work week, the last day of the work week, or the middle of the work week. It evaluates the property of the current day against the members of the enumeration. - -[!code-csharp[switch#7](~/samples/snippets/csharp/language-reference/keywords/switch/const-pattern.cs#1)] - -The following example uses the constant pattern to handle user input in a console application that simulates an automatic coffee machine. - -[!code-csharp[switch#6](~/samples/snippets/csharp/language-reference/keywords/switch/switch6.cs)] - -### Type pattern - -The type pattern enables concise type evaluation and conversion. When used with the `switch` statement to perform pattern matching, it tests whether an expression can be converted to a specified type and, if it can be, casts it to a variable of that type. Its syntax is: - -```csharp - case type varname -``` - -where *type* is the name of the type to which the result of *expr* is to be converted, and *varname* is the object to which the result of *expr* is converted if the match succeeds. The compile-time type of *expr* may be a generic type parameter, starting with C# 7.1. - -The `case` expression is `true` if any of the following is true: - -- *expr* is an instance of the same type as *type*. - -- *expr* is an instance of a type that derives from *type*. In other words, the result of *expr* can be upcast to an instance of *type*. - -- *expr* has a compile-time type that is a base class of *type*, and *expr* has a runtime type that is *type* or is derived from *type*. The *compile-time type* of a variable is the variable's type as defined in its type declaration. The *runtime type* of a variable is the type of the instance that is assigned to that variable. - -- *expr* is an instance of a type that implements the *type* interface. - -If the case expression is true, *varname* is definitely assigned and has local scope within the switch section only. - -Note that `null` doesn't match a type. To match a `null`, you use the following `case` label: - -```csharp -case null: -``` - -The following example uses the type pattern to provide information about various kinds of collection types. - -[!code-csharp[type-pattern#1](~/samples/snippets/csharp/language-reference/keywords/switch/type-pattern.cs#1)] - -Instead of `object`, you could make a generic method, using the type of the collection as the type parameter, as shown in the following code: - -[!code-csharp[type-pattern#3](~/samples/snippets/csharp/language-reference/keywords/switch/type-pattern3.cs#1)] - -The generic version is different than the first sample in two ways. First, you can't use the `null` case. You can't use any constant case because the compiler can't convert any arbitrary type `T` to any type other than `object`. What had been the `default` case now tests for a non-null `object`. That means the `default` case tests only for `null`. - -Without pattern matching, this code might be written as follows. The use of type pattern matching produces more compact, readable code by eliminating the need to test whether the result of a conversion is a `null` or to perform repeated casts. - -[!code-csharp[type-pattern2#1](~/samples/snippets/csharp/language-reference/keywords/switch/type-pattern2.cs#1)] - -## The `case` statement and the `when` clause - -Starting with C# 7.0, because case statements need not be mutually exclusive, you can add a `when` clause to specify an additional condition that must be satisfied for the case statement to evaluate to true. The `when` clause can be any expression that returns a Boolean value. - -The following example defines a base `Shape` class, a `Rectangle` class that derives from `Shape`, and a `Square` class that derives from `Rectangle`. It uses the `when` clause to ensure that the `ShowShapeInfo` treats a `Rectangle` object that has been assigned equal lengths and widths as a `Square` even if it hasn't been instantiated as a `Square` object. The method doesn't attempt to display information either about an object that is `null` or a shape whose area is zero. - -[!code-csharp[when-clause#1](~/samples/snippets/csharp/language-reference/keywords/switch/when-clause.cs#1)] - -Note that the `when` clause in the example that attempts to test whether a `Shape` object is `null` doesn't execute. The correct type pattern to test for a `null` is `case null:`. - -## C# language specification - -For more information, see [The switch statement](~/_csharplang/spec/statements.md#the-switch-statement) in the [C# Language Specification](/dotnet/csharp/language-reference/language-specification/introduction). The language specification is the definitive source for C# syntax and usage. - -## See also - -- [C# Reference](../index.md) -- [C# Programming Guide](../../programming-guide/index.md) -- [C# Keywords](index.md) -- [if-else](if-else.md) -- [Pattern Matching](../../fundamentals/functional/pattern-matching.md) diff --git a/docs/csharp/language-reference/keywords/when.md b/docs/csharp/language-reference/keywords/when.md index 7e68433191936..2f22680800c82 100644 --- a/docs/csharp/language-reference/keywords/when.md +++ b/docs/csharp/language-reference/keywords/when.md @@ -1,6 +1,6 @@ --- -description: "when contextual keyword - C# Reference" -title: "when contextual keyword - C# Reference" +description: "when contextual keyword - C# reference" +title: "when contextual keyword - C# reference" ms.date: 03/07/2017 f1_keywords: - "when_CSharpKeyword" @@ -9,13 +9,13 @@ helpviewer_keywords: - "when keyword [C#]" ms.assetid: dd543335-ae37-48ac-9560-bd5f047b9aea --- -# when (C# Reference) +# when (C# reference) -You can use the `when` contextual keyword to specify a filter condition in the following contexts: +You use the `when` contextual keyword to specify a filter condition in the following contexts: - In the `catch` statement of a [try/catch](try-catch.md) or [try/catch/finally](try-catch-finally.md) block. -- In the `case` label of a [switch](switch.md) statement. -- In the [`switch` expression](../operators/switch-expression.md). +- As a [case guard](../statements/selection-statements.md#case-guards) in the [`switch` statement](../statements/selection-statements.md#the-switch-statement). +- As a [case guard](../operators/switch-expression.md#case-guards) in the [`switch` expression](../operators/switch-expression.md). ## `when` in a `catch` statement @@ -31,22 +31,7 @@ The following example uses the `when` keyword to conditionally execute handlers [!code-csharp[when-with-catch](~/samples/snippets/csharp/language-reference/keywords/when/catch.cs)] -## `when` in a `switch` statement - -Starting with C# 7.0, `case` labels no longer need be mutually exclusive, and the order in which `case` labels appear in a `switch` statement can determine which switch block executes. The `when` keyword can be used to specify a filter condition that causes its associated case label to be true only if the filter condition is also true. Its syntax is: - -```csharp -case (expr) when (when-condition): -``` - -where *expr* is a constant pattern or type pattern that is compared to the match expression, and *when-condition* is any Boolean expression. - -The following example uses the `when` keyword to test for `Shape` objects that have an area of zero, as well as to test for a variety of `Shape` objects that have an area greater than zero. - -[!code-csharp[when-with-case#1](~/samples/snippets/csharp/language-reference/keywords/when/when.cs#1)] - ## See also -- [switch statement](switch.md) - [try/catch statement](try-catch.md) - [try/catch/finally statement](try-catch-finally.md) diff --git a/docs/csharp/language-reference/operators/conditional-operator.md b/docs/csharp/language-reference/operators/conditional-operator.md index 65199917df63b..45bd3e3472d34 100644 --- a/docs/csharp/language-reference/operators/conditional-operator.md +++ b/docs/csharp/language-reference/operators/conditional-operator.md @@ -70,9 +70,9 @@ The following example demonstrates the usage of a conditional ref expression: [!code-csharp-interactive[conditional ref](snippets/shared/ConditionalOperator.cs#ConditionalRef)] -## Conditional operator and an `if..else` statement +## Conditional operator and an `if` statement -Use of the conditional operator instead of an [if-else](../keywords/if-else.md) statement might result in more concise code in cases when you need conditionally to compute a value. The following example demonstrates two ways to classify an integer as negative or nonnegative: +Use of the conditional operator instead of an [`if` statement](../statements/selection-statements.md#the-if-statement) might result in more concise code in cases when you need conditionally to compute a value. The following example demonstrates two ways to classify an integer as negative or nonnegative: [!code-csharp[conditional and if-else](snippets/shared/ConditionalOperator.cs#CompareWithIf)] @@ -93,7 +93,7 @@ For more information about features added in C# 7.2 and later, see the following - [C# reference](../index.md) - [C# operators and expressions](index.md) -- [if-else statement](../keywords/if-else.md) +- [if statement](../statements/selection-statements.md#the-if-statement) - [?. and ?[] operators](member-access-operators.md#null-conditional-operators--and-) - [?? and ??= operators](null-coalescing-operator.md) - [ref keyword](../keywords/ref.md) diff --git a/docs/csharp/language-reference/operators/default.md b/docs/csharp/language-reference/operators/default.md index a734871b84788..b91bd7d726529 100644 --- a/docs/csharp/language-reference/operators/default.md +++ b/docs/csharp/language-reference/operators/default.md @@ -11,7 +11,7 @@ helpviewer_keywords: A default value expression produces the [default value](../builtin-types/default-values.md) of a type. There are two kinds of default value expressions: the [default operator](#default-operator) call and a [default literal](#default-literal). -You also use the `default` keyword as the default case label within a [`switch` statement](../keywords/switch.md). +You also use the `default` keyword as the default case label within a [`switch` statement](../statements/selection-statements.md#the-switch-statement). ## default operator diff --git a/docs/csharp/language-reference/operators/patterns.md b/docs/csharp/language-reference/operators/patterns.md index 1408f6806a4a9..ea49acfb3debf 100644 --- a/docs/csharp/language-reference/operators/patterns.md +++ b/docs/csharp/language-reference/operators/patterns.md @@ -17,7 +17,7 @@ helpviewer_keywords: C# introduced pattern matching in C# 7.0. Since then, each major C# version extends pattern matching capabilities. The following C# expressions and statements support pattern matching: - [`is` expression](is.md) -- `switch` [statement](../keywords/switch.md) +- `switch` [statement](../statements/selection-statements.md#the-switch-statement) - `switch` [expression](switch-expression.md) (introduced in C# 8.0) In those constructs, you can match an input expression against any of the following patterns: diff --git a/docs/csharp/language-reference/operators/switch-expression.md b/docs/csharp/language-reference/operators/switch-expression.md index 7b75533cb87f2..b41604bde80dc 100644 --- a/docs/csharp/language-reference/operators/switch-expression.md +++ b/docs/csharp/language-reference/operators/switch-expression.md @@ -10,7 +10,7 @@ helpviewer_keywords: --- # switch expression (C# reference) -Beginning with C# 8.0, you use the `switch` expression to evaluate a single expression from a list of candidate expressions based on a pattern match with an input expression. For information about the `switch` statement that supports `switch`-like semantics in a statement context, see the [`switch` statement](../keywords/switch.md) article. +Beginning with C# 8.0, you use the `switch` expression to evaluate a single expression from a list of candidate expressions based on a pattern match with an input expression. For information about the `switch` statement that supports `switch`-like semantics in a statement context, see the [`switch` statement](../statements/selection-statements.md#the-switch-statement) section of the [Selection statements](../statements/selection-statements.md) article. The following example demonstrates a `switch` expression, which converts values of an [`enum`](../builtin-types/enum.md) representing visual directions in an online map to the corresponding cardinal directions: @@ -23,8 +23,8 @@ The preceding example shows the basic elements of a `switch` expression: At the preceding example, a `switch` expression uses the following patterns: -- A [constant pattern](patterns.md#constant-pattern) that is used to handle the defined values of the `Direction` enumeration. -- A [discard pattern](patterns.md#discard-pattern) that is used to handle any integer value that doesn't have the corresponding member of the `Direction` enumeration (for example, `(Direction)10`). That makes the `switch` expression [exhaustive](#non-exhaustive-switch-expressions). +- A [constant pattern](patterns.md#constant-pattern): to handle the defined values of the `Direction` enumeration. +- A [discard pattern](patterns.md#discard-pattern): to handle any integer value that doesn't have the corresponding member of the `Direction` enumeration (for example, `(Direction)10`). That makes the `switch` expression [exhaustive](#non-exhaustive-switch-expressions). For information about the patterns supported by a `switch` expression, see [Patterns](patterns.md). @@ -34,7 +34,7 @@ The compiler generates an error when a lower `switch` expression arm can't be ch ## Case guards -A pattern may be not expressive enough to specify the condition for the evaluation of an arm's expression. In such a case, you can use a case guard. That is an additional condition that must be satisfied together with a matched pattern. You specify a case guard after the `when` keyword that follows a pattern, as the following example shows: +A pattern may be not expressive enough to specify the condition for the evaluation of an arm's expression. In such a case, you can use a case guard. That is an additional condition that must be satisfied together with a matched pattern. A case guard must be a Boolean expression. You specify a case guard after the `when` keyword that follows a pattern, as the following example shows: :::code language="csharp" source="snippets/shared/SwitchExpressions.cs" id="CaseGuardExample"::: @@ -57,4 +57,4 @@ For more information, see the [`switch` expression](~/_csharplang/proposals/csha - [C# operators and expressions](index.md) - [Patterns](patterns.md) - [Tutorial: Use pattern matching to build type-driven and data-driven algorithms](../../fundamentals/tutorials/pattern-matching.md) -- [`switch` statement](../keywords/switch.md) +- [`switch` statement](../statements/selection-statements.md#the-switch-statement) diff --git a/docs/csharp/language-reference/operators/true-false-operators.md b/docs/csharp/language-reference/operators/true-false-operators.md index 26b9208cfb897..f56312ab148ed 100644 --- a/docs/csharp/language-reference/operators/true-false-operators.md +++ b/docs/csharp/language-reference/operators/true-false-operators.md @@ -16,7 +16,7 @@ The `true` operator returns the [bool](../builtin-types/bool.md) value `true` to ## Boolean expressions -A type with the defined `true` operator can be the type of a result of a controlling conditional expression in the [if](../keywords/if-else.md), [do](../statements/iteration-statements.md#the-do-statement), [while](../statements/iteration-statements.md#the-while-statement), and [for](../statements/iteration-statements.md#the-for-statement) statements and in the [conditional operator `?:`](conditional-operator.md). For more information, see the [Boolean expressions](~/_csharplang/spec/expressions.md#boolean-expressions) section of the [C# language specification](~/_csharplang/spec/introduction.md). +A type with the defined `true` operator can be the type of a result of a controlling conditional expression in the [if](../statements/selection-statements.md#the-if-statement), [do](../statements/iteration-statements.md#the-do-statement), [while](../statements/iteration-statements.md#the-while-statement), and [for](../statements/iteration-statements.md#the-for-statement) statements and in the [conditional operator `?:`](conditional-operator.md). For more information, see the [Boolean expressions](~/_csharplang/spec/expressions.md#boolean-expressions) section of the [C# language specification](~/_csharplang/spec/introduction.md). ## User-defined conditional logical operators diff --git a/docs/csharp/language-reference/statements/selection-statements.md b/docs/csharp/language-reference/statements/selection-statements.md new file mode 100644 index 0000000000000..f138efc05010c --- /dev/null +++ b/docs/csharp/language-reference/statements/selection-statements.md @@ -0,0 +1,107 @@ +--- +title: "Selection statements - C# reference" +description: "Learn about C# selection statements: if and switch." +ms.date: 08/09/2021 +f1_keywords: + - "if_CSharpKeyword" + - "else_CSharpKeyword" + - "switch_CSharpKeyword" + - "case_CSharpKeyword" + - "defaultcase_CSharpKeyword" +helpviewer_keywords: + - "if statement [C#]" + - "if keyword [C#]" + - "else keyword [C#]" + - "switch statement [C#]" + - "switch keyword [C#]" + - "case keyword [C#]" + - "default keyword [C#]" +--- +# Selection statements (C# reference) + +The following statements select statements to execute from a number of possible statements based on the value of an expression: + +- The [`if` statement](#the-if-statement): selects a statement to execute based on the value of a Boolean expression. +- The [`switch` statement](#the-switch-statement): selects a statement list to execute based on a pattern match with an expression. + +## The `if` statement + +An `if` statement can be any of the following two forms: + +- An `if` statement with an `else` part selects one of the two statements to execute based on the value of a Boolean expression, as the following example shows: + + :::code language="csharp" interactive="try-dotnet-method" source="snippets/selection-statements/IfStatement.cs" id="IfElse"::: + +- An `if` statement without an `else` part executes its body only if a Boolean expression evaluates to `true`, as the following example shows: + + :::code language="csharp" interactive="try-dotnet-method" source="snippets/selection-statements/IfStatement.cs" id="OnlyIf"::: + +You can nest `if` statements to check multiple conditions, as the following example shows: + +:::code language="csharp" interactive="try-dotnet-method" source="snippets/selection-statements/IfStatement.cs" id="NestedIf"::: + +In an expression context, you can use the [conditional operator `?:`](../operators/conditional-operator.md) to evaluate one of the two expressions based on the value of a Boolean expression. + +## The `switch` statement + +The `switch` statement selects a statement list to execute based on a pattern match with a match expression, as the following example shows: + +:::code language="csharp" source="snippets/selection-statements/SwitchStatement.cs" id="Example"::: + +At the preceding example, the `switch` statement uses the following patterns: + +- A [relational pattern](../operators/patterns.md#relational-patterns): to compare an expression result with a constant. +- A [constant pattern](../operators/patterns.md#constant-pattern): to test if an expression result equals a constant. + +For information about the patterns supported by the `switch` statement, see [Patterns](../operators/patterns.md). + +The preceding example also demonstrates the `default` case. The `default` case specifies statements to execute when a match expression doesn't match any other case pattern. If a match expression doesn't match any case pattern and there is no `default` case, control falls through a `switch` statement. + +A `switch` statement executes the *statement list* in the first *switch section* whose *case pattern* matches a match expression and whose [case guard](#case-guards), if present, evaluates to `true`. A `switch` statement evaluates case patterns in text order from top to bottom. The compiler generates an error when a `switch` statement contains an unreachable case. That is a case that is already handled by an upper case or whose pattern is impossible to match. + +> [!NOTE] +> The `default` case can appear in any place within a `switch` statement. Regardless of its position, the `default` case is always evaluated last and only if all other case patterns aren't matched. + +You can specify multiple case patterns for one section of a `switch` statement, as the following example shows: + +:::code language="csharp" source="snippets/selection-statements/SwitchStatement.cs" id="MultipleCases"::: + +Within a `switch` statement, control cannot fall through from one switch section to the next. As the examples in this section show, typically you use the `break` statement at the end of each switch section to pass control out of a `switch` statement. You can also use the [return](../keywords/return.md) and [throw](../keywords/throw.md) statements to pass control out of a `switch` statement. To imitate the fall-through behavior and pass control to other switch section, you can use the [`goto` statement](../keywords/goto.md). + +In an expression context, you can use the [`switch` expression](../operators/switch-expression.md) to evaluate a single expression from a list of candidate expressions based on a pattern match with an expression. + +### Case guards + +A case pattern may be not expressive enough to specify the condition for the execution of the switch section. In such a case, you can use a *case guard*. That is an additional condition that must be satisfied together with a matched pattern. A case guard must be a Boolean expression. You specify a case guard after the `when` keyword that follows a pattern, as the following example shows: + +:::code language="csharp" source="snippets/selection-statements/SwitchStatement.cs" id="WithCaseGuard"::: + +The preceding example uses [positional patterns](../operators/patterns.md#positional-pattern) with nested [relational patterns](../operators/patterns.md#relational-patterns). + +### Language version support + +The `switch` statement supports pattern matching beginning with C# 7.0. + +In C# 6 and earlier, you use the `switch` statement with the following limitations: + +- A match expression must be of one of the following types: [char](../builtin-types/char.md), [string](../builtin-types/reference-types.md), [bool](../builtin-types/bool.md), an [integral numeric](../builtin-types/integral-numeric-types.md) type, or an [enum](../builtin-types/enum.md) type. +- Only constant expressions are allowed in `case` labels. + +## C# language specification + +For more information, see the following sections of the [C# language specification](~/_csharplang/spec/introduction.md): + +- [The `if` statement](~/_csharplang/spec/statements.md#the-if-statement) +- [The `switch` statement](~/_csharplang/spec/statements.md#the-switch-statement) + +For more information about features introduced in C# 7.0 and later, see the following feature proposal notes: + +- [Switch statement (Pattern matching for C# 7.0)](~/_csharplang/proposals/csharp-7.0/pattern-matching.md#switch-statement) + +## See also + +- [C# reference](../index.md) +- [Conditional operator `?:`](../operators/conditional-operator.md) +- [Logical operators](../operators/boolean-logical-operators.md) +- [Patterns](../operators/patterns.md) +- [`switch` expression](../operators/switch-expression.md) diff --git a/docs/csharp/language-reference/statements/snippets/selection-statements/IfStatement.cs b/docs/csharp/language-reference/statements/snippets/selection-statements/IfStatement.cs new file mode 100644 index 0000000000000..394f0976ff13a --- /dev/null +++ b/docs/csharp/language-reference/statements/snippets/selection-statements/IfStatement.cs @@ -0,0 +1,82 @@ +using System; + +namespace SelectionStatements +{ + public static class IfStatement + { + public static void Examples() + { + IfElse(); + OnlyIf(); + NestedIf(); + } + + private static void IfElse() + { + // + DisplayWeatherReport(15.0); // Output: Cold. + DisplayWeatherReport(24.0); // Output: Perfect! + + void DisplayWeatherReport(double tempInCelsius) + { + if (tempInCelsius < 20.0) + { + Console.WriteLine("Cold."); + } + else + { + Console.WriteLine("Perfect!"); + } + } + // + } + + private static void OnlyIf() + { + // + DisplayMeasurement(45); // Output: The measurement value is 45 + DisplayMeasurement(-3); // Output: Warning: not acceptable value! The measurement value is -3 + + void DisplayMeasurement(double value) + { + if (value < 0 || value > 100) + { + Console.Write("Warning: not acceptable value! "); + } + + Console.WriteLine($"The measurement value is {value}"); + } + // + } + + private static void NestedIf() + { + // + DisplayCharacter('f'); // Output: A lowercase letter: f + DisplayCharacter('R'); // Output: An uppercase letter: R + DisplayCharacter('8'); // Output: A digit: 8 + DisplayCharacter(','); // Output: Not alphanumeric character: , + + void DisplayCharacter(char ch) + { + if (char.IsUpper(ch)) + { + Console.WriteLine($"An uppercase letter: {ch}"); + } + else if (char.IsLower(ch)) + { + Console.WriteLine($"A lowercase letter: {ch}"); + } + else if (char.IsDigit(ch)) + { + Console.WriteLine($"A digit: {ch}"); + } + else + { + Console.WriteLine($"Not alphanumeric character: {ch}"); + } + } + // + } + } +} \ No newline at end of file diff --git a/docs/csharp/language-reference/statements/snippets/selection-statements/Program.cs b/docs/csharp/language-reference/statements/snippets/selection-statements/Program.cs new file mode 100644 index 0000000000000..c9f464977befa --- /dev/null +++ b/docs/csharp/language-reference/statements/snippets/selection-statements/Program.cs @@ -0,0 +1,16 @@ +using System; + +namespace SelectionStatements +{ + class Program + { + static void Main(string[] args) + { + Console.WriteLine("------------- if examples ---------------"); + IfStatement.Examples(); + + Console.WriteLine("----------- switch examples -------------"); + SwitchStatement.Examples(); + } + } +} diff --git a/docs/csharp/language-reference/statements/snippets/selection-statements/SwitchStatement.cs b/docs/csharp/language-reference/statements/snippets/selection-statements/SwitchStatement.cs new file mode 100644 index 0000000000000..5a80276347629 --- /dev/null +++ b/docs/csharp/language-reference/statements/snippets/selection-statements/SwitchStatement.cs @@ -0,0 +1,96 @@ +using System; + +namespace SelectionStatements +{ + public static class SwitchStatement + { + public static void Examples() + { + Example(); + MultipleCases(); + WithCaseGuard(); + } + + private static void Example() + { + // + DisplayMeasurement(-4); // Output: Measured value is -4; too low. + DisplayMeasurement(5); // Output: Measured value is 5. + DisplayMeasurement(30); // Output: Measured value is 30; too high. + DisplayMeasurement(double.NaN); // Output: Failed measurement. + + void DisplayMeasurement(double measurement) + { + switch (measurement) + { + case < 0.0: + Console.WriteLine($"Measured value is {measurement}; too low."); + break; + + case > 15.0: + Console.WriteLine($"Measured value is {measurement}; too high."); + break; + + case double.NaN: + Console.WriteLine("Failed measurement."); + break; + + default: + Console.WriteLine($"Measured value is {measurement}."); + break; + } + } + // + } + + private static void MultipleCases() + { + // + DisplayMeasurement(-4); // Output: Measured value is -4; out of an acceptable range. + DisplayMeasurement(50); // Output: Measured value is 50. + DisplayMeasurement(132); // Output: Measured value is 132; out of an acceptable range. + + void DisplayMeasurement(int measurement) + { + switch (measurement) + { + case < 0: + case > 100: + Console.WriteLine($"Measured value is {measurement}; out of an acceptable range."); + break; + + default: + Console.WriteLine($"Measured value is {measurement}."); + break; + } + } + // + } + + private static void WithCaseGuard() + { + // + DisplayMeasurements(3, 4); // Output: First measurement is 3, second measurement is 4. + DisplayMeasurements(5, 5); // Output: Both measurements are valid and equal to 5. + + void DisplayMeasurements(int a, int b) + { + switch ((a, b)) + { + case (> 0, > 0) when a == b: + Console.WriteLine($"Both measurements are valid and equal to {a}."); + break; + + case (> 0, > 0): + Console.WriteLine($"First measurement is {a}, second measurement is {b}."); + break; + + default: + Console.WriteLine("One or both measurements are not valid."); + break; + } + } + // + } + } +} \ No newline at end of file diff --git a/docs/csharp/language-reference/statements/snippets/selection-statements/selection-statements.csproj b/docs/csharp/language-reference/statements/snippets/selection-statements/selection-statements.csproj new file mode 100644 index 0000000000000..b385a449bbc3c --- /dev/null +++ b/docs/csharp/language-reference/statements/snippets/selection-statements/selection-statements.csproj @@ -0,0 +1,11 @@ + + + + Exe + net5.0 + enable + SelectionStatements + SelectionStatements.Program + + + diff --git a/docs/csharp/misc/cs0150.md b/docs/csharp/misc/cs0150.md index 3cf59f11aa4a8..5ce18458f349c 100644 --- a/docs/csharp/misc/cs0150.md +++ b/docs/csharp/misc/cs0150.md @@ -12,7 +12,7 @@ ms.assetid: 1fd08ca5-e1a9-42f5-93de-2916a3bdcad1 A constant value is expected - A variable was found where a constant was expected. For more information, see [switch](../language-reference/keywords/switch.md). + A variable was found where a constant was expected. For more information, see [switch](../language-reference/statements/selection-statements.md#the-switch-statement). The following sample generates CS0150: diff --git a/docs/csharp/misc/cs0152.md b/docs/csharp/misc/cs0152.md index e8755b6342a2a..c24c0dbee067e 100644 --- a/docs/csharp/misc/cs0152.md +++ b/docs/csharp/misc/cs0152.md @@ -12,7 +12,7 @@ ms.assetid: 4915ca16-6485-4e1f-ace0-c71a7b339ba4 The label 'label' already occurs in this switch statement - A label was repeated in a [switch](../language-reference/keywords/switch.md) statement. For more information, see [switch](../language-reference/keywords/switch.md). + A label was repeated in a [`switch` statement](../language-reference/statements/selection-statements.md#the-switch-statement). The following sample generates CS0152: diff --git a/docs/csharp/misc/cs0153.md b/docs/csharp/misc/cs0153.md index ffc7f8bd06424..596b9c3704e5c 100644 --- a/docs/csharp/misc/cs0153.md +++ b/docs/csharp/misc/cs0153.md @@ -12,7 +12,7 @@ ms.assetid: 3a0791e9-0ab9-4eaa-a230-d39aabaa9d5d A goto case is only valid inside a switch statement - An attempt was made to use [switch](../language-reference/keywords/switch.md) syntax outside of a **switch** statement. For more information, see [switch](../language-reference/keywords/switch.md). + An attempt was made to use the [`switch` statement](../language-reference/statements/selection-statements.md#the-switch-statement) syntax outside of a `switch` statement. The following sample generates CS0153: diff --git a/docs/csharp/misc/cs1522.md b/docs/csharp/misc/cs1522.md index e3880cc05271c..a47c019ca9251 100644 --- a/docs/csharp/misc/cs1522.md +++ b/docs/csharp/misc/cs1522.md @@ -12,7 +12,7 @@ ms.assetid: afb99bbf-a1d9-441e-b392-6845bea23f27 Empty switch block - The compiler detected a [switch](../language-reference/keywords/switch.md) block with no **case** or **default** statement. A `switch` block must have one or more **case** or **default** statements. + The compiler detected a [switch](../language-reference/statements/selection-statements.md#the-switch-statement) block with no **case** or **default** statement. A `switch` block must have one or more **case** or **default** statements. The following sample generates CS1522: diff --git a/docs/csharp/programming-guide/statements-expressions-operators/statements.md b/docs/csharp/programming-guide/statements-expressions-operators/statements.md index 90dd1634a93d3..8f9f206016a97 100644 --- a/docs/csharp/programming-guide/statements-expressions-operators/statements.md +++ b/docs/csharp/programming-guide/statements-expressions-operators/statements.md @@ -23,9 +23,9 @@ The following table lists the various types of statements in C# and their associ |--------------|---------------------------| |[Declaration statements](#declaration-statements)|A declaration statement introduces a new variable or constant. A variable declaration can optionally assign a value to the variable. In a constant declaration, the assignment is required.| |[Expression statements](#expression-statements)|Expression statements that calculate a value must store the value in a variable.| -|Selection statements|Selection statements enable you to branch to different sections of code, depending on one or more specified conditions. For more information, see the following topics:
  • [if](../../language-reference/keywords/if-else.md)
  • [else](../../language-reference/keywords/if-else.md)
  • [switch](../../language-reference/keywords/switch.md)
  • [case](../../language-reference/keywords/switch.md)
| +|Selection statements|Selection statements enable you to branch to different sections of code, depending on one or more specified conditions. For more information, see the following topics:
  • [if](../../language-reference/statements/selection-statements.md#the-if-statement)
  • [switch](../../language-reference/statements/selection-statements.md#the-switch-statement)
| |Iteration statements|Iteration statements enable you to loop through collections like arrays, or perform the same set of statements repeatedly until a specified condition is met. For more information, see the following topics:
  • [do](../../language-reference/statements/iteration-statements.md#the-do-statement)
  • [for](../../language-reference/statements/iteration-statements.md#the-for-statement)
  • [foreach](../../language-reference/statements/iteration-statements.md#the-foreach-statement)
  • [while](../../language-reference/statements/iteration-statements.md#the-while-statement)
| -|Jump statements|Jump statements transfer control to another section of code. For more information, see the following topics:
  • [break](../../language-reference/keywords/break.md)
  • [continue](../../language-reference/keywords/continue.md)
  • [default](../../language-reference/keywords/switch.md)
  • [goto](../../language-reference/keywords/goto.md)
  • [return](../../language-reference/keywords/return.md)
  • [yield](../../language-reference/keywords/yield.md)
| +|Jump statements|Jump statements transfer control to another section of code. For more information, see the following topics:
  • [break](../../language-reference/keywords/break.md)
  • [continue](../../language-reference/keywords/continue.md)
  • [goto](../../language-reference/keywords/goto.md)
  • [return](../../language-reference/keywords/return.md)
  • [yield](../../language-reference/keywords/yield.md)
| |Exception handling statements|Exception handling statements enable you to gracefully recover from exceptional conditions that occur at run time. For more information, see the following topics:
  • [throw](../../language-reference/keywords/throw.md)
  • [try-catch](../../language-reference/keywords/try-catch.md)
  • [try-finally](../../language-reference/keywords/try-finally.md)
  • [try-catch-finally](../../language-reference/keywords/try-catch-finally.md)
| |[Checked and unchecked](../../language-reference/keywords/checked-and-unchecked.md)|Checked and unchecked statements enable you to specify whether numerical operations are allowed to cause an overflow when the result is stored in a variable that is too small to hold the resulting value. For more information, see [checked](../../language-reference/keywords/checked.md) and [unchecked](../../language-reference/keywords/unchecked.md).| |The `await` statement|If you mark a method with the [async](../../language-reference/keywords/async.md) modifier, you can use the [await](../../language-reference/operators/await.md) operator in the method. When control reaches an `await` expression in the async method, control returns to the caller, and progress in the method is suspended until the awaited task completes. When the task is complete, execution can resume in the method.

For a simple example, see the "Async Methods" section of [Methods](../classes-and-structs/methods.md). For more information, see [Asynchronous Programming with async and await](../concepts/async/index.md).| diff --git a/docs/csharp/toc.yml b/docs/csharp/toc.yml index 146c165ab2cc8..5411592462535 100644 --- a/docs/csharp/toc.yml +++ b/docs/csharp/toc.yml @@ -993,12 +993,6 @@ items: items: - name: Statement categories href: language-reference/keywords/statement-keywords.md - - name: Selection Statements - items: - - name: if-else - href: language-reference/keywords/if-else.md - - name: switch - href: language-reference/keywords/switch.md - name: Jump Statements items: - name: break @@ -1225,7 +1219,7 @@ items: displayName: stack allocation, span, stackalloc operator - name: switch expression href: language-reference/operators/switch-expression.md - displayName: pattern matching, patterns + displayName: pattern matching, patterns, when - name: true and false operators href: language-reference/operators/true-false-operators.md - name: with expression @@ -1238,6 +1232,9 @@ items: - name: Iteration statements displayName: for, foreach, do, while, loop href: language-reference/statements/iteration-statements.md + - name: Selection statements + displayName: if, else, switch, case, when + href: language-reference/statements/selection-statements.md - name: Special characters items: - name: Overview diff --git a/docs/csharp/tour-of-csharp/tutorials/branches-and-loops-local.md b/docs/csharp/tour-of-csharp/tutorials/branches-and-loops-local.md index 8256723f97799..f4a9e5752dc4b 100644 --- a/docs/csharp/tour-of-csharp/tutorials/branches-and-loops-local.md +++ b/docs/csharp/tour-of-csharp/tutorials/branches-and-loops-local.md @@ -287,5 +287,5 @@ your own development environment. You can learn more about these concepts in these articles: -- [If and else statement](../../language-reference/keywords/if-else.md) +- [Selection statements](../../language-reference/statements/selection-statements.md) - [Iteration statements](../../language-reference/statements/iteration-statements.md) diff --git a/docs/csharp/tour-of-csharp/tutorials/branches-and-loops.yml b/docs/csharp/tour-of-csharp/tutorials/branches-and-loops.yml index 1e080c7bdca60..4cd69f099419c 100644 --- a/docs/csharp/tour-of-csharp/tutorials/branches-and-loops.yml +++ b/docs/csharp/tour-of-csharp/tutorials/branches-and-loops.yml @@ -305,5 +305,5 @@ items: You can learn more about these concepts in these articles: - - [If and else statement](../../language-reference/keywords/if-else.md) + - [Selection statements](../../language-reference/statements/selection-statements.md) - [Iteration statements](../../language-reference/statements/iteration-statements.md) diff --git a/docs/csharp/whats-new/csharp-7.md b/docs/csharp/whats-new/csharp-7.md index 7f02fc5f482b0..979e32779e4f3 100644 --- a/docs/csharp/whats-new/csharp-7.md +++ b/docs/csharp/whats-new/csharp-7.md @@ -100,7 +100,7 @@ Discards are supported in the following scenarios: - When deconstructing tuples or user-defined types. - When calling methods with [out](../language-reference/keywords/out-parameter-modifier.md) parameters. -- In a pattern matching operation with the [is](../language-reference/operators/is.md) and [switch](../language-reference/keywords/switch.md) statements. +- In a pattern matching operation with the [`is` operator](../language-reference/operators/is.md) and [`switch` statement](../language-reference/statements/selection-statements.md#the-switch-statement). - As a standalone identifier when you want to explicitly identify the value of an assignment as a discard. The following example defines a `QueryCityData` method that returns a 3-tuple that contains data for a city for two different years. The method call in the example is concerned only with the two population values returned by the method and so treats the remaining values in the tuple as discards when it deconstructs the tuple. diff --git a/docs/csharp/whats-new/csharp-8.md b/docs/csharp/whats-new/csharp-8.md index b338731402068..869288e7e209d 100644 --- a/docs/csharp/whats-new/csharp-8.md +++ b/docs/csharp/whats-new/csharp-8.md @@ -94,7 +94,7 @@ Default interface methods affect many scenarios and language elements. Our first ## More patterns in more places -**Pattern matching** gives tools to provide shape-dependent functionality across related but different kinds of data. C# 7.0 introduced syntax for type patterns and constant patterns by using the [`is`](../language-reference/operators/is.md) expression and the [`switch`](../language-reference/keywords/switch.md) statement. These features represented the first tentative steps toward supporting programming paradigms where data and functionality live apart. As the industry moves toward more microservices and other cloud-based architectures, other language tools are needed. +**Pattern matching** gives tools to provide shape-dependent functionality across related but different kinds of data. C# 7.0 introduced syntax for type patterns and constant patterns by using the [`is`](../language-reference/operators/is.md) expression and the [`switch`](../language-reference/statements/selection-statements.md#the-switch-statement) statement. These features represented the first tentative steps toward supporting programming paradigms where data and functionality live apart. As the industry moves toward more microservices and other cloud-based architectures, other language tools are needed. C# 8.0 expands this vocabulary so you can use more pattern expressions in more places in your code. Consider these features when your data and functionality are separate. Consider pattern matching when your algorithms depend on a fact other than the runtime type of an object. These techniques provide another way to express designs. @@ -102,7 +102,7 @@ In addition to new patterns in new places, C# 8.0 adds **recursive patterns**. R ### Switch expressions -Often, a [`switch`](../language-reference/keywords/switch.md) statement produces a value in each of its `case` blocks. **Switch expressions** enable you to use more concise expression syntax. There are fewer repetitive `case` and `break` keywords, and fewer curly braces. As an example, consider the following enum that lists the colors of the rainbow: +Often, a [`switch`](../language-reference/statements/selection-statements.md#the-switch-statement) statement produces a value in each of its `case` blocks. **Switch expressions** enable you to use more concise expression syntax. There are fewer repetitive `case` and `break` keywords, and fewer curly braces. As an example, consider the following enum that lists the colors of the rainbow: ```csharp public enum Rainbow diff --git a/docs/fundamentals/code-analysis/style-rules/ide0010.md b/docs/fundamentals/code-analysis/style-rules/ide0010.md index 97fda3d89b211..49b3e2962b315 100644 --- a/docs/fundamentals/code-analysis/style-rules/ide0010.md +++ b/docs/fundamentals/code-analysis/style-rules/ide0010.md @@ -25,10 +25,10 @@ dev_langs: ## Overview -This rule concerns specifying all the missing switch cases for a [switch statement](../../../csharp/language-reference/keywords/switch.md). A switch statement is considered incomplete with missing cases in the following scenarios: +This rule concerns specifying all the missing switch cases for a [`switch` statement](../../../csharp/language-reference/statements/selection-statements.md#the-switch-statement). A `switch` statement is considered incomplete with missing cases in the following scenarios: -- An [enum](../../../csharp/language-reference/builtin-types/enum.md) switch statement which is missing cases for one or more enum members. -- Switch statements missing the [default case](../../../csharp/language-reference/keywords/switch.md#the-default-case). +- An [enum](../../../csharp/language-reference/builtin-types/enum.md) `switch` statement which is missing cases for one or more enum members. +- A `switch` statement with missing `default` case. This rule has no associated code style option. @@ -74,7 +74,7 @@ class C ## See also -- [Switch statement](../../../csharp/language-reference/keywords/switch.md) +- [Switch statement](../../../csharp/language-reference/statements/selection-statements.md#the-switch-statement) - [Add missing cases to switch expression (IDE0072)](ide0072.md) - [Expression-level preferences](expression-level-preferences.md) - [Code style language rules](language-rules.md) diff --git a/docs/fundamentals/code-analysis/style-rules/ide0066.md b/docs/fundamentals/code-analysis/style-rules/ide0066.md index 98cdabcffa975..cb774d52c8f09 100644 --- a/docs/fundamentals/code-analysis/style-rules/ide0066.md +++ b/docs/fundamentals/code-analysis/style-rules/ide0066.md @@ -27,7 +27,7 @@ dev_langs: ## Overview -This style rule concerns the use of [switch expressions](../../../csharp/language-reference/operators/switch-expression.md) versus [switch statements](../../../csharp/language-reference/keywords/switch.md). +This style rule concerns the use of [switch expressions](../../../csharp/language-reference/operators/switch-expression.md) versus [switch statements](../../../csharp/language-reference/statements/selection-statements.md#the-switch-statement). ## csharp_style_prefer_switch_expression diff --git a/samples/snippets/csharp/VS_Snippets_VBCSharp/csrefKeywordsSelection/CS/csrefKeywordsSelection.cs b/samples/snippets/csharp/VS_Snippets_VBCSharp/csrefKeywordsSelection/CS/csrefKeywordsSelection.cs deleted file mode 100644 index e9cbc8194c6df..0000000000000 --- a/samples/snippets/csharp/VS_Snippets_VBCSharp/csrefKeywordsSelection/CS/csrefKeywordsSelection.cs +++ /dev/null @@ -1,288 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace KeywordsUberProject -{ - class csrefKeywordsSelection - { - - static void Main(string[] args) - { - // - bool condition = true; - - if (condition) - { - Console.WriteLine("The variable is set to true."); - } - else - { - Console.WriteLine("The variable is set to false."); - } - // - - // - // Try with m = 12 and then with m = 8. - int m = 12; - int n = 18; - - if (m > 10) - if (n > 20) - { - Console.WriteLine("Result1"); - } - else - { - Console.WriteLine("Result2"); - } - // - - // - // Try with m = 12 and then with m = 8. - if (m > 10) - { - if (n > 20) - Console.WriteLine("Result1"); - } - else - { - Console.WriteLine("Result2"); - } - // - } - } - - class IfTest - { - static void Main() - { - // - Console.Write("Enter a character: "); - char c = (char)Console.Read(); - if (Char.IsLetter(c)) - { - if (Char.IsLower(c)) - { - Console.WriteLine("The character is lowercase."); - } - else - { - Console.WriteLine("The character is uppercase."); - } - } - else - { - Console.WriteLine("The character isn't an alphabetic character."); - } - - //Sample Output: - - //Enter a character: 2 - //The character isn't an alphabetic character. - - //Enter a character: A - //The character is uppercase. - - //Enter a character: h - //The character is lowercase. - // - } - } - - class IfTest2 - { - // values aren't used - bool Condition1 = true; - bool Condition2 = true; - bool Condition3 = true; - bool Condition4 = true; - - void TestMethod() - { - // - // Change the values of these variables to test the results. - bool Condition1 = true; - bool Condition2 = true; - bool Condition3 = true; - bool Condition4 = true; - - if (Condition1) - { - // Condition1 is true. - } - else if (Condition2) - { - // Condition1 is false and Condition2 is true. - } - else if (Condition3) - { - if (Condition4) - { - // Condition1 and Condition2 are false. Condition3 and Condition4 are true. - } - else - { - // Condition1, Condition2, and Condition4 are false. Condition3 is true. - } - } - else - { - // Condition1, Condition2, and Condition3 are false. - } - // - } - } - - public class IfTest3 - { - static void Main() - { - // - Console.Write("Enter a character: "); - char ch = (char)Console.Read(); - - if (Char.IsUpper(ch)) - { - Console.WriteLine("The character is an uppercase letter."); - } - else if (Char.IsLower(ch)) - { - Console.WriteLine("The character is a lowercase letter."); - } - else if (Char.IsDigit(ch)) - { - Console.WriteLine("The character is a number."); - } - else - { - Console.WriteLine("The character is not alphanumeric."); - } - - //Sample Input and Output: - //Enter a character: E - //The character is an uppercase letter. - - //Enter a character: e - //The character is a lowercase letter. - - //Enter a character: 4 - //The character is a number. - - //Enter a character: = - //The character is not alphanumeric. - // - } - } - - class SwitchTest1 - { - - void Test() - { - // removed from topicID 44bae8b8-8841-4d85-826b-8a94277daecb - // on switch statement,left here in case used elsewhere - // - int caseSwitch = 1; - switch (caseSwitch) - { - case 1: - Console.WriteLine("Case 1"); - break; - case 2: - Console.WriteLine("Case 2"); - break; - default: - Console.WriteLine("Default case"); - break; - } - // - } - } - - // - class SwitchTest - { - static void Main() - { - Console.WriteLine("Coffee sizes: 1=small 2=medium 3=large"); - Console.Write("Please enter your selection: "); - string str = Console.ReadLine(); - int cost = 0; - - // Notice the goto statements in cases 2 and 3. The base cost of 25 - // cents is added to the additional cost for the medium and large sizes. - switch (str) - { - case "1": - case "small": - cost += 25; - break; - case "2": - case "medium": - cost += 25; - goto case "1"; - case "3": - case "large": - cost += 50; - goto case "1"; - default: - Console.WriteLine("Invalid selection. Please select 1, 2, or 3."); - break; - } - if (cost != 0) - { - Console.WriteLine("Please insert {0} cents.", cost); - } - Console.WriteLine("Thank you for your business."); - } - } - /* - Sample Input: 2 - - Sample Output: - Coffee sizes: 1=small 2=medium 3=large - Please enter your selection: 2 - Please insert 50 cents. - Thank you for your business. - */ - // - - // - class Program - { - static void Main(string[] args) - { - int switchExpression = 3; - switch (switchExpression) - { - // A switch section can have more than one case label. - case 0: - case 1: - Console.WriteLine("Case 0 or 1"); - // Most switch sections contain a jump statement, such as - // a break, goto, or return. The end of the statement list - // must be unreachable. - break; - case 2: - Console.WriteLine("Case 2"); - break; - // The following line causes a warning. - Console.WriteLine("Unreachable code"); - // 7 - 4 in the following line evaluates to 3. - case 7 - 4: - Console.WriteLine("Case 3"); - break; - // If the value of switchExpression is not 0, 1, 2, or 3, the - // default case is executed. - default: - Console.WriteLine("Default case (optional)"); - // You cannot "fall through" any switch section, including - // the last one. - break; - } - } - } - // -} diff --git a/samples/snippets/csharp/language-reference/keywords/switch/const-pattern.cs b/samples/snippets/csharp/language-reference/keywords/switch/const-pattern.cs deleted file mode 100644 index 6d213a45d2397..0000000000000 --- a/samples/snippets/csharp/language-reference/keywords/switch/const-pattern.cs +++ /dev/null @@ -1,28 +0,0 @@ -// -using System; - -class Program -{ - static void Main() - { - switch (DateTime.Now.DayOfWeek) - { - case DayOfWeek.Sunday: - case DayOfWeek.Saturday: - Console.WriteLine("The weekend"); - break; - case DayOfWeek.Monday: - Console.WriteLine("The first day of the work week."); - break; - case DayOfWeek.Friday: - Console.WriteLine("The last day of the work week."); - break; - default: - Console.WriteLine("The middle of the work week."); - break; - } - } -} -// The example displays output like the following: -// The middle of the work week. -// diff --git a/samples/snippets/csharp/language-reference/keywords/switch/switch1.cs b/samples/snippets/csharp/language-reference/keywords/switch/switch1.cs deleted file mode 100644 index 0698214cd17bd..0000000000000 --- a/samples/snippets/csharp/language-reference/keywords/switch/switch1.cs +++ /dev/null @@ -1,26 +0,0 @@ -// -using System; - -public class Example -{ - public static void Main() - { - int caseSwitch = 1; - - switch (caseSwitch) - { - case 1: - Console.WriteLine("Case 1"); - break; - case 2: - Console.WriteLine("Case 2"); - break; - default: - Console.WriteLine("Default case"); - break; - } - } -} -// The example displays the following output: -// Case 1 -// diff --git a/samples/snippets/csharp/language-reference/keywords/switch/switch2.cs b/samples/snippets/csharp/language-reference/keywords/switch/switch2.cs deleted file mode 100644 index 1151f0427e86c..0000000000000 --- a/samples/snippets/csharp/language-reference/keywords/switch/switch2.cs +++ /dev/null @@ -1,28 +0,0 @@ -// -using System; - -public class Example -{ - public static void Main() - { - Random rnd = new Random(); - int caseSwitch = rnd.Next(1,4); - - switch (caseSwitch) - { - case 1: - Console.WriteLine("Case 1"); - break; - case 2: - case 3: - Console.WriteLine($"Case {caseSwitch}"); - break; - default: - Console.WriteLine($"An unexpected value ({caseSwitch})"); - break; - } - } -} -// The example displays output like the following: -// Case 1 -// diff --git a/samples/snippets/csharp/language-reference/keywords/switch/switch3.cs b/samples/snippets/csharp/language-reference/keywords/switch/switch3.cs deleted file mode 100644 index 5eb3a03b4b63c..0000000000000 --- a/samples/snippets/csharp/language-reference/keywords/switch/switch3.cs +++ /dev/null @@ -1,28 +0,0 @@ -// -using System; - -public enum Color { Red, Green, Blue } - -public class Example -{ - public static void Main() - { - Color c = (Color) (new Random()).Next(0, 3); - switch (c) - { - case Color.Red: - Console.WriteLine("The color is red"); - break; - case Color.Green: - Console.WriteLine("The color is green"); - break; - case Color.Blue: - Console.WriteLine("The color is blue"); - break; - default: - Console.WriteLine("The color is unknown."); - break; - } - } -} -// diff --git a/samples/snippets/csharp/language-reference/keywords/switch/switch3a.cs b/samples/snippets/csharp/language-reference/keywords/switch/switch3a.cs deleted file mode 100644 index fbe53acefd966..0000000000000 --- a/samples/snippets/csharp/language-reference/keywords/switch/switch3a.cs +++ /dev/null @@ -1,23 +0,0 @@ -// -using System; - -public enum Color { Red, Green, Blue } - -public class Example -{ - public static void Main() - { - Color c = (Color) (new Random()).Next(0, 3); - if (c == Color.Red) - Console.WriteLine("The color is red"); - else if (c == Color.Green) - Console.WriteLine("The color is green"); - else if (c == Color.Blue) - Console.WriteLine("The color is blue"); - else - Console.WriteLine("The color is unknown."); - } -} -// The example displays the following output: -// The color is red -// diff --git a/samples/snippets/csharp/language-reference/keywords/switch/switch4.cs b/samples/snippets/csharp/language-reference/keywords/switch/switch4.cs deleted file mode 100644 index 354f2e008b9da..0000000000000 --- a/samples/snippets/csharp/language-reference/keywords/switch/switch4.cs +++ /dev/null @@ -1,27 +0,0 @@ -using System; - -public class Example -{ - public static void Main() - { - int caseSwitch = 1; - // - switch (caseSwitch) - { - case 1: - Console.WriteLine("Case 1..."); - break; - case 2: - case 3: - Console.WriteLine("... and/or Case 2"); - break; - case 4: - while (true) - Console.WriteLine("Endless looping. . . ."); - default: - Console.WriteLine("Default value..."); - break; - } - // - } -} diff --git a/samples/snippets/csharp/language-reference/keywords/switch/switch5.cs b/samples/snippets/csharp/language-reference/keywords/switch/switch5.cs deleted file mode 100644 index 4b4eb65269a0c..0000000000000 --- a/samples/snippets/csharp/language-reference/keywords/switch/switch5.cs +++ /dev/null @@ -1,85 +0,0 @@ -// -using System; -using System.Collections.Generic; -using System.Linq; - -public class Example -{ - public static void Main() - { - var values = new List(); - for (int ctr = 0; ctr <= 7; ctr++) { - if (ctr == 2) - values.Add(DiceLibrary.Roll2()); - else if (ctr == 4) - values.Add(DiceLibrary.Pass()); - else - values.Add(DiceLibrary.Roll()); - } - - Console.WriteLine($"The sum of { values.Count } die is { DiceLibrary.DiceSum(values) }"); - } -} - -public static class DiceLibrary -{ - // Random number generator to simulate dice rolls. - static Random rnd = new Random(); - - // Roll a single die. - public static int Roll() - { - return rnd.Next(1, 7); - } - - // Roll two dice. - public static List Roll2() - { - var rolls = new List(); - rolls.Add(Roll()); - rolls.Add(Roll()); - return rolls; - } - - // Calculate the sum of n dice rolls. - public static int DiceSum(IEnumerable values) - { - var sum = 0; - foreach (var item in values) - { - switch (item) - { - // A single zero value. - case 0: - break; - // A single value. - case int val: - sum += val; - break; - // A non-empty collection. - case IEnumerable subList when subList.Any(): - sum += DiceSum(subList); - break; - // An empty collection. - case IEnumerable subList: - break; - // A null reference. - case null: - break; - // A value that is neither an integer nor a collection. - default: - throw new InvalidOperationException("unknown item type"); - } - } - return sum; - } - - public static object Pass() - { - if (rnd.Next(0, 2) == 0) - return null; - else - return new List(); - } -} -// diff --git a/samples/snippets/csharp/language-reference/keywords/switch/switch6.cs b/samples/snippets/csharp/language-reference/keywords/switch/switch6.cs deleted file mode 100644 index c7d41e9131934..0000000000000 --- a/samples/snippets/csharp/language-reference/keywords/switch/switch6.cs +++ /dev/null @@ -1,43 +0,0 @@ -using System; - -class Example -{ - static void Main() - { - Console.WriteLine("Coffee sizes: 1=small 2=medium 3=large"); - Console.Write("Please enter your selection: "); - string str = Console.ReadLine(); - int cost = 0; - - // Because of the goto statements in cases 2 and 3, the base cost of 25 - // cents is added to the additional cost for the medium and large sizes. - switch (str) - { - case "1": - case "small": - cost += 25; - break; - case "2": - case "medium": - cost += 25; - goto case "1"; - case "3": - case "large": - cost += 50; - goto case "1"; - default: - Console.WriteLine("Invalid selection. Please select 1, 2, or 3."); - break; - } - if (cost != 0) - { - Console.WriteLine("Please insert {0} cents.", cost); - } - Console.WriteLine("Thank you for your business."); - } -} -// The example displays output like the following: -// Coffee sizes: 1=small 2=medium 3=large -// Please enter your selection: 2 -// Please insert 50 cents. -// Thank you for your business. diff --git a/samples/snippets/csharp/language-reference/keywords/switch/type-pattern.cs b/samples/snippets/csharp/language-reference/keywords/switch/type-pattern.cs deleted file mode 100644 index ad76076f90a80..0000000000000 --- a/samples/snippets/csharp/language-reference/keywords/switch/type-pattern.cs +++ /dev/null @@ -1,53 +0,0 @@ -// -using System; -using System.Collections; -using System.Collections.Generic; -using System.Linq; - -class Example -{ - static void Main(string[] args) - { - int[] values = { 2, 4, 6, 8, 10 }; - ShowCollectionInformation(values); - - var names = new List(); - names.AddRange(new string[] { "Adam", "Abigail", "Bertrand", "Bridgette" }); - ShowCollectionInformation(names); - - List numbers = null; - ShowCollectionInformation(numbers); - } - - private static void ShowCollectionInformation(object coll) - { - switch (coll) - { - case Array arr: - Console.WriteLine($"An array with {arr.Length} elements."); - break; - case IEnumerable ieInt: - Console.WriteLine($"Average: {ieInt.Average(s => s)}"); - break; - case IList list: - Console.WriteLine($"{list.Count} items"); - break; - case IEnumerable ie: - string result = ""; - foreach (var e in ie) - result += $"{e} "; - Console.WriteLine(result); - break; - case null: - // Do nothing for a null. - break; - default: - Console.WriteLine($"A instance of type {coll.GetType().Name}"); - break; - } - } -} -// The example displays the following output: -// An array with 5 elements. -// 4 items -// diff --git a/samples/snippets/csharp/language-reference/keywords/switch/type-pattern2.cs b/samples/snippets/csharp/language-reference/keywords/switch/type-pattern2.cs deleted file mode 100644 index eee7463e76ded..0000000000000 --- a/samples/snippets/csharp/language-reference/keywords/switch/type-pattern2.cs +++ /dev/null @@ -1,60 +0,0 @@ -// -using System; -using System.Collections; -using System.Collections.Generic; -using System.Linq; - -class Example -{ - static void Main(string[] args) - { - int[] values = { 2, 4, 6, 8, 10 }; - ShowCollectionInformation(values); - - var names = new List(); - names.AddRange(new string[] { "Adam", "Abigail", "Bertrand", "Bridgette" }); - ShowCollectionInformation(names); - - List numbers = null; - ShowCollectionInformation(numbers); - } - - private static void ShowCollectionInformation(object coll) - { - if (coll is Array) - { - Array arr = (Array) coll; - Console.WriteLine($"An array with {arr.Length} elements."); - } - else if (coll is IEnumerable) - { - IEnumerable ieInt = (IEnumerable) coll; - Console.WriteLine($"Average: {ieInt.Average(s => s)}"); - } - else if (coll is IList) - { - IList list = (IList) coll; - Console.WriteLine($"{list.Count} items"); - } - else if (coll is IEnumerable) - { - IEnumerable ie = (IEnumerable) coll; - string result = ""; - foreach (var e in ie) - result += $"{e} "; - Console.WriteLine(result); - } - else if (coll == null) - { - // Do nothing. - } - else - { - Console.WriteLine($"An instance of type {coll.GetType().Name}"); - } - } -} -// The example displays the following output: -// An array with 5 elements. -// 4 items -// diff --git a/samples/snippets/csharp/language-reference/keywords/switch/type-pattern3.cs b/samples/snippets/csharp/language-reference/keywords/switch/type-pattern3.cs deleted file mode 100644 index aa406b5e8ca78..0000000000000 --- a/samples/snippets/csharp/language-reference/keywords/switch/type-pattern3.cs +++ /dev/null @@ -1,54 +0,0 @@ -// -using System; -using System.Collections; -using System.Collections.Generic; -using System.Linq; - -class Example -{ - static void Main(string[] args) - { - int[] values = { 2, 4, 6, 8, 10 }; - ShowCollectionInformation(values); - - var names = new List(); - names.AddRange(new string[] { "Adam", "Abigail", "Bertrand", "Bridgette" }); - ShowCollectionInformation(names); - - List numbers = null; - ShowCollectionInformation(numbers); - } - - private static void ShowCollectionInformation(T coll) - { - switch (coll) - { - case Array arr: - Console.WriteLine($"An array with {arr.Length} elements."); - break; - case IEnumerable ieInt: - Console.WriteLine($"Average: {ieInt.Average(s => s)}"); - break; - case IList list: - Console.WriteLine($"{list.Count} items"); - break; - case IEnumerable ie: - string result = ""; - foreach (var e in ie) - result += $"{e} "; - Console.WriteLine(result); - break; - case object o: - Console.WriteLine($"A instance of type {o.GetType().Name}"); - break; - default: - Console.WriteLine("Null passed to this method."); - break; - } - } -} -// The example displays the following output: -// An array with 5 elements. -// 4 items -// Null passed to this method. -// diff --git a/samples/snippets/csharp/language-reference/keywords/switch/when-clause.cs b/samples/snippets/csharp/language-reference/keywords/switch/when-clause.cs deleted file mode 100644 index 9b3ecb04e539a..0000000000000 --- a/samples/snippets/csharp/language-reference/keywords/switch/when-clause.cs +++ /dev/null @@ -1,125 +0,0 @@ -// -using System; - -public abstract class Shape -{ - public abstract double Area { get; } - public abstract double Circumference { get; } -} - -public class Rectangle : Shape -{ - public Rectangle(double length, double width) - { - Length = length; - Width = width; - } - - public double Length { get; set; } - public double Width { get; set; } - - public override double Area - { - get { return Math.Round(Length * Width,2); } - } - - public override double Circumference - { - get { return (Length + Width) * 2; } - } -} - -public class Square : Rectangle -{ - public Square(double side) : base(side, side) - { - Side = side; - } - - public double Side { get; set; } -} - -public class Circle : Shape -{ - public Circle(double radius) - { - Radius = radius; - } - - public double Radius { get; set; } - - public override double Circumference - { - get { return 2 * Math.PI * Radius; } - } - - public override double Area - { - get { return Math.PI * Math.Pow(Radius, 2); } - } -} - -public class Example -{ - public static void Main() - { - Shape sh = null; - Shape[] shapes = { new Square(10), new Rectangle(5, 7), - sh, new Square(0), new Rectangle(8, 8), - new Circle(3) }; - foreach (var shape in shapes) - ShowShapeInfo(shape); - } - - private static void ShowShapeInfo(Shape sh) - { - switch (sh) - { - // Note that this code never evaluates to true. - case Shape shape when shape == null: - Console.WriteLine($"An uninitialized shape (shape == null)"); - break; - case null: - Console.WriteLine($"An uninitialized shape"); - break; - case Shape shape when sh.Area == 0: - Console.WriteLine($"The shape: {sh.GetType().Name} with no dimensions"); - break; - case Square sq when sh.Area > 0: - Console.WriteLine("Information about square:"); - Console.WriteLine($" Length of a side: {sq.Side}"); - Console.WriteLine($" Area: {sq.Area}"); - break; - case Rectangle r when r.Length == r.Width && r.Area > 0: - Console.WriteLine("Information about square rectangle:"); - Console.WriteLine($" Length of a side: {r.Length}"); - Console.WriteLine($" Area: {r.Area}"); - break; - case Rectangle r when sh.Area > 0: - Console.WriteLine("Information about rectangle:"); - Console.WriteLine($" Dimensions: {r.Length} x {r.Width}"); - Console.WriteLine($" Area: {r.Area}"); - break; - case Shape shape when sh != null: - Console.WriteLine($"A {sh.GetType().Name} shape"); - break; - default: - Console.WriteLine($"The {nameof(sh)} variable does not represent a Shape."); - break; - } - } -} -// The example displays the following output: -// Information about square: -// Length of a side: 10 -// Area: 100 -// Information about rectangle: -// Dimensions: 5 x 7 -// Area: 35 -// An uninitialized shape -// The shape: Square with no dimensions -// Information about square rectangle: -// Length of a side: 8 -// Area: 64 -// A Circle shape -// diff --git a/samples/snippets/csharp/language-reference/keywords/when/when.cs b/samples/snippets/csharp/language-reference/keywords/when/when.cs deleted file mode 100644 index fdc1dfdfcaa02..0000000000000 --- a/samples/snippets/csharp/language-reference/keywords/when/when.cs +++ /dev/null @@ -1,94 +0,0 @@ -// -using System; - -public abstract class Shape -{ - public abstract double Area { get; } - public abstract double Circumference { get; } -} - -public class Rectangle : Shape -{ - public Rectangle(double length, double width) - { - Length = length; - Width = width; - } - - public double Length { get; set; } - public double Width { get; set; } - - public override double Area - { - get { return Math.Round(Length * Width,2); } - } - - public override double Circumference - { - get { return (Length + Width) * 2; } - } -} - -public class Square : Rectangle -{ - public Square(double side) : base(side, side) - { - Side = side; - } - - public double Side { get; set; } -} - -public class Example -{ - public static void Main() - { - Shape sh = null; - Shape[] shapes = { new Square(10), new Rectangle(5, 7), - new Rectangle(10, 10), sh, new Square(0) }; - foreach (var shape in shapes) - ShowShapeInfo(shape); - } - - private static void ShowShapeInfo(Object obj) - { - switch (obj) - { - case Shape shape when shape.Area == 0: - Console.WriteLine($"The shape: {shape.GetType().Name} with no dimensions"); - break; - case Square sq when sq.Area > 0: - Console.WriteLine("Information about the square:"); - Console.WriteLine($" Length of a side: {sq.Side}"); - Console.WriteLine($" Area: {sq.Area}"); - break; - case Rectangle r when r.Area > 0: - Console.WriteLine("Information about the rectangle:"); - Console.WriteLine($" Dimensions: {r.Length} x {r.Width}"); - Console.WriteLine($" Area: {r.Area}"); - break; - case Shape shape: - Console.WriteLine($"A {shape.GetType().Name} shape"); - break; - case null: - Console.WriteLine($"The {nameof(obj)} variable is uninitialized."); - break; - default: - Console.WriteLine($"The {nameof(obj)} variable does not represent a Shape."); - break; - } - } -} -// The example displays the following output: -// Information about the square: -// Length of a side: 10 -// Area: 100 -// Information about the rectangle: -// Dimensions: 5 x 7 -// Area: 35 -// Information about the rectangle: -// Dimensions: 10 x 10 -// Area: 100 -// The obj variable is uninitialized. -// The shape: Square with no dimensions -//