Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 37 additions & 39 deletions standard/statements.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ The *embedded_statement* nonterminal is used for statements that appear within o

> *Example*: The code
>
> <!-- Example: {template:"standalone-console", name:"Statements", expectedErrors:["CS1023"], ignoredWarnings:["CS8321","CS0219"]} -->
> <!-- Example: {template:"standalone-console-without-using", name:"Statements", expectedErrors:["CS1023"], ignoredWarnings:["CS8321","CS0219"]} -->
> ```csharp
> void F(bool b)
> {
Expand All @@ -60,7 +60,7 @@ If a statement can possibly be reached by execution, the statement is said to be

> *Example*: In the following code
>
> <!-- IncompleteExample: {template:"standalone-console", name:"Reachability1", expectedWarnings:["CS0162","CS8321"]} -->
> <!-- Example: {template:"standalone-console", name:"Reachability1", expectedWarnings:["CS8321","CS0162"]} -->
> ```csharp
> void F()
> {
Expand All @@ -82,7 +82,7 @@ A warning is reported if a statement other than *throw_statement*, *block*, or *
>
> In the example
>
> <!-- IncompleteExample: {template:"standalone-console", name:"Reachability2", expectedWarnings:["CS0162","CS8321"]} -->
> <!-- Example: {template:"standalone-console", name:"Reachability2", expectedWarnings:["CS8321","CS0162"]} -->
> ```csharp
> void F()
> {
Expand All @@ -94,7 +94,7 @@ A warning is reported if a statement other than *throw_statement*, *block*, or *
>
> the Boolean expression of the `if` statement is a constant expression because both operands of the `==` operator are constants. As the constant expression is evaluated at compile-time, producing the value `false`, the `Console.WriteLine` invocation is considered unreachable. However, if `i` is changed to be a local variable
>
> <!-- IncompleteExample: {template:"standalone-console", name:"Reachability3", expectedWarnings:["CS8321"]} -->
> <!-- Example: {template:"standalone-console", name:"Reachability3", expectedWarnings:["CS8321"]} -->
> ```csharp
> void F()
> {
Expand All @@ -112,7 +112,7 @@ The *block* of a function member or an anonymous function is always considered r

> *Example*: In the following code
>
> <!-- IncompleteExample: {template:"standalone-console", name:"Reachability4", expectedWarnings:["CS8321"]} -->
> <!-- Example: {template:"standalone-console", name:"Reachability4", expectedWarnings:["CS8321"]} -->
> ```csharp
> void F(int x)
> {
Expand Down Expand Up @@ -203,7 +203,7 @@ Execution of an empty statement simply transfers control to the end point of the

> *Example*: An empty statement can be used when writing a `while` statement with a null body:
>
> <!-- IncompleteExample: {template:"standalone-console", name:"EmptyStatement1", replaceEllipsis:true, expectedWarnings:["CS8321]} -->
> <!-- Example: {template:"standalone-console-without-using", name:"EmptyStatement1", replaceEllipsis:true, customEllipsisReplacements: ["return true;"], expectedWarnings:["CS8321"]} -->
> ```csharp
> bool ProcessMessage() {...}
> void ProcessMessages()
Expand All @@ -215,7 +215,7 @@ Execution of an empty statement simply transfers control to the end point of the
>
> Also, an empty statement can be used to declare a label just before the closing “`}`” of a block:
>
> <!-- Example: {template:"standalone-console", name:"EmptyStatement2", replaceEllipsis:true, expectedWarnings:["CS8321"]} -->
> <!-- Example: {template:"standalone-console-without-using", name:"EmptyStatement2", replaceEllipsis:true, expectedWarnings:["CS8321"]} -->
> ```csharp
> void F(bool done)
> {
Expand Down Expand Up @@ -252,7 +252,7 @@ Labels have their own declaration space and do not interfere with other identifi

> *Example*: The example
>
> <!-- Example: {template:"standalone-console", name:"LabeledStatements", expectedWarnings:["CS8321"]} -->
> <!-- Example: {template:"standalone-console-without-using", name:"LabeledStatements", expectedWarnings:["CS8321"]} -->
> ```csharp
> int F(int x)
> {
Expand Down Expand Up @@ -335,7 +335,7 @@ In the context of a local variable declaration, the identifier `var` acts as a c

> *Example*: The following are incorrect implicitly typed local variable declarations:
>
> <!-- Example: {template:"standalone-console", name:"LocalVariableDecls1", expectedErrors:["CS0818","CS0820","CS0815","CS8917","CS0841"], ignoredWarnings:["CS0168"]} -->
> <!-- Example: {template:"standalone-console-without-using", name:"LocalVariableDecls1", expectedErrors:["CS0818","CS0820","CS0815","CS8917","CS0841"], ignoredWarnings:["CS0168"]} -->
> ```csharp
> var x; // Error, no initializer to infer type from
> var y = {1, 2, 3}; // Error, array initializer not permitted
Expand All @@ -354,7 +354,7 @@ A local variable declaration that declares multiple variables is equivalent to m

> *Example*: The example
>
> <!-- Example: {template:"standalone-console", name:"LocalVariableDecls2", ignoredWarnings:["CS0168","CS8321"]} -->
> <!-- Example: {template:"standalone-console-without-using", name:"LocalVariableDecls2", ignoredWarnings:["CS0168","CS8321"]} -->
> ```csharp
> void F()
> {
Expand All @@ -364,7 +364,7 @@ A local variable declaration that declares multiple variables is equivalent to m
>
> corresponds exactly to
>
> <!-- Example: {template:"standalone-console", name:"LocalVariableDecls3", ignoredWarnings:["CS0168","CS8321"]} -->
> <!-- Example: {template:"standalone-console-without-using", name:"LocalVariableDecls3", ignoredWarnings:["CS0168","CS8321"]} -->
> ```csharp
> void F()
> {
Expand All @@ -380,7 +380,7 @@ In an implicitly typed local variable declaration, the type of the local variabl

> *Example*:
>
> <!-- IncompleteExample: {template:"standalone-console", name:"LocalVariableDecls4", expectedWarnings:["CS0219","CS0219","CS0219"]} -->
> <!-- Example: {template:"code-in-main", name:"LocalVariableDecls4", additionalFiles:["Order.cs"], expectedWarnings:["CS0219","CS0219","CS0219"]} -->
> ```csharp
> var i = 5;
> var s = "Hello";
Expand All @@ -391,7 +391,7 @@ In an implicitly typed local variable declaration, the type of the local variabl
>
> The implicitly typed local variable declarations above are precisely equivalent to the following explicitly typed declarations:
>
> <!-- IncompleteExample: {template:"standalone-console", name:"LocalVariableDecls5", expectedWarnings:["CS0219","CS0219","CS0219"]} -->
> <!-- Example: {template:"code-in-main", name:"LocalVariableDecls5", additionalFiles:["Order.cs"], expectedWarnings:["CS0219","CS0219","CS0219"]} -->
> ```csharp
> int i = 5;
> string s = "Hello";
Expand Down Expand Up @@ -459,7 +459,7 @@ Grammar note: When recognising a *local_function_body* if both the *null_conditi

> *Example*: There are two common use cases for local functions: iterator methods and async methods. In iterator methods, any exceptions are observed only when calling code that enumerates the returned sequence. In async methods, any exceptions are only observed when the returned Task is awaited. The following example demonstrates separating parameter validation from the iterator implementation using a local function:
>
> <!-- IncompleteExample: {template:"standalone-console", name:"LocalFunctionDeclarations1", expectedWarnings:["xx","xx"]} -->
> <!-- Example: {template:"code-in-class-lib", name:"LocalFunctionDeclarations1"} -->
> ```csharp
> public static IEnumerable<char> AlphabetSubset(char start, char end)
> {
Expand Down Expand Up @@ -505,7 +505,7 @@ Local function bodies are always reachable. The endpoint of a local function dec

> *Example*: In the following example, the body of `L` is reachable even though the beginning point of `L` is not reachable. Because the beginning point of `L` isn’t reachable, the statement following the endpoint of `L` is not reachable:
>
> <!-- IncompleteExample: {template:"standalone-console", name:"LocalFunctionDeclarations2", expectedWarnings:["xx","xx"]} -->
> <!-- Example: {template:"standalone-lib-without-using", name:"LocalFunctionDeclarations2", expectedWarnings:["CS0162"]} -->
> ```csharp
> class C
> {
Expand Down Expand Up @@ -583,14 +583,16 @@ An `else` part is associated with the lexically nearest preceding `if` that is a

> *Example*: Thus, an `if` statement of the form
>
> <!-- IncompleteExample: {template:"standalone-console", name:"IfStatement1", expectedErrors:["x","x"], expectedWarnings:["x","x"]} -->
> <!-- Incomplete$Example: {template:"standalone-console", name:"IfStatement1", expectedErrors:["x","x"], expectedWarnings:["x","x"]} -->
> <!-- FIX: needs defs for x, y, F and G. -->
> ```csharp
> if (x) if (y) F(); else G();
> ```
>
> is equivalent to
>
> <!-- IncompleteExample: {template:"standalone-console", name:"IfStatement2", expectedErrors:["x","x"], expectedWarnings:["x","x"]} -->
> <!-- Incomplete$Example: {template:"standalone-console", name:"IfStatement2", expectedErrors:["x","x"], expectedWarnings:["x","x"]} -->
> <!-- FIX: needs defs for x, y, F and G. -->
> ```csharp
> if (x)
> {
Expand Down Expand Up @@ -666,7 +668,8 @@ If the end point of the statement list of a switch section is reachable, a compi

> *Example*: The example
>
> <!-- IncompleteExample: {template:"standalone-console", name:"SwitchStatement1", expectedErrors:["x","x"], expectedWarnings:["x","x"]} -->
> <!-- Incomplete$Example: {template:"standalone-console", name:"SwitchStatement1", expectedErrors:["x","x"], expectedWarnings:["x","x"]} -->
> <!-- FIX: needs defs for i, CaseZero, CaseOne, and CaseOthers. -->
> ```csharp
> switch (i)
> {
Expand All @@ -684,7 +687,8 @@ If the end point of the statement list of a switch section is reachable, a compi
>
> is valid because no switch section has a reachable end point. Unlike C and C++, execution of a switch section is not permitted to “fall through” to the next switch section, and the example
>
> <!-- IncompleteExample: {template:"standalone-console", name:"SwitchStatement2", expectedErrors:["CS0163","CS0163","CS8070"]} -->
> <!-- Incomplete$Example: {template:"standalone-console", name:"SwitchStatement2", expectedErrors:["CS0163","CS0163","CS8070"]} -->
> <!-- FIX: needs defs for i, CaseZero, CaseZeroOrOne, and CaseAny. -->
> ```csharp
> switch (i)
> {
Expand All @@ -699,7 +703,8 @@ If the end point of the statement list of a switch section is reachable, a compi
>
> results in a compile-time error. When execution of a switch section is to be followed by execution of another switch section, an explicit `goto case` or `goto default` statement shall be used:
>
> <!-- IncompleteExample: {template:"standalone-console", name:"SwitchStatement3"} -->
> <!-- Incomplete$Example: {template:"standalone-console", name:"SwitchStatement3"} -->
> <!-- FIX: needs defs for i, CaseZero, CaseZeroOrOne, and CaseAny. -->
> ```csharp
> switch (i)
> {
Expand All @@ -721,7 +726,8 @@ Multiple labels are permitted in a *switch_section*.

> *Example*: The example
>
> <!-- IncompleteExample: {template:"standalone-console", name:"SwitchStatement4"} -->
> <!-- Incomplete$Example: {template:"standalone-console", name:"SwitchStatement4"} -->
> <!-- FIX: needs defs for i, CaseZero, CaseOne, and CaseTwo. -->
> ```csharp
> switch (i)
> {
Expand All @@ -746,7 +752,8 @@ Multiple labels are permitted in a *switch_section*.
<!-- markdownlint-enable MD028 -->
> *Note*: The “no fall through” rule prevents a common class of bugs that occur in C and C++ when `break` statements are accidentally omitted. For example, the sections of the `switch` statement above can be reversed without affecting the behavior of the statement:
>
> <!-- IncompleteExample: {template:"standalone-console", name:"SwitchStatement5"]} -->
> <!-- Incomplete$Example: {template:"standalone-console", name:"SwitchStatement5"]} -->
> <!-- FIX: needs defs for i, CaseZero, CaseZeroOrOne, and CaseAny. -->
> ```csharp
> switch (i)
> {
Expand All @@ -768,7 +775,8 @@ Multiple labels are permitted in a *switch_section*.
<!-- markdownlint-enable MD028 -->
> *Note*: The statement list of a switch section typically ends in a `break`, `goto case`, or `goto default` statement, but any construct that renders the end point of the statement list unreachable is permitted. For example, a `while` statement controlled by the Boolean expression `true` is known to never reach its end point. Likewise, a `throw` or `return` statement always transfers control elsewhere and never reaches its end point. Thus, the following example is valid:
>
> <!-- IncompleteExample: {template:"standalone-console", name:"SwitchStatement6"} -->
> <!-- Incomplete$Example: {template:"standalone-console", name:"SwitchStatement6"} -->
> <!-- FIX: needs defs for i, F. -->
> ```csharp
> switch (i)
> {
Expand All @@ -790,7 +798,8 @@ Multiple labels are permitted in a *switch_section*.
<!-- markdownlint-enable MD028 -->
> *Example*: The governing type of a `switch` statement can be the type `string`. For example:
>
> <!-- IncompleteExample: {template:"standalone-console", name:"SwitchStatement7", expectedWarnings:["CS8321"]} -->
> <!-- Incomplete$Example: {template:"standalone-console", name:"SwitchStatement7", expectedWarnings:["CS8321"]} -->
> <!-- FIX: top-level must be a console, but then it has no named parent class type, so can't implement Do* as extension methods. -->
> ```csharp
> void DoCommand(string command)
> {
Expand Down Expand Up @@ -1020,7 +1029,7 @@ The placement of `v` inside the `while` loop is important for how it is captured

> *Example*:
>
> <!-- IncompleteExample: {template:"standalone-console", name:"ForeachStatement1", expectedErrors:["x","x"], expectedWarnings:["x","x"]} -->
> <!-- Example: {template:"code-in-main", name:"ForeachStatement1", expectedOutput:["First value: 7"]} -->
> ```csharp
> int[] values = { 7, 9, 13 };
> Action f = null;
Expand Down Expand Up @@ -1091,7 +1100,6 @@ The order in which `foreach` traverses the elements of an array, is as follows:
>
> <!-- Example: {template:"standalone-console", name:"ForeachStatement2", replaceEllipsis:true, inferOutput:true} -->
> ```csharp
> using System;
> class Test
> {
> static void Main()
Expand Down Expand Up @@ -1127,7 +1135,7 @@ The order in which `foreach` traverses the elements of an array, is as follows:
> int[] numbers = { 1, 3, 5, 7, 9 };
> foreach (var n in numbers)
> {
> System.Console.WriteLine(n);
> Console.WriteLine(n);
> }
> ```
>
Expand Down Expand Up @@ -1161,7 +1169,6 @@ Execution of jump statements is complicated by the presence of intervening `try`
>
> <!-- Example: {template:"standalone-console", name:"JumpStatements", inferOutput:true} -->
> ```csharp
> using System;
> class Test
> {
> static void Main()
Expand Down Expand Up @@ -1266,8 +1273,6 @@ The target of a `goto` *identifier* statement is the labeled statement with the
>
> <!-- Example: {template:"standalone-console", name:"GotoStatement"} -->
> ```csharp
> using System;
>
> class Test
> {
> static void Main(string[] args)
Expand Down Expand Up @@ -1431,8 +1436,6 @@ Within a `catch` block, a `throw` statement ([§12.10.6](statements.md#12106-the
>
> <!-- Example: {template:"standalone-console", name:"TryStatement1", inferOutput:true} -->
> ```csharp
> using System;
>
> class Test
> {
> static void F()
Expand Down Expand Up @@ -1501,8 +1504,6 @@ If an exception is thrown during execution of a `finally` block, and is not caug
>
> <!-- Example: {template:"standalone-console", name:"TryStatement2", inferOutput:true} -->
> ```csharp
> using System;
>
> public class Test
> {
> static void Main()
Expand Down Expand Up @@ -1731,11 +1732,8 @@ using (ResourceType rN = eN)

> *Example*: The example below creates a file named log.txt and writes two lines of text to the file. The example then opens that same file for reading and copies the contained lines of text to the console.
>
> <!-- IncompleteExample: {template:"standalone-console", name:"UsingStatement", expectedErrors:["x","x"], expectedWarnings:["x","x"]} -->
> <!-- Example: {template:"standalone-console", name:"UsingStatement"} -->
> ```csharp
> using System;
> using System.IO;
>
> class Test
> {
> static void Main()
Expand Down Expand Up @@ -1783,7 +1781,7 @@ There are several restrictions on where a `yield` statement can appear, as descr

> *Example*: The following example shows some valid and invalid uses of `yield` statements.
>
> <!-- IncompleteExample: {template:"standalone-console", name:"YieldStatement", expectedErrors:["x","x"], expectedWarnings:["x","x"]} -->
> <!-- Example: {template:"code-in-class-lib-without-using", name:"YieldStatement", expectedErrors:["CS1625","CS1625","CS1626","CS1631","CS1643","CS1621","CS1624"], expectedWarnings:["CS0162"]} -->
> ```csharp
> delegate IEnumerable<int> D();
>
Expand Down