Statements

C#에서는 다양 한 문을 제공 합니다.C# provides a variety of statements. 이러한 문은 대부분 C 및 C++에서 프로그래밍 한 개발자에 게 친숙 합니다.Most of these statements will be familiar to developers who have programmed in C and C++.

statement
    : labeled_statement
    | declaration_statement
    | embedded_statement
    ;

embedded_statement
    : block
    | empty_statement
    | expression_statement
    | selection_statement
    | iteration_statement
    | jump_statement
    | try_statement
    | checked_statement
    | unchecked_statement
    | lock_statement
    | using_statement
    | yield_statement
    | embedded_statement_unsafe
    ;

Embedded_statement 비터미널는 다른 문 내에 표시 되는 문에 사용 됩니다.The embedded_statement nonterminal is used for statements that appear within other statements. 대신 embedded_statement 를 사용 하면 이러한 컨텍스트에서 선언 문과 레이블 문 사용이 제외 됩니다.The use of embedded_statement rather than statement excludes the use of declaration statements and labeled statements in these contexts. 예제The example

void F(bool b) {
    if (b)
        int i = 44;
}

if 문에 if 분기에 대 한 문이 아닌 embedded_statement 가 필요 하기 때문에 컴파일 시간 오류가 발생 합니다.results in a compile-time error because an if statement requires an embedded_statement rather than a statement for its if branch. 이 코드가 허용 된 경우 변수 i 는 선언 되지만 사용할 수는 없습니다.If this code were permitted, then the variable i would be declared, but it could never be used. 그러나를 블록에 배치 i하 여 예제를 사용할 수 있습니다.Note, however, that by placing i's declaration in a block, the example is valid.

끝점 및 연결 가능성End points and reachability

모든 문에는 끝점이있습니다.Every statement has an end point. 직관적인 용어로 문의 끝점은 문 바로 다음에 오는 위치입니다.In intuitive terms, the end point of a statement is the location that immediately follows the statement. 복합 문 (포함 문이 포함 된 문)에 대 한 실행 규칙은 컨트롤이 포함 된 문의 끝점에 도달할 때 수행 되는 동작을 지정 합니다.The execution rules for composite statements (statements that contain embedded statements) specify the action that is taken when control reaches the end point of an embedded statement. 예를 들어 제어가 블록에서 문의 끝점에 도달 하면 컨트롤은 블록의 다음 문으로 전송 됩니다.For example, when control reaches the end point of a statement in a block, control is transferred to the next statement in the block.

문을 실행 하 여 도달할 수 있는 경우 문에 도달할수 있는 것으로 간주 됩니다.If a statement can possibly be reached by execution, the statement is said to be reachable. 반대로 문이 실행 될 가능성이 없는 경우 문에는 접근할수 없습니다.Conversely, if there is no possibility that a statement will be executed, the statement is said to be unreachable.

예제에서In the example

void F() {
    Console.WriteLine("reachable");
    goto Label;
    Console.WriteLine("unreachable");
    Label:
    Console.WriteLine("reachable");
}

문이 실행 될 가능성이 Console.WriteLine 없으므로 두 번째 호출에 연결할 수 없습니다.the second invocation of Console.WriteLine is unreachable because there is no possibility that the statement will be executed.

컴파일러가 문에 연결할 수 없다고 결정 하면 경고가 보고 됩니다.A warning is reported if the compiler determines that a statement is unreachable. 문에 연결할 수 없는 경우에는 특히 오류가 발생 하지 않습니다.It is specifically not an error for a statement to be unreachable.

특정 문이나 끝점에 연결할 수 있는지 여부를 확인 하기 위해 컴파일러는 각 문에 대해 정의 된 연결 가능성 규칙에 따라 흐름 분석을 수행 합니다.To determine whether a particular statement or end point is reachable, the compiler performs flow analysis according to the reachability rules defined for each statement. 흐름 분석에서는 문의 동작을 제어 하는 상수 식 (상수 식)의 값을 고려 하지만 비상수 식의 가능한 값은 고려 하지 않습니다.The flow analysis takes into account the values of constant expressions (Constant expressions) that control the behavior of statements, but the possible values of non-constant expressions are not considered. 즉, 제어 흐름 분석을 위해 지정 된 형식의 비상수 식에는 해당 형식의 가능한 값이 있는 것으로 간주 됩니다.In other words, for purposes of control flow analysis, a non-constant expression of a given type is considered to have any possible value of that type.

예제에서In the example

void F() {
    const int i = 1;
    if (i == 2) Console.WriteLine("unreachable");
}

if 문의 부울 식은 == 연산자의 두 피연산자가 상수 이므로 상수 식입니다.the boolean expression of the if statement is a constant expression because both operands of the == operator are constants. 상수 식은 컴파일 타임에 계산 되 고 값 false Console.WriteLine 을 생성 하므로 호출을 연결할 수 없는 것으로 간주 됩니다.As the constant expression is evaluated at compile-time, producing the value false, the Console.WriteLine invocation is considered unreachable. 그러나가 지역 i 변수가 되도록 변경 된 경우However, if i is changed to be a local variable

void F() {
    int i = 1;
    if (i == 2) Console.WriteLine("reachable");
}

실제로는 실행 되지 않지만 실제로는 호출을연결할수있는것으로간주됩니다.Console.WriteLinethe Console.WriteLine invocation is considered reachable, even though, in reality, it will never be executed.

함수 멤버의 블록 은 항상 접근할 수 있는 것으로 간주 됩니다.The block of a function member is always considered reachable. 블록에서 각 문의 상관 관계 규칙을 차례로 평가 하 여 지정 된 문의 연결 가능성을 확인할 수 있습니다.By successively evaluating the reachability rules of each statement in a block, the reachability of any given statement can be determined.

예제에서In the example

void F(int x) {
    Console.WriteLine("start");
    if (x < 0) Console.WriteLine("negative");
}

두 번째 Console.WriteLine 의 연결 가능성은 다음과 같이 결정 됩니다.the reachability of the second Console.WriteLine is determined as follows:

  • 메서드의F 블록 Console.WriteLine 에 연결할 수 있으므로 첫 번째 식 문에 접근할 수 있습니다.The first Console.WriteLine expression statement is reachable because the block of the F method is reachable.
  • 첫 번째 Console.WriteLine 식 문의 끝점에 연결할 수 있으므로 해당 문에 연결할 수 있습니다.The end point of the first Console.WriteLine expression statement is reachable because that statement is reachable.
  • 첫 번째Console.WriteLine 식 문의 끝점에 연결할 수 있으므로 문에접근할수있습니다.ifThe if statement is reachable because the end point of the first Console.WriteLine expression statement is reachable.
  • 문의 부울 Console.WriteLinefalse에 상수 값이 없기 때문에 두 번째 식 문에 접근할 수 있습니다. ifThe second Console.WriteLine expression statement is reachable because the boolean expression of the if statement does not have the constant value false.

문의 끝점에 연결할 수 있는 두 가지 경우는 두 가지입니다.There are two situations in which it is a compile-time error for the end point of a statement to be reachable:

  • switch 문이 스위치 섹션을 다음 switch 섹션으로 "이동" 하는 것을 허용 하지 않기 때문에 연결할 수 있는 switch 섹션의 문 목록 끝점에 대 한 컴파일 타임 오류가 발생 합니다.Because the switch statement does not permit a switch section to "fall through" to the next switch section, it is a compile-time error for the end point of the statement list of a switch section to be reachable. 이 오류가 발생 하는 경우 일반적으로 break 문이 없음을 나타냅니다.If this error occurs, it is typically an indication that a break statement is missing.
  • 연결할 수 있는 값을 계산 하는 함수 멤버 블록의 끝점에 대 한 컴파일 타임 오류입니다.It is a compile-time error for the end point of the block of a function member that computes a value to be reachable. 이 오류가 발생 하는 경우 일반적으로 return 문이 없음을 나타냅니다.If this error occurs, it typically is an indication that a return statement is missing.

블록Blocks

블록은 단일 문이 허용되는 컨텍스트에서 여러 문을 쓸 수 있도록 허용합니다.A block permits multiple statements to be written in contexts where a single statement is allowed.

block
    : '{' statement_list? '}'
    ;

블록 은 중괄호로 묶인 선택적인 statement_list (문 목록)로 구성 됩니다.A block consists of an optional statement_list (Statement lists), enclosed in braces. 문 목록을 생략 하면 블록이 비어 있는 것으로 간주 됩니다.If the statement list is omitted, the block is said to be empty.

블록에는 선언 문 (선언문)이 포함 될 수 있습니다.A block may contain declaration statements (Declaration statements). 블록에 선언 된 지역 변수 또는 상수 범위는 블록입니다.The scope of a local variable or constant declared in a block is the block.

블록은 다음과 같이 실행 됩니다.A block is executed as follows:

  • 블록이 비어 있으면 제어는 블록의 끝점으로 전송 됩니다.If the block is empty, control is transferred to the end point of the block.
  • 블록이 비어 있지 않으면 제어가 문 목록으로 전송 됩니다.If the block is not empty, control is transferred to the statement list. 제어가 문 목록의 끝점에 도달 하는 경우 컨트롤은 블록의 끝점으로 전송 됩니다.When and if control reaches the end point of the statement list, control is transferred to the end point of the block.

블록 자체에 도달할 수 있는 경우 블록의 문 목록에 접근할 수 있습니다.The statement list of a block is reachable if the block itself is reachable.

블록이 비어 있거나 문 목록의 끝점에 연결할 수 있으면 블록의 끝점에 도달할 수 있습니다.The end point of a block is reachable if the block is empty or if the end point of the statement list is reachable.

하나yield 이상의 문 (yield 문)을 포함 하는 블록 을 반복기 블록 이라고 합니다.A block that contains one or more yield statements (The yield statement) is called an iterator block. 반복기 블록은 함수 멤버를반복기 (반복기)로 구현 하는 데 사용 됩니다.Iterator blocks are used to implement function members as iterators (Iterators). 반복기 블록에는 다음과 같은 몇 가지 추가 제한 사항이 적용 됩니다.Some additional restrictions apply to iterator blocks:

  • return 문이 반복기 블록에 표시 되는 컴파일 시간 오류입니다 yield return (문은 허용 됨).It is a compile-time error for a return statement to appear in an iterator block (but yield return statements are permitted).
  • 반복기 블록이 안전 하지 않은 컨텍스트 (안전 하지않은 컨텍스트)를 포함 하는 경우 컴파일 시간 오류가 발생 합니다.It is a compile-time error for an iterator block to contain an unsafe context (Unsafe contexts). 반복기 블록은 선언이 안전 하지 않은 컨텍스트에서 중첩 된 경우에도 항상 안전 컨텍스트를 정의 합니다.An iterator block always defines a safe context, even when its declaration is nested in an unsafe context.

문 목록Statement lists

문 목록은 차례로 작성 된 하나 이상의 문으로 구성 됩니다.A statement list consists of one or more statements written in sequence. 문 목록은 블록s (블록) 및 switch_blocks (switch 문)에서 발생 합니다.Statement lists occur in blocks (Blocks) and in switch_blocks (The switch statement).

statement_list
    : statement+
    ;

문 목록은 첫 번째 문으로 제어를 전송 하 여 실행 됩니다.A statement list is executed by transferring control to the first statement. 제어가 문의 끝점에 도달 하면 다음 문으로 제어가 전달 됩니다.When and if control reaches the end point of a statement, control is transferred to the next statement. 제어가 마지막 문의 끝점에 도달 하는 경우 컨트롤은 문 목록의 끝점으로 전송 됩니다.When and if control reaches the end point of the last statement, control is transferred to the end point of the statement list.

다음 중 하나 이상이 true 인 경우 문 목록의 문에 접근할 수 있습니다.A statement in a statement list is reachable if at least one of the following is true:

  • 문은 첫 번째 문이 고 문 목록 자체에 연결할 수 있습니다.The statement is the first statement and the statement list itself is reachable.
  • 이전 문의 끝점에 연결할 수 있습니다.The end point of the preceding statement is reachable.
  • 문은 레이블이 지정 된 문이 고, 레이블은 연결 가능한 goto 문에 의해 참조 됩니다.The statement is a labeled statement and the label is referenced by a reachable goto statement.

목록에서 마지막 문의 끝점에 연결할 수 있는 경우 문 목록의 끝점에 연결할 수 있습니다.The end point of a statement list is reachable if the end point of the last statement in the list is reachable.

빈 문The empty statement

Empty_statement 은 아무 작업도 수행 하지 않습니다.An empty_statement does nothing.

empty_statement
    : ';'
    ;

문이 필요한 컨텍스트에서 수행할 작업이 없는 경우 빈 문이 사용 됩니다.An empty statement is used when there are no operations to perform in a context where a statement is required.

빈 문을 실행 하면 단순히 문의 끝점으로 제어를 전달 합니다.Execution of an empty statement simply transfers control to the end point of the statement. 따라서 빈 문에 연결할 수 있으면 빈 문의 끝점에 연결할 수 있습니다.Thus, the end point of an empty statement is reachable if the empty statement is reachable.

Null 본문을 포함 하는 while 문을 작성 하는 경우 빈 문을 사용할 수 있습니다.An empty statement can be used when writing a while statement with a null body:

bool ProcessMessage() {...}

void ProcessMessages() {
    while (ProcessMessage())
        ;
}

또한 빈 문을 사용 하 여 블록의 닫는 "}" 바로 앞에 있는 레이블을 선언할 수 있습니다.Also, an empty statement can be used to declare a label just before the closing "}" of a block:

void F() {
    ...
    if (done) goto exit;
    ...
    exit: ;
}

레이블 문Labeled statements

Labeled_statement 는 문에 레이블이 접두사로 붙는 것을 허용 합니다.A labeled_statement permits a statement to be prefixed by a label. 레이블 문은 블록에서 허용 되지만 포함 문으로 허용 되지 않습니다.Labeled statements are permitted in blocks, but are not permitted as embedded statements.

labeled_statement
    : identifier ':' statement
    ;

레이블이 지정 된 문은 식별자로 지정 된 이름을 사용 하 여 레이블을 선언 합니다.A labeled statement declares a label with the name given by the identifier. 레이블 범위는 중첩 된 블록을 포함 하 여 레이블이 선언 되는 전체 블록입니다.The scope of a label is the whole block in which the label is declared, including any nested blocks. 동일한 이름을 가진 두 개의 레이블에 겹치는 범위가 있는 경우 컴파일 시간 오류가 발생 합니다.It is a compile-time error for two labels with the same name to have overlapping scopes.

레이블은 레이블 범위 내에서 문 goto (goto 문)에서 참조할 수 있습니다.A label can be referenced from goto statements (The goto statement) within the scope of the label. 즉, 문은 블록 내에서 제어를 전달할 수 있지만 블록으로는 이동할 수 없습니다. gotoThis means that goto statements can transfer control within blocks and out of blocks, but never into blocks.

레이블은 고유한 선언 공간을 가지 며 다른 식별자를 방해 하지 않습니다.Labels have their own declaration space and do not interfere with other identifiers. 예제The example

int F(int x) {
    if (x >= 0) goto x;
    x = -x;
    x: return x;
}

는 유효 하며 이름을 x 매개 변수와 레이블 모두로 사용 합니다.is valid and uses the name x as both a parameter and a label.

레이블이 지정 된 문의 실행은 레이블 다음에 오는 문의 실행과 정확히 일치 합니다.Execution of a labeled statement corresponds exactly to execution of the statement following the label.

정상적인 제어 흐름에서 제공 되는 연결 가능성 외에도, 연결 가능한 goto 문에서 레이블을 참조 하는 경우 레이블이 지정 된 문에 연결할 수 있습니다.In addition to the reachability provided by normal flow of control, a labeled statement is reachable if the label is referenced by a reachable goto statement. 발생할 try try finally 문이 블록 을포함finally 하는 내에 있고 레이블이 지정 된 문이 외부에 있고 블록의 끝점에 연결할 수 없는 경우 레이블이 지정 된 문은에서 goto 도달할 수 없습니다. 해당 goto(Exception: If a goto statement is inside a try that includes a finally block, and the labeled statement is outside the try, and the end point of the finally block is unreachable, then the labeled statement is not reachable from that goto statement.)

선언문Declaration statements

Declaration_statement 는 지역 변수 또는 상수를 선언 합니다.A declaration_statement declares a local variable or constant. 선언 문은 블록에서 허용 되지만 포함 문으로 허용 되지 않습니다.Declaration statements are permitted in blocks, but are not permitted as embedded statements.

declaration_statement
    : local_variable_declaration ';'
    | local_constant_declaration ';'
    ;

지역 변수 선언Local variable declarations

Local_variable_declaration 는 하나 이상의 지역 변수를 선언 합니다.A local_variable_declaration declares one or more local variables.

local_variable_declaration
    : local_variable_type local_variable_declarators
    ;

local_variable_type
    : type
    | 'var'
    ;

local_variable_declarators
    : local_variable_declarator
    | local_variable_declarators ',' local_variable_declarator
    ;

local_variable_declarator
    : identifier
    | identifier '=' local_variable_initializer
    ;

local_variable_initializer
    : expression
    | array_initializer
    | local_variable_initializer_unsafe
    ;

Local_variable_declarationlocal_variable_type 는 선언에 의해 도입 된 변수 형식을 직접 지정 하거나 식별자 var를 나타냅니다 .이는 이니셜라이저를 기반으로 형식을 유추 해야 한다는 것입니다.The local_variable_type of a local_variable_declaration either directly specifies the type of the variables introduced by the declaration, or indicates with the identifier var that the type should be inferred based on an initializer. 형식은 각각 새 변수를 소개 하는 local_variable_declarators의 목록 다음에 옵니다.The type is followed by a list of local_variable_declarators, each of which introduces a new variable. Local_variable_declarator 은 변수의 이름을 입력 하는 식별자 로 구성 되며, 선택적으로 "=" 토큰 및 변수의 초기 값을 제공 하는 local_variable_initializer 로 구성 됩니다.A local_variable_declarator consists of an identifier that names the variable, optionally followed by an "=" token and a local_variable_initializer that gives the initial value of the variable.

지역 변수 선언의 컨텍스트에서 식별자 var은 상황별 키워드 (키워드)로 작동 합니다. Local_variable_typevar로 지정 되 고 var 이라는 형식이 범위 내에 없는 경우 선언은 암시적으로 형식화 된 지역 변수 선언이며, 해당 형식은 관련 이니셜라이저 식의 형식에서 유추 됩니다.In the context of a local variable declaration, the identifier var acts as a contextual keyword (Keywords).When the local_variable_type is specified as var and no type named var is in scope, the declaration is an implicitly typed local variable declaration, whose type is inferred from the type of the associated initializer expression. 암시적으로 형식화 된 지역 변수 선언에는 다음과 같은 제한 사항이 적용 됩니다.Implicitly typed local variable declarations are subject to the following restrictions:

  • Local_variable_declaration 는 여러 local_variable_declarators를 포함할 수 없습니다.The local_variable_declaration cannot include multiple local_variable_declarators.
  • Local_variable_declarator 에는 local_variable_initializer가 포함 되어야 합니다.The local_variable_declarator must include a local_variable_initializer.
  • Local_variable_initializer이어야 합니다.The local_variable_initializer must be an expression.
  • 이니셜라이저 에는 컴파일 시간 형식이 있어야 합니다.The initializer expression must have a compile-time type.
  • 이니셜라이저 식은 선언 된 변수 자체를 참조할 수 없습니다.The initializer expression cannot refer to the declared variable itself

다음은 잘못 된 암시적 형식의 지역 변수 선언에 대 한 예입니다.The following are examples of incorrect implicitly typed local variable declarations:

var x;               // Error, no initializer to infer type from
var y = {1, 2, 3};   // Error, array initializer not permitted
var z = null;        // Error, null does not have a type
var u = x => x + 1;  // Error, anonymous functions do not have a type
var v = v++;         // Error, initializer cannot refer to variable itself

지역 변수의 값은 simple_name (단순 이름)를 사용 하 여 식에서 가져오며 지역 변수의 값은 할당 (대입 연산자)을 사용 하 여 수정 됩니다.The value of a local variable is obtained in an expression using a simple_name (Simple names), and the value of a local variable is modified using an assignment (Assignment operators). 지역 변수는 해당 값을 가져온 각 위치에서 명확 하 게 할당 되어야 합니다 (한정 된 할당).A local variable must be definitely assigned (Definite assignment) at each location where its value is obtained.

Local_variable_declaration 에 선언 된 지역 변수의 범위는 선언이 발생 하는 블록입니다.The scope of a local variable declared in a local_variable_declaration is the block in which the declaration occurs. 지역 변수의 local_variable_declarator 앞에 오는 텍스트 위치에서 지역 변수를 참조 하면 오류가 발생 합니다.It is an error to refer to a local variable in a textual position that precedes the local_variable_declarator of the local variable. 지역 변수의 범위 내에서 같은 이름으로 다른 지역 변수 또는 상수를 선언 하는 것은 컴파일 시간 오류입니다.Within the scope of a local variable, it is a compile-time error to declare another local variable or constant with the same name.

여러 변수를 선언 하는 지역 변수 선언은 동일한 형식의 단일 변수를 여러 개 선언 하는 것과 같습니다.A local variable declaration that declares multiple variables is equivalent to multiple declarations of single variables with the same type. 또한 지역 변수 선언의 변수 이니셜라이저는 선언 바로 뒤에 삽입 되는 대입문과 정확히 일치 합니다.Furthermore, a variable initializer in a local variable declaration corresponds exactly to an assignment statement that is inserted immediately after the declaration.

예제The example

void F() {
    int x = 1, y, z = x * 2;
}

정확히 일치corresponds exactly to

void F() {
    int x; x = 1;
    int y;
    int z; z = x * 2;
}

암시적으로 형식화 된 지역 변수 선언에서 선언 되는 지역 변수의 형식은 변수를 초기화 하는 데 사용 되는 식의 형식과 동일 하 게 간주 됩니다.In an implicitly typed local variable declaration, the type of the local variable being declared is taken to be the same as the type of the expression used to initialize the variable. 예를 들어 다음과 같은 가치를 제공해야 합니다.For example:

var i = 5;
var s = "Hello";
var d = 1.0;
var numbers = new int[] {1, 2, 3};
var orders = new Dictionary<int,Order>();

위의 암시적으로 형식화 된 지역 변수 선언은 다음과 같이 명시적으로 형식화 된 선언과 정확히 동일 합니다.The implicitly typed local variable declarations above are precisely equivalent to the following explicitly typed declarations:

int i = 5;
string s = "Hello";
double d = 1.0;
int[] numbers = new int[] {1, 2, 3};
Dictionary<int,Order> orders = new Dictionary<int,Order>();

지역 상수 선언Local constant declarations

Local_constant_declaration 는 하나 이상의 지역 상수를 선언 합니다.A local_constant_declaration declares one or more local constants.

local_constant_declaration
    : 'const' type constant_declarators
    ;

constant_declarators
    : constant_declarator (',' constant_declarator)*
    ;

constant_declarator
    : identifier '=' constant_expression
    ;

Local_constant_declaration형식은 선언에 의해 도입 된 상수의 형식을 지정 합니다.The type of a local_constant_declaration specifies the type of the constants introduced by the declaration. 형식은 각각 새 상수를 소개 하는 constant_declarators 목록 뒤에 나옵니다.The type is followed by a list of constant_declarators, each of which introduces a new constant. Constant_declarator 은 상수의 이름을, "=" 토큰, 상수 값을 제공 하는 constant_expression (상수 식)을 차례로 나타내는 식별자 로 구성 됩니다.A constant_declarator consists of an identifier that names the constant, followed by an "=" token, followed by a constant_expression (Constant expressions) that gives the value of the constant.

로컬 상수 선언의 형식과 constant_expression 는 상수 멤버 선언 (상수)과 동일한 규칙을 따라야 합니다.The type and constant_expression of a local constant declaration must follow the same rules as those of a constant member declaration (Constants).

로컬 상수의 값은 simple_name (단순 이름)를 사용 하 여 식에서 가져옵니다.The value of a local constant is obtained in an expression using a simple_name (Simple names).

지역 상수의 범위는 선언이 발생 하는 블록입니다.The scope of a local constant is the block in which the declaration occurs. Constant_declarator앞에 오는 텍스트 위치에서 지역 상수를 참조 하는 것은 오류입니다.It is an error to refer to a local constant in a textual position that precedes its constant_declarator. 지역 상수 범위 내에서 같은 이름으로 다른 지역 변수 또는 상수를 선언 하는 것은 컴파일 시간 오류입니다.Within the scope of a local constant, it is a compile-time error to declare another local variable or constant with the same name.

여러 상수를 선언 하는 로컬 상수 선언은 동일한 형식의 단일 상수에 대 한 여러 선언과 동일 합니다.A local constant declaration that declares multiple constants is equivalent to multiple declarations of single constants with the same type.

식 문Expression statements

Expression_statement 는 지정 된 식을 계산 합니다.An expression_statement evaluates a given expression. 식으로 계산 된 값 (있는 경우)은 무시 됩니다.The value computed by the expression, if any, is discarded.

expression_statement
    : statement_expression ';'
    ;

statement_expression
    : invocation_expression
    | null_conditional_invocation_expression
    | object_creation_expression
    | assignment
    | post_increment_expression
    | post_decrement_expression
    | pre_increment_expression
    | pre_decrement_expression
    | await_expression
    ;

모든 식이 문으로 허용 되는 것은 아닙니다.Not all expressions are permitted as statements. 특히 값을 계산 하는 x + yx == 1 등의 식은 문으로 허용 되지 않습니다.In particular, expressions such as x + y and x == 1 that merely compute a value (which will be discarded), are not permitted as statements.

Expression_statement 를 실행 하면 포함 된 식이 계산 된 후 컨트롤을 expression_statement의 끝점으로 전달 합니다.Execution of an expression_statement evaluates the contained expression and then transfers control to the end point of the expression_statement. Expression_statement 에 연결할 수 있으면 expression_statement 의 끝점에 연결할 수 있습니다.The end point of an expression_statement is reachable if that expression_statement is reachable.

선택 문Selection statements

선택 문은 일부 식의 값에 따라 실행할 수 있는 여러 문 중 하나를 선택 합니다.Selection statements select one of a number of possible statements for execution based on the value of some expression.

selection_statement
    : if_statement
    | switch_statement
    ;

If 문The if statement

if 문은 부울 식의 값에 따라 실행할 문을 선택 합니다.The if statement selects a statement for execution based on the value of a boolean expression.

if_statement
    : 'if' '(' boolean_expression ')' embedded_statement
    | 'if' '(' boolean_expression ')' embedded_statement 'else' embedded_statement
    ;

파트는 구문에서 허용 하는 어휘 적 if 으로 가장 가까운 앞에 연결 됩니다. elseAn else part is associated with the lexically nearest preceding if that is allowed by the syntax. 따라서 폼의 if 문은Thus, an if statement of the form

if (x) if (y) F(); else G();

위의 식은 아래의 식과 동일합니다.is equivalent to

if (x) {
    if (y) {
        F();
    }
    else {
        G();
    }
}

if 문은 다음과 같이 실행 됩니다.An if statement is executed as follows:

  • Boolean_expression (부울 식)이 계산 됩니다.The boolean_expression (Boolean expressions) is evaluated.
  • 부울 식이 생성 true하는 경우 제어는 첫 번째 포함 된 문으로 전달 됩니다.If the boolean expression yields true, control is transferred to the first embedded statement. 컨트롤이 해당 문의 끝점에 도달 하는 경우 제어가 if 문의 끝점으로 전송 됩니다.When and if control reaches the end point of that statement, control is transferred to the end point of the if statement.
  • 부울 식이 생성 false 하 고 else 파트가 있으면 두 번째 포함 된 문으로 제어가 전송 됩니다.If the boolean expression yields false and if an else part is present, control is transferred to the second embedded statement. 컨트롤이 해당 문의 끝점에 도달 하는 경우 제어가 if 문의 끝점으로 전송 됩니다.When and if control reaches the end point of that statement, control is transferred to the end point of the if statement.
  • 부울 식이 생성 false 하 고 else 파트가 없으면 제어가 if 문의 끝점으로 전송 됩니다.If the boolean expression yields false and if an else part is not present, control is transferred to the end point of the if statement.

문에 연결할 수 있고 부울 식 if 에 상수 값 false이 없는 if 경우 문의 첫 번째 포함 문에 연결할 수 있습니다.The first embedded statement of an if statement is reachable if the if statement is reachable and the boolean expression does not have the constant value false.

문의 연결 가능 하 고 부울 if 식에 상수 값 true이 없는 if 경우 문의 두 번째 포함 문 (있는 경우)에 연결할 수 있습니다.The second embedded statement of an if statement, if present, is reachable if the if statement is reachable and the boolean expression does not have the constant value true.

if 문의 끝점에는 포함 된 문 중 하나 이상의 끝점에 연결할 수 있는 경우 연결할 수 있습니다.The end point of an if statement is reachable if the end point of at least one of its embedded statements is reachable. 또한 if 문에 연결할 수 있고 부울 식에 if 상수 값 trueelse 없는 경우에는 파트가 없는 문의 끝점에 연결할 수 있습니다.In addition, the end point of an if statement with no else part is reachable if the if statement is reachable and the boolean expression does not have the constant value true.

Switch 문The switch statement

Switch 문은 스위치 식의 값에 해당 하는 연결 된 스위치 레이블이 있는 문 목록 실행을 위해 선택 합니다.The switch statement selects for execution a statement list having an associated switch label that corresponds to the value of the switch expression.

switch_statement
    : 'switch' '(' expression ')' switch_block
    ;

switch_block
    : '{' switch_section* '}'
    ;

switch_section
    : switch_label+ statement_list
    ;

switch_label
    : 'case' constant_expression ':'
    | 'default' ':'
    ;

Switch_statement 는 키워드 switch로 구성 되 고 그 뒤에 괄호로 묶은 식 (switch 식 이라고 함)이 오고 그 뒤에 switch_block가 나옵니다.A switch_statement consists of the keyword switch, followed by a parenthesized expression (called the switch expression), followed by a switch_block. Switch_block 는 0 개 이상의 switch_sections로 구성 되며 중괄호로 묶여 있습니다.The switch_block consists of zero or more switch_sections, enclosed in braces. switch_section 는 하나 이상의 switch_labels와 statement_list (문 목록)로 구성 됩니다.Each switch_section consists of one or more switch_labels followed by a statement_list (Statement lists).

switch 문의 관리 형식은 switch 식에 의해 설정 됩니다.The governing type of a switch statement is established by the switch expression.

  • 스위치 식의 형식이 sbyte, byte, short, ushort, int, uint, long, ulong, bool, char, 0 또는 enum_type이거나 이러한 형식 중 하나에 해당 하는 nullable 형식이 면입니다. 이는 2 문의 관리 유형입니다.If the type of the switch expression is sbyte, byte, short, ushort, int, uint, long, ulong, bool, char, string, or an enum_type, or if it is the nullable type corresponding to one of these types, then that is the governing type of the switch statement.
  • 그렇지 않으면 정확히 하나의 사용자 정의 암시적 변환 (사용자 정의 변환)이 스위치 식의 형식에서 sbyte, byte, short, ushort 등의 가능한 관리 형식 중 하나로 존재 해야 합니다. int ,,uint,,,,, 또는 해당 형식 중 하나에 해당 하는 nullable 형식입니다. long ulong char stringOtherwise, exactly one user-defined implicit conversion (User-defined conversions) must exist from the type of the switch expression to one of the following possible governing types: sbyte, byte, short, ushort, int, uint, long, ulong, char, string, or, a nullable type corresponding to one of those types.
  • 그렇지 않고 이러한 암시적 변환이 없거나 이러한 암시적 변환이 둘 이상 있는 경우 컴파일 시간 오류가 발생 합니다.Otherwise, if no such implicit conversion exists, or if more than one such implicit conversion exists, a compile-time error occurs.

case 레이블의 상수 식은 switch 문의 관리 형식에 대해 암시적으로 변환할 수 있는 값 (암시적 변환)을 나타내야 합니다.The constant expression of each case label must denote a value that is implicitly convertible (Implicit conversions) to the governing type of the switch statement. case 같은switch 문에서 둘 이상의 레이블이 동일한 상수 값을 지정 하는 경우 컴파일 시간 오류가 발생 합니다.A compile-time error occurs if two or more case labels in the same switch statement specify the same constant value.

Switch 문에는 하나의 default 레이블만 있을 수 있습니다.There can be at most one default label in a switch statement.

switch 문은 다음과 같이 실행 됩니다.A switch statement is executed as follows:

  • Switch 식이 계산 되어 관리 형식으로 변환 됩니다.The switch expression is evaluated and converted to the governing type.
  • 동일한 case case 문의 레이블에 지정 된 상수 중 하나가 switch 식의 값과 같으면 컨트롤이 일치 하는 레이블 다음에 오는 문 목록으로 전송 됩니다. switchIf one of the constants specified in a case label in the same switch statement is equal to the value of the switch expression, control is transferred to the statement list following the matched case label.
  • 동일한 case default default 문의 레이블에 지정 된 상수 중 switch 식의 값과 같지 않은 경우에는 레이블이 있는 경우 컨트롤이 다음의 문 목록으로 전송 됩니다. switch 레이블.If none of the constants specified in case labels in the same switch statement is equal to the value of the switch expression, and if a default label is present, control is transferred to the statement list following the default label.
  • 동일한 case default switch 문의 레이블에 지정 된 상수 중 switch 식의 값과 같지 않은 경우 및 레이블이 없는 경우 제어가 문의 끝점으로 전송 됩니다. switchIf none of the constants specified in case labels in the same switch statement is equal to the value of the switch expression, and if no default label is present, control is transferred to the end point of the switch statement.

Switch 섹션의 문 목록 끝 지점에 연결할 수 있는 경우 컴파일 시간 오류가 발생 합니다.If the end point of the statement list of a switch section is reachable, a compile-time error occurs. 이를 "없음" 규칙 이라고 합니다.This is known as the "no fall through" rule. 예제The example

switch (i) {
case 0:
    CaseZero();
    break;
case 1:
    CaseOne();
    break;
default:
    CaseOthers();
    break;
}

는 연결 가능한 끝점이 있는 switch 섹션이 없기 때문에 유효 합니다.is valid because no switch section has a reachable end point. C 및 C++와 달리 switch 섹션의 실행은 다음 switch 섹션으로 "이동" 하 고 예제를 사용할 수 없습니다.Unlike C and C++, execution of a switch section is not permitted to "fall through" to the next switch section, and the example

switch (i) {
case 0:
    CaseZero();
case 1:
    CaseZeroOrOne();
default:
    CaseAny();
}

컴파일 시간 오류가 발생 합니다.results in a compile-time error. 스위치 섹션을 실행 한 후 다른 스위치 섹션을 실행 하면 explicit goto case 또는 goto default 문을 사용 해야 합니다.When execution of a switch section is to be followed by execution of another switch section, an explicit goto case or goto default statement must be used:

switch (i) {
case 0:
    CaseZero();
    goto case 1;
case 1:
    CaseZeroOrOne();
    goto default;
default:
    CaseAny();
    break;
}

Switch_section에는 여러 개의 레이블이 허용 됩니다.Multiple labels are permitted in a switch_section. 예제The example

switch (i) {
case 0:
    CaseZero();
    break;
case 1:
    CaseOne();
    break;
case 2:
default:
    CaseTwo();
    break;
}

가 유효 합니다.is valid. 이 예제에서는 레이블이 case 2:이 고 default:이 같은 switch_section의 일부 이기 때문에 "일치 하지 않음" 규칙을 위반 하지 않습니다.The example does not violate the "no fall through" rule because the labels case 2: and default: are part of the same switch_section.

"참여 안 함" 규칙은 C에서 발생 하는 일반적인 버그 클래스와 C++ 문이 실수로 생략 break 된 경우를 방지 합니다.The "no fall through" rule prevents a common class of bugs that occur in C and C++ when break statements are accidentally omitted. 또한이 규칙으로 인해 문의 동작에 영향을 주지 않고 switch 문의 스위치 섹션을 임의로 다시 정렬할 수 있습니다.In addition, because of this rule, the switch sections of a switch statement can be arbitrarily rearranged without affecting the behavior of the statement. 예를 들어 위의 switch 문 섹션은 문의 동작에 영향을 주지 않고 되돌릴 수 있습니다.For example, the sections of the switch statement above can be reversed without affecting the behavior of the statement:

switch (i) {
default:
    CaseAny();
    break;
case 1:
    CaseZeroOrOne();
    goto default;
case 0:
    CaseZero();
    goto case 1;
}

Switch 섹션의 문 목록은 일반적으로 break, goto case또는 goto default 문에서 끝나지만 문 목록의 끝점을 렌더링 하는 모든 생성자는 허용 되지 않습니다.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. 예를 들어, while 부울 식 true 에 의해 제어 되는 문은 해당 끝점에 도달 하지 않는 것으로 알려져 있습니다.For example, a while statement controlled by the boolean expression true is known to never reach its end point. 마찬가지로, throw 또는 return 문은 항상 다른 곳에서 컨트롤을 전송 하 고 끝점에 도달 하지 않습니다.Likewise, a throw or return statement always transfers control elsewhere and never reaches its end point. 따라서 다음 예제를 사용할 수 있습니다.Thus, the following example is valid:

switch (i) {
case 0:
    while (true) F();
case 1:
    throw new ArgumentException();
case 2:
    return;
}

switch 문의 관리 형식은 형식일 string수 있습니다.The governing type of a switch statement may be the type string. 예를 들어 다음과 같은 가치를 제공해야 합니다.For example:

void DoCommand(string command) {
    switch (command.ToLower()) {
    case "run":
        DoRun();
        break;
    case "save":
        DoSave();
        break;
    case "quit":
        DoQuit();
        break;
    default:
        InvalidCommand(command);
        break;
    }
}

문자열 같음 연산자 (문자열 같음 연산자) switch 와 같이 문은 대/소문자를 구분 하며 switch 식 case 문자열이 레이블 상수와 정확히 일치 하는 경우에만 지정 된 switch 섹션을 실행 합니다.Like the string equality operators (String equality operators), the switch statement is case sensitive and will execute a given switch section only if the switch expression string exactly matches a case label constant.

switch 문의 관리 형식이 인 string경우 해당 값 null 은 case 레이블 상수로 허용 됩니다.When the governing type of a switch statement is string, the value null is permitted as a case label constant.

Switch_blockstatement_lists에는 선언 문 (선언문)이 포함 될 수 있습니다.The statement_lists of a switch_block may contain declaration statements (Declaration statements). 스위치 블록에 선언 된 지역 변수 또는 상수 범위는 스위치 블록입니다.The scope of a local variable or constant declared in a switch block is the switch block.

switch 문에 연결할 수 있고 다음 중 하나 이상이 true 인 경우 지정 된 switch 섹션의 문 목록에 접근할 수 있습니다.The statement list of a given switch section is reachable if the switch statement is reachable and at least one of the following is true:

  • Switch 식이 비상수 값입니다.The switch expression is a non-constant value.
  • Switch 식은 switch 섹션의 case 레이블과 일치 하는 상수 값입니다.The switch expression is a constant value that matches a case label in the switch section.
  • Switch 식은 case 레이블과 일치 하지 않는 상수 값 이며 switch 섹션에는 default 레이블이 포함 되어 있습니다.The switch expression is a constant value that doesn't match any case label, and the switch section contains the default label.
  • 스위치 섹션의 스위치 레이블은 연결 가능 goto case 또는 goto default 문에 의해 참조 됩니다.A switch label of the switch section is referenced by a reachable goto case or goto default statement.

다음 중 하나 이상이 true switch 인 경우 문의 끝점에 연결할 수 있습니다.The end point of a switch statement is reachable if at least one of the following is true:

  • 문에는 문을 종료 하는 연결 가능한 break 문이 포함 되어 있습니다. switch switchThe switch statement contains a reachable break statement that exits the switch statement.
  • 문에 연결할 수 있으며, switch 식이 비상수 값 이며, 레이블이 없는 default경우 switchThe switch statement is reachable, the switch expression is a non-constant value, and no default label is present.
  • 문에 연결할 수 있습니다. switch 식은 case 레이블과 일치 하지 않는 상수 값 이며 레이블이 없습니다 default. switchThe switch statement is reachable, the switch expression is a constant value that doesn't match any case label, and no default label is present.

반복 문Iteration statements

반복 문은 포함 된 문을 반복 해 서 실행 합니다.Iteration statements repeatedly execute an embedded statement.

iteration_statement
    : while_statement
    | do_statement
    | for_statement
    | foreach_statement
    ;

While 문The while statement

문은 while 조건에 따라 포함 된 문을 0 번 이상 실행 합니다.The while statement conditionally executes an embedded statement zero or more times.

while_statement
    : 'while' '(' boolean_expression ')' embedded_statement
    ;

while 문은 다음과 같이 실행 됩니다.A while statement is executed as follows:

  • Boolean_expression (부울 식)이 계산 됩니다.The boolean_expression (Boolean expressions) is evaluated.
  • 부울 식이 생성 true하는 경우 제어는 포함 된 문으로 전달 됩니다.If the boolean expression yields true, control is transferred to the embedded statement. 제어가 문 실행 continue 의 경우 포함 된 문의 끝점에 도달 하면 while 문의 시작 부분으로 제어가 전달 됩니다.When and if control reaches the end point of the embedded statement (possibly from execution of a continue statement), control is transferred to the beginning of the while statement.
  • 부울 식이 생성 false하는 경우 제어가 while 문의 끝점으로 전송 됩니다.If the boolean expression yields false, control is transferred to the end point of the while statement.

문의 while 포함 문 break 내에서 문 (break 문)을 사용 하 여 while 문의 끝점으로 제어를 전달 (따라서 포함 된 문의 반복 종료) 할수있습니다.continue statement (continue 문)를 사용 하 여 제어를 포함 된 문의 끝점으로 전송 하 여 while 문의 다른 반복을 수행할 수 있습니다.Within the embedded statement of a while statement, a break statement (The break statement) may be used to transfer control to the end point of the while statement (thus ending iteration of the embedded statement), and a continue statement (The continue statement) may be used to transfer control to the end point of the embedded statement (thus performing another iteration of the while statement).

문에 연결할 수 있고 부울 while 식에 상수 값 falsewhile 없는 경우 문의 포함 문에 접근할 수 있습니다.The embedded statement of a while statement is reachable if the while statement is reachable and the boolean expression does not have the constant value false.

다음 중 하나 이상이 true while 인 경우 문의 끝점에 연결할 수 있습니다.The end point of a while statement is reachable if at least one of the following is true:

  • 문에는 문을 종료 하는 연결 가능한 break 문이 포함 되어 있습니다. while whileThe while statement contains a reachable break statement that exits the while statement.
  • 문에 연결할 수 있으며 부울 식에 상수 값 true이 없습니다. whileThe while statement is reachable and the boolean expression does not have the constant value true.

Do 문The do statement

문은 do 조건에 따라 포함 문을 한 번 이상 실행 합니다.The do statement conditionally executes an embedded statement one or more times.

do_statement
    : 'do' embedded_statement 'while' '(' boolean_expression ')' ';'
    ;

do 문은 다음과 같이 실행 됩니다.A do statement is executed as follows:

  • 컨트롤이 포함 된 문으로 전송 됩니다.Control is transferred to the embedded statement.
  • 컨트롤이 포함 된 문의 끝점에 도달 하는 경우 (continue 문 실행) boolean_expression (부울 식)이 계산 됩니다.When and if control reaches the end point of the embedded statement (possibly from execution of a continue statement), the boolean_expression (Boolean expressions) is evaluated. 부울 식이 생성 true하는 경우 제어가 do 문의 시작 부분으로 전송 됩니다.If the boolean expression yields true, control is transferred to the beginning of the do statement. 그렇지 않으면 do 문의 끝점으로 제어가 전달 됩니다.Otherwise, control is transferred to the end point of the do statement.

문의 do 포함 문 break 내에서 문 (break 문)을 사용 하 여 do 문의 끝점으로 제어를 전달 (따라서 포함 된 문의 반복 종료) 할수있습니다.continue statement (continue 문)를 사용 하 여 제어를 포함 된 문의 끝점으로 전달할 수 있습니다.Within the embedded statement of a do statement, a break statement (The break statement) may be used to transfer control to the end point of the do statement (thus ending iteration of the embedded statement), and a continue statement (The continue statement) may be used to transfer control to the end point of the embedded statement.

문에 연결할 수 do do 있으면 문의 포함 문에 접근할 수 있습니다.The embedded statement of a do statement is reachable if the do statement is reachable.

다음 중 하나 이상이 true do 인 경우 문의 끝점에 연결할 수 있습니다.The end point of a do statement is reachable if at least one of the following is true:

  • 문에는 문을 종료 하는 연결 가능한 break 문이 포함 되어 있습니다. do doThe do statement contains a reachable break statement that exits the do statement.
  • 포함 된 문의 끝점에 연결할 수 있으며 부울 식에 상수 값 true이 없습니다.The end point of the embedded statement is reachable and the boolean expression does not have the constant value true.

For 문The for statement

for 문은 초기화 식의 시퀀스를 평가한 다음 조건이 true 이면 포함 된 문을 반복 해 서 실행 하 고 반복 식의 시퀀스를 계산 합니다.The for statement evaluates a sequence of initialization expressions and then, while a condition is true, repeatedly executes an embedded statement and evaluates a sequence of iteration expressions.

for_statement
    : 'for' '(' for_initializer? ';' for_condition? ';' for_iterator? ')' embedded_statement
    ;

for_initializer
    : local_variable_declaration
    | statement_expression_list
    ;

for_condition
    : boolean_expression
    ;

for_iterator
    : statement_expression_list
    ;

statement_expression_list
    : statement_expression (',' statement_expression)*
    ;

For_initializer(있는 경우)는 local_variable_declaration (지역 변수 선언) 또는 쉼표로 구분 된 statement_expressions (식 문)의 목록으로 구성 됩니다.The for_initializer, if present, consists of either a local_variable_declaration (Local variable declarations) or a list of statement_expressions (Expression statements) separated by commas. For_initializer 로 선언 된 지역 변수의 범위는 변수에 대 한 local_variable_declarator 에서 시작 하 여 포함 문의 끝으로 확장 됩니다.The scope of a local variable declared by a for_initializer starts at the local_variable_declarator for the variable and extends to the end of the embedded statement. 범위에는 for_conditionfor_iterator가 포함 됩니다.The scope includes the for_condition and the for_iterator.

For_condition(있는 경우)는 boolean_expression (부울 식) 이어야 합니다.The for_condition, if present, must be a boolean_expression (Boolean expressions).

For_iterator(있는 경우)은 쉼표로 구분 된 Statement_expressions (식 문)의 목록으로 구성 됩니다.The for_iterator, if present, consists of a list of statement_expressions (Expression statements) separated by commas.

For 문은 다음과 같이 실행 됩니다.A for statement is executed as follows:

  • For_initializer 이 있으면 변수 이니셜라이저 또는 문 식이 작성 된 순서 대로 실행 됩니다.If a for_initializer is present, the variable initializers or statement expressions are executed in the order they are written. 이 단계는 한 번만 수행 됩니다.This step is only performed once.
  • For_condition 있는 경우 계산 됩니다.If a for_condition is present, it is evaluated.
  • For_condition 이 없거나 평가가 true을 생성 하는 경우에는 제어가 포함 된 문으로 전달 됩니다.If the for_condition is not present or if the evaluation yields true, control is transferred to the embedded statement. 컨트롤이 포함 된 문의 끝점에 도달 하는 경우 (continue 문의 실행으로 인해) for_iterator의 식 (있는 경우)이 순서 대로 계산 된 후 다른 반복이 수행 됩니다. 위의 단계에서 for_condition 를 평가 합니다.When and if control reaches the end point of the embedded statement (possibly from execution of a continue statement), the expressions of the for_iterator, if any, are evaluated in sequence, and then another iteration is performed, starting with evaluation of the for_condition in the step above.
  • For_condition 가 있고 평가가 false을 생성 하는 경우 컨트롤은 for 문의 끝점으로 전송 됩니다.If the for_condition is present and the evaluation yields false, control is transferred to the end point of the for statement.

@No__t-0 문의 포함 된 문 내에서 break 문 (break 문)을 사용 하 여 @no__t 3 문의 끝점 (즉, 포함 된 문의 반복 종료) 및 continue 문 ( Continue 문은포함 된 문의 끝점으로 제어를 전송 하는 데 사용 될 수 있습니다. 따라서 for_iterator 을 실행 하 고 for_condition로 시작 하는 for 문의 다른 반복을 수행 합니다.Within the embedded statement of a for statement, a break statement (The break statement) may be used to transfer control to the end point of the for statement (thus ending iteration of the embedded statement), and a continue statement (The continue statement) may be used to transfer control to the end point of the embedded statement (thus executing the for_iterator and performing another iteration of the for statement, starting with the for_condition).

다음 조건 중 하나에 for 해당 하는 경우 문의 포함 문에 접근할 수 있습니다.The embedded statement of a for statement is reachable if one of the following is true:

  • @No__t-0 문에 연결할 수 있으며 for_condition 없습니다.The for statement is reachable and no for_condition is present.
  • @No__t-0 문에 연결할 수 있으며 for_condition 이 있고 상수 값 false가 없습니다.The for statement is reachable and a for_condition is present and does not have the constant value false.

다음 중 하나 이상이 true for 인 경우 문의 끝점에 연결할 수 있습니다.The end point of a for statement is reachable if at least one of the following is true:

  • 문에는 문을 종료 하는 연결 가능한 break 문이 포함 되어 있습니다. for forThe for statement contains a reachable break statement that exits the for statement.
  • @No__t-0 문에 연결할 수 있으며 for_condition 이 있고 상수 값 true가 없습니다.The for statement is reachable and a for_condition is present and does not have the constant value true.

Foreach 문The foreach statement

foreach 문은 컬렉션의 각 요소에 대해 포함 문을 실행 하 여 컬렉션의 요소를 열거 합니다.The foreach statement enumerates the elements of a collection, executing an embedded statement for each element of the collection.

foreach_statement
    : 'foreach' '(' local_variable_type identifier 'in' expression ')' embedded_statement
    ;

문의 형식식별자 foreach 는 문의 반복 변수 를 선언 합니다.The type and identifier of a foreach statement declare the iteration variable of the statement. @No__t-0 식별자가 local_variable_type으로 지정 되 고 var 라는 형식이 범위에 없는 경우 반복 변수는 암시적으로 형식화 된 반복 변수라고 하며, 해당 형식은 foreach의 요소 형식으로 사용 됩니다. 문을 지정 합니다.If the var identifier is given as the local_variable_type, and no type named var is in scope, the iteration variable is said to be an implicitly typed iteration variable, and its type is taken to be the element type of the foreach statement, as specified below. 반복 변수는 포함 된 문으로 확장 되는 범위의 읽기 전용 지역 변수에 해당 합니다.The iteration variable corresponds to a read-only local variable with a scope that extends over the embedded statement. foreach 문을 실행 하는 동안 반복 변수는 반복이 현재 수행 중인 컬렉션 요소를 나타냅니다.During execution of a foreach statement, the iteration variable represents the collection element for which an iteration is currently being performed. 포함 된 문이 반복 변수 (대입 ++ 또는 and -- 연산자를 통해)를 수정 하려고 하거나 반복 변수 ref 를 또는 out 매개 변수로 전달 하려고 하면 컴파일 시간 오류가 발생 합니다.A compile-time error occurs if the embedded statement attempts to modify the iteration variable (via assignment or the ++ and -- operators) or pass the iteration variable as a ref or out parameter.

다음 IEnumerable에서, IEnumerable<T>IEnumerator System.Collections System.Collections.Generic를 간단 하 게 하기 위해 및는 네임 스페이스 및의 해당 형식을 참조 합니다. IEnumerator<T>In the following, for brevity, IEnumerable, IEnumerator, IEnumerable<T> and IEnumerator<T> refer to the corresponding types in the namespaces System.Collections and System.Collections.Generic.

Foreach 문의 컴파일 시간 처리에서는 먼저 컬렉션 형식, 열거자 형식 및 식의 요소 형식을 결정 합니다.The compile-time processing of a foreach statement first determines the collection type, enumerator type and element type of the expression. 이러한 결정은 다음과 같이 진행 됩니다.This determination proceeds as follows:

  • 식의 형식이 X 배열 형식인 경우에서 X IEnumerable 인터페이스로의 암시적 참조 변환이 있습니다 (이후 System.Array 이 인터페이스를 구현).If the type X of expression is an array type then there is an implicit reference conversion from X to the IEnumerable interface (since System.Array implements this interface). 컬렉션 형식은 IEnumerable 인터페이스이 고, 열거자 형식은 IEnumerator 인터페이스 이며, 요소 형식은 배열 형식의 X요소 형식입니다.The collection type is the IEnumerable interface, the enumerator type is the IEnumerator interface and the element type is the element type of the array type X.

  • X 의형식이IEnumerable 이면 에서 인터페이스로의 암시적 변환이 수행 됩니다 (암시적 동적 변환). dynamicIf the type X of expression is dynamic then there is an implicit conversion from expression to the IEnumerable interface (Implicit dynamic conversions). 컬렉션 형식은 IEnumerable 인터페이스이 고 열거자 형식은 IEnumerator 인터페이스입니다.The collection type is the IEnumerable interface and the enumerator type is the IEnumerator interface. @No__t-0 식별자가 local_variable_type 으로 지정 된 경우 요소 형식은 -3 @no__t이 고, 그렇지 @no__t 않으면-4입니다.If the var identifier is given as the local_variable_type then the element type is dynamic, otherwise it is object.

  • 그렇지 않으면 형식 X 에 적절 한 GetEnumerator 메서드가 있는지 확인 합니다.Otherwise, determine whether the type X has an appropriate GetEnumerator method:

    • X 식별자GetEnumerator 가 있는 형식에 대해 멤버 조회를 수행 하 고 형식 인수를 사용 하지 않습니다.Perform member lookup on the type X with identifier GetEnumerator and no type arguments. 멤버 조회가 일치 하는 항목을 생성 하지 않거나 모호성을 생성 하거나 메서드 그룹이 아닌 일치 항목을 생성 하는 경우 아래 설명 된 대로 열거 가능 인터페이스를 확인 합니다.If the member lookup does not produce a match, or it produces an ambiguity, or produces a match that is not a method group, check for an enumerable interface as described below. 멤버 조회가 메서드 그룹을 제외한 모든 항목을 생성 하거나 일치 하는 항목을 생성 하지 않는 경우 경고를 생성 하는 것이 좋습니다.It is recommended that a warning be issued if member lookup produces anything except a method group or no match.
    • 결과 메서드 그룹과 빈 인수 목록을 사용 하 여 오버 로드 확인을 수행 합니다.Perform overload resolution using the resulting method group and an empty argument list. 오버 로드 확인이 적용 가능한 메서드를 반환 하지 않거나, 모호성을 발생 시키거나, 단일 최상의 메서드를 생성 하지만,이 메서드는 정적 이거나 public이 아닌 경우 아래 설명 된 대로 열거 가능 인터페이스를 확인 합니다.If overload resolution results in no applicable methods, results in an ambiguity, or results in a single best method but that method is either static or not public, check for an enumerable interface as described below. 오버 로드 확인에서 명확한 public 인스턴스 메서드를 제외한 모든 항목을 생성 하거나 해당 메서드를 생성 하지 않는 경우 경고를 생성 하는 것이 좋습니다.It is recommended that a warning be issued if overload resolution produces anything except an unambiguous public instance method or no applicable methods.
    • GetEnumerator 메서드의 반환 형식이 E 클래스, 구조체 또는 인터페이스 형식이 아닌 경우 오류가 생성 되 고 추가 단계를 수행 하지 않습니다.If the return type E of the GetEnumerator method is not a class, struct or interface type, an error is produced and no further steps are taken.
    • 멤버 조회는 식별자 E Current 와 형식 인수를 사용 하 여에 대해 수행 됩니다.Member lookup is performed on E with the identifier Current and no type arguments. 멤버 조회가 일치 하는 항목을 생성 하지 않으면 오류가 발생 하거나, 읽기를 허용 하는 공용 인스턴스 속성을 제외한 모든 결과가 반환 됩니다. 오류가 생성 되 고 추가 단계가 수행 되지 않습니다.If the member lookup produces no match, the result is an error, or the result is anything except a public instance property that permits reading, an error is produced and no further steps are taken.
    • 멤버 조회는 식별자 E MoveNext 와 형식 인수를 사용 하 여에 대해 수행 됩니다.Member lookup is performed on E with the identifier MoveNext and no type arguments. 멤버 조회에서 일치 하는 항목이 생성 되지 않으면 오류가 발생 하거나 메서드 그룹을 제외한 결과가 발생 하는 경우 오류가 생성 되 고 추가 단계가 수행 되지 않습니다.If the member lookup produces no match, the result is an error, or the result is anything except a method group, an error is produced and no further steps are taken.
    • 오버 로드 확인은 빈 인수 목록을 사용 하 여 메서드 그룹에 대해 수행 됩니다.Overload resolution is performed on the method group with an empty argument list. 오버 로드 확인이 적용 가능한 메서드를 반환 하지 않거나, 모호성을 발생 시키거나, 단일 최상의 메서드를 생성 하는 경우, 해당 메서드가 정적 이거나 public이 아니거나, 반환 형식이가 bool아닌 경우 오류가 생성 되 고 추가 단계가 수행 되지 않습니다.If overload resolution results in no applicable methods, results in an ambiguity, or results in a single best method but that method is either static or not public, or its return type is not bool, an error is produced and no further steps are taken.
    • 컬렉션 형식은X고, 열거자 형식은 이며 E, 요소 형식은 Current 속성의 형식입니다.The collection type is X, the enumerator type is E, and the element type is the type of the Current property.
  • 그렇지 않으면 열거 가능 인터페이스를 확인 합니다.Otherwise, check for an enumerable interface:

    • 에서로의 X 암시적 변환이 Ti 가능한 T dynamic IEnumerable<Ti> Ti 모든 형식중에서로의암시적변환이있는경우에는이아닌고유한형식이있습니다.T IEnumerable<T> 에서로 IEnumerable<T> IEnumerator<T> 의 암시적 변환은 컬렉션 형식이 인터페이스이 고 열거자 형식이 인터페이스이 고 요소 형식이입니다. IEnumerable<Ti> T.If among all the types Ti for which there is an implicit conversion from X to IEnumerable<Ti>, there is a unique type T such that T is not dynamic and for all the other Ti there is an implicit conversion from IEnumerable<T> to IEnumerable<Ti>, then the collection type is the interface IEnumerable<T>, the enumerator type is the interface IEnumerator<T>, and the element type is T.
    • 그렇지 않고 이러한 형식이 T두 개 이상 있는 경우 오류가 생성 되 고 추가 단계가 수행 되지 않습니다.Otherwise, if there is more than one such type T, then an error is produced and no further steps are taken.
    • 그렇지 않고에서 X System.Collections.IEnumerable 인터페이스로의 암시적 변환이 있는 경우 컬렉션 형식이 이 인터페이스이 고, 열거자 형식이 인터페이스 System.Collections.IEnumerator이 고, 요소 형식이 입니다 object.Otherwise, if there is an implicit conversion from X to the System.Collections.IEnumerable interface, then the collection type is this interface, the enumerator type is the interface System.Collections.IEnumerator, and the element type is object.
    • 그렇지 않으면 오류가 생성 되 고 추가 단계가 수행 되지 않습니다.Otherwise, an error is produced and no further steps are taken.

위의 단계에서 성공 하면 컬렉션 형식 C, 열거자 형식 E 및 요소 형식을 T명확 하 게 생성 합니다.The above steps, if successful, unambiguously produce a collection type C, enumerator type E and element type T. 양식의 foreach 문A foreach statement of the form

foreach (V v in x) embedded_statement

다음으로 확장 됩니다.is then expanded to:

{
    E e = ((C)(x)).GetEnumerator();
    try {
        while (e.MoveNext()) {
            V v = (V)(T)e.Current;
            embedded_statement
        }
    }
    finally {
        ... // Dispose e
    }
}

변수 e 는 식 x 또는 포함 된 문이나 프로그램의 다른 소스 코드에서 볼 수 없거나 액세스할 수 없습니다.The variable e is not visible to or accessible to the expression x or the embedded statement or any other source code of the program. 변수가 v 포함 된 문에서 읽기 전용입니다.The variable v is read-only in the embedded statement. @No__t-1 (요소 형식)에서 V (foreach 문의 local_variable_type )로의 명시적 변환 (명시적변환)이 없는 경우 오류가 발생 하 고 추가 단계를 수행 하지 않습니다.If there is not an explicit conversion (Explicit conversions) from T (the element type) to V (the local_variable_type in the foreach statement), an error is produced and no further steps are taken. xnull 이있으면런타임에System.NullReferenceException 이 throw 됩니다.If x has the value null, a System.NullReferenceException is thrown at run-time.

구현에서는 특정 foreach 문을 다르게 구현할 수 있습니다. 예를 들어, 동작이 위의 확장과 일치 하는 경우 성능상의 이유로이를 다르게 구현할 수 있습니다.An implementation is permitted to implement a given foreach-statement differently, e.g. for performance reasons, as long as the behavior is consistent with the above expansion.

While 루프 내의 vembedded_statement에서 발생 하는 익명 함수에서 캡처하는 방법에 중요 합니다.The placement of v inside the while loop is important for how it is captured by any anonymous function occurring in the embedded_statement.

예를 들어 다음과 같은 가치를 제공해야 합니다.For example:

int[] values = { 7, 9, 13 };
Action f = null;

foreach (var value in values)
{
    if (f == null) f = () => Console.WriteLine("First value: " + value);
}

f();

v while 루프 외부에서 선언 되는 경우 모든 반복에서 공유 되 고 for 루프 뒤의 해당 값은의 f 호출이 인쇄 되는 최종 13값인입니다.If v was declared outside of the while loop, it would be shared among all iterations, and its value after the for loop would be the final value, 13, which is what the invocation of f would print. 대신 각 반복에 고유한 변수가 v있으므로 첫 번째 반복에서에 의해 f 캡처된 하나는 값을 계속 유지 합니다 .이 값 7은 인쇄 됩니다.Instead, because each iteration has its own variable v, the one captured by f in the first iteration will continue to hold the value 7, which is what will be printed. (참고: 이전 버전의 C# 는 v while 루프 외부에서 선언 했습니다.)(Note: earlier versions of C# declared v outside of the while loop.)

Finally 블록의 본문은 다음 단계에 따라 생성 됩니다.The body of the finally block is constructed according to the following steps:

  • 에서 E System.IDisposable 인터페이스로의 암시적 변환이 있는 경우If there is an implicit conversion from E to the System.IDisposable interface, then

    • E null을 허용 하지 않는 값 형식인 경우 finally 절은에 해당 하는 의미 체계를 확장 합니다.If E is a non-nullable value type then the finally clause is expanded to the semantic equivalent of:

      finally {
          ((System.IDisposable)e).Dispose();
      }
      
    • 그렇지 않으면 finally 절은에 해당 하는 의미 체계를 확장 합니다.Otherwise the finally clause is expanded to the semantic equivalent of:

      finally {
          if (e != null) ((System.IDisposable)e).Dispose();
      }
      

    가 값 형식 E 이거나 값 형식으로 인스턴스화된 형식 매개 변수가 인 경우 e 를로 System.IDisposable 캐스팅 하면 boxing이 발생 하지 않습니다.except that if E is a value type, or a type parameter instantiated to a value type, then the cast of e to System.IDisposable will not cause boxing to occur.

  • 그렇지 않고가 E sealed 형식이 면 finally 절이 빈 블록으로 확장 됩니다.Otherwise, if E is a sealed type, the finally clause is expanded to an empty block:

    finally {
    }
    
  • 그렇지 않으면 finally 절이 다음으로 확장 됩니다.Otherwise, the finally clause is expanded to:

    finally {
        System.IDisposable d = e as System.IDisposable;
        if (d != null) d.Dispose();
    }
    

    지역 변수 d 는 사용자 코드에 표시 되거나 사용자 코드에 액세스할 수 없습니다.The local variable d is not visible to or accessible to any user code. 특히 해당 범위에 finally 블록이 포함 된 다른 변수와 충돌 하지 않습니다.In particular, it does not conflict with any other variable whose scope includes the finally block.

에서 배열의 요소를 foreach 트래버스하는 순서는 다음과 같습니다. 1 차원 배열 요소의 경우 인덱스부터 시작 하 여 인덱스부터 시작 0 Length - 1하 여 인덱스 순서를 늘립니다.The order in which foreach traverses the elements of an array, is as follows: For single-dimensional arrays elements are traversed in increasing index order, starting with index 0 and ending with index Length - 1. 다차원 배열의 경우 가장 오른쪽 차원의 인덱스가 먼저 증가 하 고 그 다음 왼쪽 차원이 이동 하도록 요소를 트래버스 합니다.For multi-dimensional arrays, elements are traversed such that the indices of the rightmost dimension are increased first, then the next left dimension, and so on to the left.

다음 예제에서는 요소 순서에 따라 2 차원 배열의 각 값을 출력 합니다.The following example prints out each value in a two-dimensional array, in element order:

using System;

class Test
{
    static void Main() {
        double[,] values = {
            {1.2, 2.3, 3.4, 4.5},
            {5.6, 6.7, 7.8, 8.9}
        };

        foreach (double elementValue in values)
            Console.Write("{0} ", elementValue);

        Console.WriteLine();
    }
}

생성 되는 출력은 다음과 같습니다.The output produced is as follows:

1.2 2.3 3.4 4.5 5.6 6.7 7.8 8.9

예제에서In the example

int[] numbers = { 1, 3, 5, 7, 9 };
foreach (var n in numbers) Console.WriteLine(n);

n 형식은 intnumbers요소 형식인로 유추 됩니다.the type of n is inferred to be int, the element type of numbers.

점프 문Jump statements

점프 문이 무조건 전송 컨트롤입니다.Jump statements unconditionally transfer control.

jump_statement
    : break_statement
    | continue_statement
    | goto_statement
    | return_statement
    | throw_statement
    ;

점프 문이 제어를 전송 하는 위치를 점프 문의 대상 이라고 합니다.The location to which a jump statement transfers control is called the target of the jump statement.

점프 문이 블록 내에서 발생 하 고 해당 점프 문의 대상이 해당 블록 외부에 있는 경우 점프 문이 블록을 종료 합니다.When a jump statement occurs within a block, and the target of that jump statement is outside that block, the jump statement is said to exit the block. 점프 문은 블록 밖으로 제어를 전송할 수 있지만 제어를 블록으로 전송할 수는 없습니다.While a jump statement may transfer control out of a block, it can never transfer control into a block.

점프 문 실행은 중간 try 문이 있기 때문에 복잡 합니다.Execution of jump statements is complicated by the presence of intervening try statements. 이러한 try 문이 없으면 점프 문이 무조건 점프 문에서 대상으로 제어를 전달 합니다.In the absence of such try statements, a jump statement unconditionally transfers control from the jump statement to its target. 이러한 중간 try 문이 있으면 실행이 더 복잡해 집니다.In the presence of such intervening try statements, execution is more complex. 점프 문이 연결 finally 된 블록을 사용 하 try 여 하나 이상의 블록을 종료 하는 경우 처음에 finally 는 제어가 가장 안쪽 try 의 문 블록으로 전송 됩니다.If the jump statement exits one or more try blocks with associated finally blocks, control is initially transferred to the finally block of the innermost try statement. 제어가 finally 블록의 끝점에 도달 하면 다음 바깥쪽 try 문의 finally 블록으로 제어가 전달 됩니다.When and if control reaches the end point of a finally block, control is transferred to the finally block of the next enclosing try statement. 이 프로세스는 모든 중간 finally try 문의 블록이 실행 될 때까지 반복 됩니다.This process is repeated until the finally blocks of all intervening try statements have been executed.

예제에서In the example

using System;

class Test
{
    static void Main() {
        while (true) {
            try {
                try {
                    Console.WriteLine("Before break");
                    break;
                }
                finally {
                    Console.WriteLine("Innermost finally block");
                }
            }
            finally {
                Console.WriteLine("Outermost finally block");
            }
        }
        Console.WriteLine("After break");
    }
}

finallytry 문과 연결 된 블록은 컨트롤이 점프 문의 대상으로 전송 되기 전에 실행 됩니다.the finally blocks associated with two try statements are executed before control is transferred to the target of the jump statement.

생성 되는 출력은 다음과 같습니다.The output produced is as follows:

Before break
Innermost finally block
Outermost finally block
After break

Break 문The break statement

while 문은가장for가까운 바깥쪽 switch, ,foreach , 또는 문을 종료 합니다. do breakThe break statement exits the nearest enclosing switch, while, do, for, or foreach statement.

break_statement
    : 'break' ';'
    ;

break 문의 대상은 가장 가까운 바깥쪽 switch, while do,, for또는 문의끝점입니다.foreachThe target of a break statement is the end point of the nearest enclosing switch, while, do, for, or foreach statement. break 문이 switch, ,,for또는 문으로foreach 묶이지 않은 경우 컴파일 타임 오류가 발생 합니다. while doIf a break statement is not enclosed by a switch, while, do, for, or foreach statement, a compile-time error occurs.

switch여러 ,for,, 또는foreach 문이 서로 중첩break 된 경우 문은 가장 안쪽 문에만 적용 됩니다. while doWhen multiple switch, while, do, for, or foreach statements are nested within each other, a break statement applies only to the innermost statement. 여러 중첩 수준 goto 에서 제어를 전송 하려면 문 (goto 문)을 사용 해야 합니다.To transfer control across multiple nesting levels, a goto statement (The goto statement) must be used.

문은 블록 (try 문)을 finally 종료할 수 없습니다. breakA break statement cannot exit a finally block (The try statement). 문이 블록 내에서 발생 break 하는 경우 문의 대상은 동일한 finally 블록 내에 있어야 합니다. 그렇지 않으면 컴파일 타임 오류가 발생 합니다. finally breakWhen a break statement occurs within a finally block, the target of the break statement must be within the same finally block; otherwise, a compile-time error occurs.

break 문은 다음과 같이 실행 됩니다.A break statement is executed as follows:

  • try try 문이연결finally 된 블록을 사용 하 여 하나 이상의 블록을 종료 하는 경우 처음에는 제어가 가장 안쪽의 문 블록으로 전송 됩니다. finally breakIf the break statement exits one or more try blocks with associated finally blocks, control is initially transferred to the finally block of the innermost try statement. 제어가 finally 블록의 끝점에 도달 하면 다음 바깥쪽 try 문의 finally 블록으로 제어가 전달 됩니다.When and if control reaches the end point of a finally block, control is transferred to the finally block of the next enclosing try statement. 이 프로세스는 모든 중간 finally try 문의 블록이 실행 될 때까지 반복 됩니다.This process is repeated until the finally blocks of all intervening try statements have been executed.
  • 제어가 break 문의 대상으로 전송 됩니다.Control is transferred to the target of the break statement.

문은 다른 곳에서 제어를 전달 하기 때문에 break 문의 끝점에는 연결할 수 없습니다. breakBecause a break statement unconditionally transfers control elsewhere, the end point of a break statement is never reachable.

Continue 문The continue statement

while do문은 가장 가까운 바깥쪽, ,for 또는foreach 문의 새 반복을 시작 합니다. continueThe continue statement starts a new iteration of the nearest enclosing while, do, for, or foreach statement.

continue_statement
    : 'continue' ';'
    ;

continue 문의 대상은 가장 가까운 바깥쪽 while, do, for또는 foreach 문에 포함 된 문의 끝점입니다.The target of a continue statement is the end point of the embedded statement of the nearest enclosing while, do, for, or foreach statement. 문이,while ,또는foreach 문으로 묶이지 않은 경우 컴파일 타임 오류가 발생 합니다. do continue forIf a continue statement is not enclosed by a while, do, for, or foreach statement, a compile-time error occurs.

여러 while, do, 또는문이foreach 서로 중첩continue 된 경우 문은 가장 안쪽 문에만 적용 됩니다. forWhen multiple while, do, for, or foreach statements are nested within each other, a continue statement applies only to the innermost statement. 여러 중첩 수준 goto 에서 제어를 전송 하려면 문 (goto 문)을 사용 해야 합니다.To transfer control across multiple nesting levels, a goto statement (The goto statement) must be used.

문은 블록 (try 문)을 finally 종료할 수 없습니다. continueA continue statement cannot exit a finally block (The try statement). 문이 블록 내에서 발생 continue 하는 경우 문의 대상은 동일한 finally 블록 내에 있어야 합니다. 그렇지 않으면 컴파일 타임 오류가 발생 합니다. finally continueWhen a continue statement occurs within a finally block, the target of the continue statement must be within the same finally block; otherwise a compile-time error occurs.

continue 문은 다음과 같이 실행 됩니다.A continue statement is executed as follows:

  • try try 문이연결finally 된 블록을 사용 하 여 하나 이상의 블록을 종료 하는 경우 처음에는 제어가 가장 안쪽의 문 블록으로 전송 됩니다. finally continueIf the continue statement exits one or more try blocks with associated finally blocks, control is initially transferred to the finally block of the innermost try statement. 제어가 finally 블록의 끝점에 도달 하면 다음 바깥쪽 try 문의 finally 블록으로 제어가 전달 됩니다.When and if control reaches the end point of a finally block, control is transferred to the finally block of the next enclosing try statement. 이 프로세스는 모든 중간 finally try 문의 블록이 실행 될 때까지 반복 됩니다.This process is repeated until the finally blocks of all intervening try statements have been executed.
  • 제어가 continue 문의 대상으로 전송 됩니다.Control is transferred to the target of the continue statement.

문은 다른 곳에서 제어를 전달 하기 때문에 continue 문의 끝점에는 연결할 수 없습니다. continueBecause a continue statement unconditionally transfers control elsewhere, the end point of a continue statement is never reachable.

goto 문The goto statement

문은 goto 레이블로 표시 된 문으로 제어를 전달 합니다.The goto statement transfers control to a statement that is marked by a label.

goto_statement
    : 'goto' identifier ';'
    | 'goto' 'case' constant_expression ';'
    | 'goto' 'default' ';'
    ;

goto 식별자 문의 대상은 지정 된 레이블이 있는 레이블이 지정 된 문입니다.The target of a goto identifier statement is the labeled statement with the given label. 지정 된 이름의 레이블이 현재 함수 멤버 goto 에 없거나 문이 레이블 범위 내에 있지 않은 경우 컴파일 타임 오류가 발생 합니다.If a label with the given name does not exist in the current function member, or if the goto statement is not within the scope of the label, a compile-time error occurs. 이 규칙은 goto 문을 사용 하 여 중첩 된 범위 밖으로 제어를 전송할 수 있도록 허용 합니다.This rule permits the use of a goto statement to transfer control out of a nested scope, but not into a nested scope. 예제에서In the example

using System;

class Test
{
    static void Main(string[] args) {
        string[,] table = {
            {"Red", "Blue", "Green"},
            {"Monday", "Wednesday", "Friday"}
        };

        foreach (string str in args) {
            int row, colm;
            for (row = 0; row <= 1; ++row)
                for (colm = 0; colm <= 2; ++colm)
                    if (str == table[row,colm])
                         goto done;

            Console.WriteLine("{0} not found", str);
            continue;
    done:
            Console.WriteLine("Found {0} at [{1}][{2}]", str, row, colm);
        }
    }
}

goto 문은 중첩 된 범위에서 제어를 전달 하는 데 사용 됩니다.a goto statement is used to transfer control out of a nested scope.

goto case 문의 대상은 지정 된 상수 값의 case 레이블을 포함 하는 바로 바깥쪽 switch 문 (switch 문)의 문 목록입니다.The target of a goto case statement is the statement list in the immediately enclosing switch statement (The switch statement), which contains a case label with the given constant value. @No__t-0 문이 switch 문으로 묶여 있지 않은 경우 (암시적 변환) constant_expression 가 가장 가까운 바깥쪽 switch 문의 관리 형식으로 변환 되지 않거나 가장 가까운 바깥쪽 switch 문에 지정 된 상수 값을 가진 case 레이블이 포함 되어 있지 않습니다. 컴파일 시간 오류가 발생 합니다.If the goto case statement is not enclosed by a switch statement, if the constant_expression is not implicitly convertible (Implicit conversions) to the governing type of the nearest enclosing switch statement, or if the nearest enclosing switch statement does not contain a case label with the given constant value, a compile-time error occurs.

goto default 문의 대상은 default 레이블을 포함 하는 바로 바깥쪽 switch 문 (switch 문)의 문 목록입니다.The target of a goto default statement is the statement list in the immediately enclosing switch statement (The switch statement), which contains a default label. 문이 문으로 묶여 switch default 있지 않거나 가장 가까운 바깥쪽 문에 레이블이 없는 경우 컴파일 타임 오류가 발생 합니다. switch goto defaultIf the goto default statement is not enclosed by a switch statement, or if the nearest enclosing switch statement does not contain a default label, a compile-time error occurs.

문은 블록 (try 문)을 finally 종료할 수 없습니다. gotoA goto statement cannot exit a finally block (The try statement). 문이 블록 내에서 발생 goto 하는 경우 문의 대상은 동일한 finally 블록 내에 있어야 합니다. 그렇지 않으면 컴파일 타임 오류가 발생 합니다. finally gotoWhen a goto statement occurs within a finally block, the target of the goto statement must be within the same finally block, or otherwise a compile-time error occurs.

goto 문은 다음과 같이 실행 됩니다.A goto statement is executed as follows:

  • try try 문이연결finally 된 블록을 사용 하 여 하나 이상의 블록을 종료 하는 경우 처음에는 제어가 가장 안쪽의 문 블록으로 전송 됩니다. finally gotoIf the goto statement exits one or more try blocks with associated finally blocks, control is initially transferred to the finally block of the innermost try statement. 제어가 finally 블록의 끝점에 도달 하면 다음 바깥쪽 try 문의 finally 블록으로 제어가 전달 됩니다.When and if control reaches the end point of a finally block, control is transferred to the finally block of the next enclosing try statement. 이 프로세스는 모든 중간 finally try 문의 블록이 실행 될 때까지 반복 됩니다.This process is repeated until the finally blocks of all intervening try statements have been executed.
  • 제어가 goto 문의 대상으로 전송 됩니다.Control is transferred to the target of the goto statement.

문은 다른 곳에서 제어를 전달 하기 때문에 goto 문의 끝점에는 연결할 수 없습니다. gotoBecause a goto statement unconditionally transfers control elsewhere, the end point of a goto statement is never reachable.

Return 문The return statement

return 문은 return 문이 표시 되는 함수의 현재 호출자에 게 제어를 반환 합니다.The return statement returns control to the current caller of the function in which the return statement appears.

return_statement
    : 'return' expression? ';'
    ;

식이 없는 return 문은 값을 계산하지 않는 함수 멤버, 즉 결과 형식(메서드 본문)의 void 메서드, 속성 또는 set 인덱서의 접근자인 경우에만 사용할 수 있습니다. addremove 이벤트, 인스턴스 생성자, 정적 생성자 또는 소멸자의 및 접근자입니다.A return statement with no expression can be used only in a function member that does not compute a value, that is, a method with the result type (Method body) void, the set accessor of a property or indexer, the add and remove accessors of an event, an instance constructor, a static constructor, or a destructor.

식이 있는 get 문은 값을 계산 하는 함수 멤버, 즉 void가 아닌 결과 형식의 메서드, 속성 또는 인덱서의 접근자 또는 사용자 정의 연산자로만 사용할 수 있습니다. returnA return statement with an expression can only be used in a function member that computes a value, that is, a method with a non-void result type, the get accessor of a property or indexer, or a user-defined operator. 식의 형식에서 포함 하는 함수 멤버의 반환 형식에 대 한 암시적 변환 (암시적 변환)이 존재 해야 합니다.An implicit conversion (Implicit conversions) must exist from the type of the expression to the return type of the containing function member.

익명함수 식의 본문에서 Return 문을 사용 하 고 해당 함수에 대해 존재 하는 변환을 결정 하는 데 참여할 수도 있습니다.Return statements can also be used in the body of anonymous function expressions (Anonymous function expressions), and participate in determining which conversions exist for those functions.

return 문이 finally 블록 (try 문)에 표시 되는 컴파일 시간 오류입니다.It is a compile-time error for a return statement to appear in a finally block (The try statement).

return 문은 다음과 같이 실행 됩니다.A return statement is executed as follows:

  • return 문이 식을 지정 하는 경우 식이 계산 되 고 결과 값이 암시적 변환에 의해 포함 함수의 반환 형식으로 변환 됩니다.If the return statement specifies an expression, the expression is evaluated and the resulting value is converted to the return type of the containing function by an implicit conversion. 변환 결과는 함수에 의해 생성 되는 결과 값이 됩니다.The result of the conversion becomes the result value produced by the function.
  • finally try catch try 문이 연결 된블록을포함하는하나이상의또는블록으로묶여있는경우처음에는제어가가장안쪽의문블록으로전송됩니다.finally returnIf the return statement is enclosed by one or more try or catch blocks with associated finally blocks, control is initially transferred to the finally block of the innermost try statement. 제어가 finally 블록의 끝점에 도달 하면 다음 바깥쪽 try 문의 finally 블록으로 제어가 전달 됩니다.When and if control reaches the end point of a finally block, control is transferred to the finally block of the next enclosing try statement. 이 프로세스는 모든 바깥쪽 finally try 문의 블록이 실행 될 때까지 반복 됩니다.This process is repeated until the finally blocks of all enclosing try statements have been executed.
  • 포함 하는 함수가 비동기 함수가 아닌 경우 결과 값 (있는 경우)과 함께 포함 함수의 호출자에 게 컨트롤이 반환 됩니다.If the containing function is not an async function, control is returned to the caller of the containing function along with the result value, if any.
  • 포함 함수가 비동기 함수인 경우 컨트롤은 현재 호출자에 게 반환 되 고 결과 값 (있는 경우)은 (열거자 인터페이스)에 설명 된 대로 반환 작업에 기록 됩니다.If the containing function is an async function, control is returned to the current caller, and the result value, if any, is recorded in the return task as described in (Enumerator interfaces).

문은 다른 곳에서 제어를 전달 하기 때문에 return 문의 끝점에는 연결할 수 없습니다. returnBecause a return statement unconditionally transfers control elsewhere, the end point of a return statement is never reachable.

Throw 문The throw statement

throw 문에서 예외를 throw 합니다.The throw statement throws an exception.

throw_statement
    : 'throw' expression? ';'
    ;

식이 throw 있는 문은 식을 계산 하 여 생성 된 값을 throw 합니다.A throw statement with an expression throws the value produced by evaluating the expression. 식은에서 System.Exception System.Exception 파생 되는 클래스 형식의 값 또는 해당 하는 (또는 하위 클래스)를 유효한 기본 클래스로 포함 System.Exception 하는 형식 매개 변수 형식의 값을 나타내야 합니다.The expression must denote a value of the class type System.Exception, of a class type that derives from System.Exception or of a type parameter type that has System.Exception (or a subclass thereof) as its effective base class. 식의 계산이 생성 null System.NullReferenceException 되 면이 대신 throw 됩니다.If evaluation of the expression produces null, a System.NullReferenceException is thrown instead.

식이 없는 catch catch 문은 블록 에서만 사용할 수 있습니다 .이 경우 해당 문은 해당 블록에 의해 현재 처리 되 고 있는 예외를 다시 throw 합니다. throwA throw statement with no expression can be used only in a catch block, in which case that statement re-throws the exception that is currently being handled by that catch block.

문은 다른 곳에서 제어를 전달 하기 때문에 throw 문의 끝점에는 연결할 수 없습니다. throwBecause a throw statement unconditionally transfers control elsewhere, the end point of a throw statement is never reachable.

예외가 throw 되 면 예외를 처리할 수 있는 바깥쪽 catch try 문의 첫 번째 절에 제어가 전송 됩니다.When an exception is thrown, control is transferred to the first catch clause in an enclosing try statement that can handle the exception. 적절 한 예외 처리기로 제어를 전송 하는 지점까지 throw 되는 예외 지점에서 발생 하는 프로세스를 예외 전파라고 합니다.The process that takes place from the point of the exception being thrown to the point of transferring control to a suitable exception handler is known as exception propagation. 예외의 전파는 예외와 일치 하는 catch 절이 발견 될 때까지 다음 단계를 반복적으로 평가 하는 것으로 구성 됩니다.Propagation of an exception consists of repeatedly evaluating the following steps until a catch clause that matches the exception is found. 이 설명에서 throw 지점은 처음에 예외가 throw 되는 위치입니다.In this description, the throw point is initially the location at which the exception is thrown.

  • 현재 함수 멤버에서 throw 지점을 포함 try 하는 각 문이 검사 됩니다.In the current function member, each try statement that encloses the throw point is examined. 가장 안쪽 S try 문으로 시작 하 여 가장 바깥쪽 try 문으로 끝나는 각 문에 대해 다음 단계가 평가 됩니다.For each statement S, starting with the innermost try statement and ending with the outermost try statement, the following steps are evaluated:

    • 블록에서 throw 지점을 포함 하 고 catch S에 절 catch 이 하나 이상 있는 경우에 지정 된 규칙에 따라 절을 순서 대로 검사 하 여 예외에 대 한 적절 한 처리기를 찾습니다. S try Try 문의섹션입니다.If the try block of S encloses the throw point and if S has one or more catch clauses, the catch clauses are examined in order of appearance to locate a suitable handler for the exception, according to the rules specified in Section The try statement. 일치 catch 절이 있는 경우 제어를 해당 catch 절의 블록으로 전송 하 여 예외 전파를 완료 합니다.If a matching catch clause is located, the exception propagation is completed by transferring control to the block of that catch clause.

    • catch S finally finally 그렇지 않고 try 블록 또는S 블록에서 throw 지점을 포함 하 고,에 블록이 있으면 제어는 블록으로 전송 됩니다.Otherwise, if the try block or a catch block of S encloses the throw point and if S has a finally block, control is transferred to the finally block. 블록에서 finally 다른 예외를 throw 하는 경우 현재 예외의 처리가 종료 됩니다.If the finally block throws another exception, processing of the current exception is terminated. 그렇지 않으면 제어가 finally 블록의 끝점에 도달 하면 현재 예외 처리가 계속 됩니다.Otherwise, when control reaches the end point of the finally block, processing of the current exception is continued.

  • 현재 함수 호출에서 예외 처리기를 찾을 수 없는 경우 함수 호출이 종료 되 고 다음 중 하나가 발생 합니다.If an exception handler was not located in the current function invocation, the function invocation is terminated, and one of the following occurs:

    • 현재 함수가 비동기 함수가 아닌 경우 함수 멤버를 호출한 문에 해당 하는 throw point를 사용 하 여 함수의 호출자에 대해 위의 단계가 반복 됩니다.If the current function is non-async, the steps above are repeated for the caller of the function with a throw point corresponding to the statement from which the function member was invoked.

    • 현재 함수가 비동기이 고 작업을 반환 하는 경우이 예외는 열거자 인터페이스에 설명 된 대로 오류 또는 취소 된 상태로 전환 되는 반환 작업에 기록 됩니다.If the current function is async and task-returning, the exception is recorded in the return task, which is put into a faulted or cancelled state as described in Enumerator interfaces.

    • 현재 함수가 비동기이 고 void를 반환 하는 경우에는 열거 가능한 인터페이스에 설명 된 대로 현재 스레드의 동기화 컨텍스트에 알림이 표시 됩니다.If the current function is async and void-returning, the synchronization context of the current thread is notified as described in Enumerable interfaces.

  • 예외 처리가 현재 스레드에서 모든 함수 멤버 호출을 종료 하는 경우 스레드에 대 한 처리기가 없음을 나타내는 스레드가 종료 됩니다.If the exception processing terminates all function member invocations in the current thread, indicating that the thread has no handler for the exception, then the thread is itself terminated. 이러한 종료의 영향은 구현에 정의 되어 있습니다.The impact of such termination is implementation-defined.

Try 문The try statement

try 문은 블록을 실행 하는 동안 발생 하는 예외를 catch 하기 위한 메커니즘을 제공 합니다.The try statement provides a mechanism for catching exceptions that occur during execution of a block. 또한 문은 제어가 try 문을 떠날 때 항상 실행 되는 코드 블록을 지정 하는 기능을 제공 합니다. tryFurthermore, the try statement provides the ability to specify a block of code that is always executed when control leaves the try statement.

try_statement
    : 'try' block catch_clause+
    | 'try' block finally_clause
    | 'try' block catch_clause+ finally_clause
    ;

catch_clause
    : 'catch' exception_specifier? exception_filter?  block
    ;

exception_specifier
    : '(' type identifier? ')'
    ;

exception_filter
    : 'when' '(' expression ')'
    ;

finally_clause
    : 'finally' block
    ;

다음과 같은 세 가지 형식의 try 문을 사용할 수 있습니다.There are three possible forms of try statements:

  • 블록 뒤에 하나 catch 이상의 블록이 있습니다. tryA try block followed by one or more catch blocks.
  • 블록 tryfinally 에 블록을 만듭니다.A try block followed by a finally block.
  • 블록 뒤에 하나 catch 이상의 블록이 오고 그 finally 뒤에 블록이 옵니다. tryA try block followed by one or more catch blocks followed by a finally block.

@No__t-0 절에서 exception_specifier를 지정 하는 경우 형식은-2이 고, System.Exception에서 파생 된 형식 또는 System.Exception (또는 그 하위 클래스)가 유효한 기본 클래스로 포함 된 형식 매개 변수 형식 이어야 @no__t 합니다.When a catch clause specifies an exception_specifier, the type must be System.Exception, a type that derives from System.Exception or a type parameter type that has System.Exception (or a subclass thereof) as its effective base class.

@No__t-0 절에서 식별자가 있는 exception_specifier 를 모두 지정 하는 경우 지정 된 이름 및 형식의 예외 변수가 선언 됩니다.When a catch clause specifies both an exception_specifier with an identifier, an exception variable of the given name and type is declared. 예외 변수는 catch 절을 통해 확장 되는 범위의 지역 변수에 해당 합니다.The exception variable corresponds to a local variable with a scope that extends over the catch clause. Exception_filter블록을 실행 하는 동안 예외 변수는 현재 처리 중인 예외를 나타냅니다.During execution of the exception_filter and block, the exception variable represents the exception currently being handled. 한정 된 할당 검사를 위해 예외 변수는 전체 범위에서 명확 하 게 할당 된 것으로 간주 됩니다.For purposes of definite assignment checking, the exception variable is considered definitely assigned in its entire scope.

절에 catch 예외 변수 이름이 포함 되어 있지 않으면 필터 및 catch 블록에서 예외 개체에 액세스할 수 없습니다.Unless a catch clause includes an exception variable name, it is impossible to access the exception object in the filter and catch block.

Exception_specifier 를 지정 하지 않는 catch 절은 일반 catch 절 이라고 합니다.A catch clause that does not specify an exception_specifier is called a general catch clause.

일부 프로그래밍 언어는에서 System.Exception파생 된 개체로 표현할 수 없는 예외를 지원할 수 있지만 이러한 예외는 코드에 의해 C# 생성 되지 않을 수 있습니다.Some programming languages may support exceptions that are not representable as an object derived from System.Exception, although such exceptions could never be generated by C# code. 일반 catch 절은 이러한 예외를 catch 하는 데 사용할 수 있습니다.A general catch clause may be used to catch such exceptions. 따라서 일반 catch 절은 형식을 System.Exception지정 하는 절과 의미상 다릅니다. 즉, 다른 언어의 예외를 catch 할 수도 있습니다.Thus, a general catch clause is semantically different from one that specifies the type System.Exception, in that the former may also catch exceptions from other languages.

예외에 대 한 처리기를 찾기 위해 catch 절은 어휘 순서로 검사 됩니다.In order to locate a handler for an exception, catch clauses are examined in lexical order. 절에서 형식을 지정 하 고 예외 필터를 지정 하지 않은 경우에는 동일한 try 문에서 이후 catch 절이 해당 형식에서 파생 되거나 파생 된 형식을 지정 하는 컴파일 시간 오류가 발생 합니다. catchIf a catch clause specifies a type but no exception filter, it is a compile-time error for a later catch clause in the same try statement to specify a type that is the same as, or is derived from, that type. 절이 형식을 지정 하지 않고 필터를 지정 하지 않은 경우 해당 try 문에 대 catch 한 마지막 절 이어야 합니다. catchIf a catch clause specifies no type and no filter, it must be the last catch clause for that try statement.

catch 블록 내에서 식이 없는 throw 문(throw문)을 사용하여 catch 블록에서 catch한 예외를 다시 throw할 수 있습니다.Within a catch block, a throw statement (The throw statement) with no expression can be used to re-throw the exception that was caught by the catch block. 예외 변수에 대 한 할당은 다시 throw 되는 예외를 변경 하지 않습니다.Assignments to an exception variable do not alter the exception that is re-thrown.

예제에서In the example

using System;

class Test
{
    static void F() {
        try {
            G();
        }
        catch (Exception e) {
            Console.WriteLine("Exception in F: " + e.Message);
            e = new Exception("F");
            throw;                // re-throw
        }
    }

    static void G() {
        throw new Exception("G");
    }

    static void Main() {
        try {
            F();
        }
        catch (Exception e) {
            Console.WriteLine("Exception in Main: " + e.Message);
        }
    }
}

메서드 F 는 예외를 catch 하 고, 일부 진단 정보를 콘솔에 기록 하 고, 예외 변수를 변경 하 고, 예외를 다시 throw 합니다.the method F catches an exception, writes some diagnostic information to the console, alters the exception variable, and re-throws the exception. 다시 throw 되는 예외는 원래 예외 이므로 생성 되는 출력은 다음과 같습니다.The exception that is re-thrown is the original exception, so the output produced is:

Exception in F: G
Exception in Main: G

현재 예외를 다시 throw 하는 대신 e 첫 번째 catch 블록이 throw 된 경우 생성 되는 출력은 다음과 같습니다.If the first catch block had thrown e instead of rethrowing the current exception, the output produced would be as follows:

Exception in F: G
Exception in Main: F

break, 또는문이goto 블록 밖finally 으로 제어를 전송 하는 경우 컴파일 시간 오류가 발생 합니다. continueIt is a compile-time error for a break, continue, or goto statement to transfer control out of a finally block. 블록에서finally , continue또는 goto 문이 발생 하면 문의 대상이 동일한 finally 블록 내에 있어야 합니다. 그렇지 않으면 컴파일 타임 오류가 발생 합니다. breakWhen a break, continue, or goto statement occurs in a finally block, the target of the statement must be within the same finally block, or otherwise a compile-time error occurs.

return 문이 블록finally 에서 발생 하는 경우 컴파일 시간 오류가 발생 합니다.It is a compile-time error for a return statement to occur in a finally block.

try 문은 다음과 같이 실행 됩니다.A try statement is executed as follows:

  • 제어가 try 블록으로 전송 됩니다.Control is transferred to the try block.

  • 제어가 try 블록의 끝점에 도달 하는 경우 및 if:When and if control reaches the end point of the try block:

    • try 문에 블록이finally있으면블록이실행됩니다 finally .If the try statement has a finally block, the finally block is executed.
    • 제어가 try 문의 끝점으로 전송 됩니다.Control is transferred to the end point of the try statement.
  • try 블록을 실행 하 try 는 동안 예외가 문으로 전파 되는 경우:If an exception is propagated to the try statement during execution of the try block:

    • catch 절 (있는 경우)은 예외에 적합 한 처리기를 찾기 위해 표시 순서 대로 검사 됩니다.The catch clauses, if any, are examined in order of appearance to locate a suitable handler for the exception. catch 절에서 형식을 지정 하지 않거나 예외 형식이 나 예외 형식의 기본 형식을 지정 하는 경우:If a catch clause does not specify a type, or specifies the exception type or a base type of the exception type:
      • catch 절이 예외 변수를 선언 하는 경우 예외 개체는 예외 변수에 할당 됩니다.If the catch clause declares an exception variable, the exception object is assigned to the exception variable.
      • 절에서 catch 예외 필터를 선언 하는 경우 필터가 평가 됩니다.If the catch clause declares an exception filter, the filter is evaluated. false평가 되는 경우 catch 절은 일치 하는 항목이 아니므로 검색은 적절 한 처리기에 대 catch 한 후속 절을 계속 진행 합니다.If it evaluates to false, the catch clause is not a match, and the search continues through any subsequent catch clauses for a suitable handler.
      • 그렇지 않으면 catch 절이 일치 하는 것으로 간주 되 고 제어가 일치 하는 블록으로 전송 됩니다. catchOtherwise, the catch clause is considered a match, and control is transferred to the matching catch block.
      • 제어가 catch 블록의 끝점에 도달 하는 경우 및 if:When and if control reaches the end point of the catch block:
        • try 문에 블록이finally있으면블록이실행됩니다 finally .If the try statement has a finally block, the finally block is executed.
        • 제어가 try 문의 끝점으로 전송 됩니다.Control is transferred to the end point of the try statement.
      • catch 블록을 실행 하 try 는 동안 예외가 문으로 전파 되는 경우:If an exception is propagated to the try statement during execution of the catch block:
        • try 문에 블록이finally있으면블록이실행됩니다 finally .If the try statement has a finally block, the finally block is executed.
        • 예외는 다음 바깥쪽 try 문으로 전파 됩니다.The exception is propagated to the next enclosing try statement.
    • 문에 trycatch 이없거나해당예외와일치하는절이없으면입니다.catchIf the try statement has no catch clauses or if no catch clause matches the exception:
      • try 문에 블록이finally있으면블록이실행됩니다 finally .If the try statement has a finally block, the finally block is executed.
      • 예외는 다음 바깥쪽 try 문으로 전파 됩니다.The exception is propagated to the next enclosing try statement.

finally 블록의 문은 제어가 try 문을 떠날 때 항상 실행 됩니다.The statements of a finally block are always executed when control leaves a try statement. break이는 continue,, 또는return 문을 실행 한 결과로 또는에서 예외를 전파 한 결과로 제어 전송이 정상적인 실행의 결과로 발생 하는지 여부에 해당 try 합니다. goto 선언문.This is true whether the control transfer occurs as a result of normal execution, as a result of executing a break, continue, goto, or return statement, or as a result of propagating an exception out of the try statement.

finally 블록을 실행 하는 동안 예외가 throw 되 고 동일한 finally 블록 내에서 catch 되지 않는 경우 예외는 다음 바깥쪽 try 문으로 전파 됩니다.If an exception is thrown during execution of a finally block, and is not caught within the same finally block, the exception is propagated to the next enclosing try statement. 다른 예외를 전파 하는 동안 예외가 발생 한 경우 해당 예외가 손실 됩니다.If another exception was in the process of being propagated, that exception is lost. 예외를 전파 하는 프로세스는 throw 문 (throw 문)의 설명에 자세히 설명 되어 있습니다.The process of propagating an exception is discussed further in the description of the throw statement (The throw statement).

문에 try 도달할 수 있으면 try try 문의 블록에 접근할 수 있습니다.The try block of a try statement is reachable if the try statement is reachable.

문에 catch 연결할 수 있으면 try try 문의 블록에 접근할 수 있습니다.A catch block of a try statement is reachable if the try statement is reachable.

문에 finally 도달할 수 있으면 try try 문의 블록에 접근할 수 있습니다.The finally block of a try statement is reachable if the try statement is reachable.

다음 두 가지 조건에 try 모두 해당 하는 경우 문의 끝점에 연결할 수 있습니다.The end point of a try statement is reachable if both of the following are true:

  • try 블록의 끝점에 연결할 수 있거나 하나 catch 이상의 블록의 끝점에 연결할 수 있습니다.The end point of the try block is reachable or the end point of at least one catch block is reachable.
  • 블록이 있는 경우 finally 블록의 끝점에 연결할 수 있습니다. finallyIf a finally block is present, the end point of the finally block is reachable.

Checked 및 unchecked 문The checked and unchecked statements

및 문은 정수 계열 형식 산술 연산 및 변환에 대 한 오버플로 검사 컨텍스트 를 제어 하는 데 사용 됩니다. unchecked checkedThe checked and unchecked statements are used to control the overflow checking context for integral-type arithmetic operations and conversions.

checked_statement
    : 'checked' block
    ;

unchecked_statement
    : 'unchecked' block
    ;

문은 확인 된 unchecked 컨텍스트에서 블록의 모든 식을 계산 하 고, 문을 실행 하면 블록의 모든 식이 unchecked 컨텍스트에서 평가 됩니다. checkedThe checked statement causes all expressions in the block to be evaluated in a checked context, and the unchecked statement causes all expressions in the block to be evaluated in an unchecked context.

checkedunchecked 문은 식 대신 블록에서 작동한다는 점을 제외하고 checkedunchecked 연산자(checked 및 unchecked 연산자)와 정확하게 동일합니다.The checked and unchecked statements are precisely equivalent to the checked and unchecked operators (The checked and unchecked operators), except that they operate on blocks instead of expressions.

Lock 문The lock statement

lock 문은 지정 된 개체에 대 한 상호 배제 잠금을 얻어 문을 실행 한 다음 잠금을 해제 합니다.The lock statement obtains the mutual-exclusion lock for a given object, executes a statement, and then releases the lock.

lock_statement
    : 'lock' '(' expression ')' embedded_statement
    ;

@No__t-0 문의 식은 reference_type로 알려진 형식의 값을 나타내야 합니다.The expression of a lock statement must denote a value of a type known to be a reference_type. @No__t-1 문의 식에 대해 암시적 boxing 변환 (boxing 변환)이 수행 되지 않으므로 식에서 value_type의 값을 나타내는 컴파일 시간 오류가 발생 합니다.No implicit boxing conversion (Boxing conversions) is ever performed for the expression of a lock statement, and thus it is a compile-time error for the expression to denote a value of a value_type.

lock 의 문A lock statement of the form

lock (x) ...

여기서 xreference_type의 식 이며,는와 정확히 동일 합니다.where x is an expression of a reference_type, is precisely equivalent to

bool __lockWasTaken = false;
try {
    System.Threading.Monitor.Enter(x, ref __lockWasTaken);
    ...
}
finally {
    if (__lockWasTaken) System.Threading.Monitor.Exit(x);
}

단, x가 한 번만 계산됩니다.except that x is only evaluated once.

상호 배제 잠금이 유지 되는 동안 동일한 실행 스레드에서 실행 되는 코드는 잠금을 가져오고 해제할 수도 있습니다.While a mutual-exclusion lock is held, code executing in the same execution thread can also obtain and release the lock. 그러나 다른 스레드에서 실행 되는 코드는 잠금이 해제 될 때까지 잠금을 가져오지 못하도록 차단 됩니다.However, code executing in other threads is blocked from obtaining the lock until the lock is released.

정적 System.Type 데이터에 대 한 액세스를 동기화 하기 위해 개체를 잠그는 것은 권장 되지 않습니다.Locking System.Type objects in order to synchronize access to static data is not recommended. 다른 코드는 교착 상태가 발생할 수 있는 동일한 형식을 잠글 수 있습니다.Other code might lock on the same type, which can result in deadlock. 더 나은 방법은 전용 정적 개체를 잠가 정적 데이터에 대 한 액세스를 동기화 하는 것입니다.A better approach is to synchronize access to static data by locking a private static object. 예를 들어 다음과 같은 가치를 제공해야 합니다.For example:

class Cache
{
    private static readonly object synchronizationObject = new object();

    public static void Add(object x) {
        lock (Cache.synchronizationObject) {
            ...
        }
    }

    public static void Remove(object x) {
        lock (Cache.synchronizationObject) {
            ...
        }
    }
}

using 문The using statement

using 문은 하나 이상의 리소스를 가져오고 문을 실행 한 다음 리소스를 삭제 합니다.The using statement obtains one or more resources, executes a statement, and then disposes of the resource.

using_statement
    : 'using' '(' resource_acquisition ')' embedded_statement
    ;

resource_acquisition
    : local_variable_declaration
    | expression
    ;

리소스 는 라는 System.IDisposable Dispose단일 매개 변수가 없는 메서드를 포함 하는을 구현 하는 클래스 또는 구조체입니다.A resource is a class or struct that implements System.IDisposable, which includes a single parameterless method named Dispose. 리소스를 사용 하는 코드는를 Dispose 호출 하 여 리소스가 더 이상 필요 하지 않음을 나타낼 수 있습니다.Code that is using a resource can call Dispose to indicate that the resource is no longer needed. Dispose 호출 하지 않으면 가비지 수집의 결과로 자동 삭제가 발생 합니다.If Dispose is not called, then automatic disposal eventually occurs as a consequence of garbage collection.

Resource_acquisition 형식이 local_variable_declaration 인 경우 local_variable_declaration 의 형식은 dynamic 이거나 암시적으로 System.IDisposable로 변환 될 수 있는 형식 이어야 합니다.If the form of resource_acquisition is local_variable_declaration then the type of the local_variable_declaration must be either dynamic or a type that can be implicitly converted to System.IDisposable. Resource_acquisition 형식이 식인 경우이 식은 System.IDisposable로 암시적으로 변환할 수 있어야 합니다.If the form of resource_acquisition is expression then this expression must be implicitly convertible to System.IDisposable.

Resource_acquisition 에 선언 된 지역 변수는 읽기 전용 이며 이니셜라이저를 포함 해야 합니다.Local variables declared in a resource_acquisition are read-only, and must include an initializer. 포함 문이 이러한 지역 변수를 할당 ++ 또는 and -- 연산자를 통해 수정 하려고 시도 하는 경우 컴파일 시간 오류가 발생 합니다 .이 경우 해당 주소를 사용 하거나 ref 또는 out 매개 변수로 전달 합니다.A compile-time error occurs if the embedded statement attempts to modify these local variables (via assignment or the ++ and -- operators) , take the address of them, or pass them as ref or out parameters.

using 문은 획득, 사용 및 삭제의 세 부분으로 변환 됩니다.A using statement is translated into three parts: acquisition, usage, and disposal. 리소스 사용은 절을 try finally 포함 하는 문에 암시적으로 포함 됩니다.Usage of the resource is implicitly enclosed in a try statement that includes a finally clause. finally 절은 리소스를 삭제 합니다.This finally clause disposes of the resource. 리소스를 획득 하는 경우에 대 Dispose 한 호출이 수행 되지 않고 예외가 throw 되지 않습니다. nullIf a null resource is acquired, then no call to Dispose is made, and no exception is thrown. 리소스 형식이 dynamic 인 경우에는 사용 하기 전에 변환이 성공 하도록 하기 위해 인수를 획득 하는 동안 암시적 IDisposable 동적 변환 (암시적 동적변환)을 통해 동적으로 변환 됩니다. 방법을.If the resource is of type dynamic it is dynamically converted through an implicit dynamic conversion (Implicit dynamic conversions) to IDisposable during acquisition in order to ensure that the conversion is successful before the usage and disposal.

using 의 문A using statement of the form

using (ResourceType resource = expression) statement

가능한 세 가지 확장 중 하나에 해당 합니다.corresponds to one of three possible expansions. ResourceType null을 허용 하지 않는 값 형식인 경우 확장은When ResourceType is a non-nullable value type, the expansion is

{
    ResourceType resource = expression;
    try {
        statement;
    }
    finally {
        ((IDisposable)resource).Dispose();
    }
}

그렇지 않고가 ResourceType nullable 값 형식 이거나 이외의 dynamic참조 형식인 경우 확장은Otherwise, when ResourceType is a nullable value type or a reference type other than dynamic, the expansion is

{
    ResourceType resource = expression;
    try {
        statement;
    }
    finally {
        if (resource != null) ((IDisposable)resource).Dispose();
    }
}

그렇지 않고가 ResourceTypedynamic경우 확장은입니다.Otherwise, when ResourceType is dynamic, the expansion is

{
    ResourceType resource = expression;
    IDisposable d = (IDisposable)resource;
    try {
        statement;
    }
    finally {
        if (d != null) d.Dispose();
    }
}

두 확장 resource 중 하나에서 변수는 포함 된 문에서 읽기 전용 이며,이 변수는 d 포함 된 문에서 액세스할 수 없고에서 볼 수 없습니다.In either expansion, the resource variable is read-only in the embedded statement, and the d variable is inaccessible in, and invisible to, the embedded statement.

구현에 따라 지정 된 using 문을 다르게 구현할 수 있습니다. 예를 들어, 동작이 위의 확장과 일치 하는 경우 성능상의 이유로이를 다르게 구현할 수 있습니다.An implementation is permitted to implement a given using-statement differently, e.g. for performance reasons, as long as the behavior is consistent with the above expansion.

using 의 문A using statement of the form

using (expression) statement

에는 세 가지 확장을 사용할 수 있습니다.has the same three possible expansions. 이 경우 ResourceType 는 암시적으로 expression의 컴파일 타임 형식입니다 (있는 경우).In this case ResourceType is implicitly the compile-time type of the expression, if it has one. 그렇지 않으면 인터페이스 IDisposable 자체가 ResourceType로 사용 됩니다.Otherwise the interface IDisposable itself is used as the ResourceType. 변수 resource 는 포함 된 문에서 액세스할 수 없고 포함 된 문에서는 볼 수 없습니다.The resource variable is inaccessible in, and invisible to, the embedded statement.

Resource_acquisitionlocal_variable_declaration형식을 사용 하는 경우 지정 된 형식의 여러 리소스를 가져올 수 있습니다.When a resource_acquisition takes the form of a local_variable_declaration, it is possible to acquire multiple resources of a given type. using 의 문A using statement of the form

using (ResourceType r1 = e1, r2 = e2, ..., rN = eN) statement

는 중첩 using 된 문의 시퀀스와 정확히 동일 합니다.is precisely equivalent to a sequence of nested using statements:

using (ResourceType r1 = e1)
    using (ResourceType r2 = e2)
        ...
            using (ResourceType rN = eN)
                statement

아래 예제에서는 라는 log.txt 파일을 만들고 두 줄의 텍스트를 파일에 씁니다.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.

using System;
using System.IO;

class Test
{
    static void Main() {
        using (TextWriter w = File.CreateText("log.txt")) {
            w.WriteLine("This is line one");
            w.WriteLine("This is line two");
        }

        using (TextReader r = File.OpenText("log.txt")) {
            string s;
            while ((s = r.ReadLine()) != null) {
                Console.WriteLine(s);
            }

        }
    }
}

TextWriter IDisposable 클래스는 인터페이스를 구현 하므로이 예제에서는 문을 사용 using 하 여 쓰기 또는 읽기 작업을 수행 하는 동안 기본 파일이 제대로 닫혀 있는지 확인할 수 있습니다. TextReaderSince the TextWriter and TextReader classes implement the IDisposable interface, the example can use using statements to ensure that the underlying file is properly closed following the write or read operations.

Yield 문The yield statement

문은 반복기 블록 (블록)에서 반복기의 열거자 개체 (열거자 개체) 또는 열거 가능 개체 (열거 가능한개체)에 대 한 값을 생성 하거나 반복의 끝을 알리는 데 사용 됩니다. yieldThe yield statement is used in an iterator block (Blocks) to yield a value to the enumerator object (Enumerator objects) or enumerable object (Enumerable objects) of an iterator or to signal the end of the iteration.

yield_statement
    : 'yield' 'return' expression ';'
    | 'yield' 'break' ';'
    ;

yield는 예약어가 아닙니다. return 또는break 키워드 바로 앞에 사용 되는 경우에만 특별 한 의미가 있습니다.yield is not a reserved word; it has special meaning only when used immediately before a return or break keyword. 다른 컨텍스트에서는를 yield 식별자로 사용할 수 있습니다.In other contexts, yield can be used as an identifier.

다음에 설명 된 대로 yield 문이 나타날 수 있는 위치에 대 한 몇 가지 제한 사항이 있습니다.There are several restrictions on where a yield statement can appear, as described in the following.

  • Method_body, operator_body 또는 accessor_body 외부에 표시 되는 yield 문 (형식 중 하나)에 대 한 컴파일 타임 오류입니다.It is a compile-time error for a yield statement (of either form) to appear outside a method_body, operator_body or accessor_body
  • 익명 함수 내부에 표시 되는 yield 문 (형식 중 하나)에 대 한 컴파일 타임 오류입니다.It is a compile-time error for a yield statement (of either form) to appear inside an anonymous function.
  • 문의 yield finally 절 에표시되는문(형식중하나)에대한컴파일타임오류입니다.tryIt is a compile-time error for a yield statement (of either form) to appear in the finally clause of a try statement.
  • yield return 문이 try 모든 절catch 을 포함 하는 문의 어디에 나 표시 될 때 컴파일 시간 오류가 발생 합니다.It is a compile-time error for a yield return statement to appear anywhere in a try statement that contains any catch clauses.

다음 예에서는 yield 문의 유효 하 고 잘못 된 사용을 보여 줍니다.The following example shows some valid and invalid uses of yield statements.

delegate IEnumerable<int> D();

IEnumerator<int> GetEnumerator() {
    try {
        yield return 1;        // Ok
        yield break;           // Ok
    }
    finally {
        yield return 2;        // Error, yield in finally
        yield break;           // Error, yield in finally
    }

    try {
        yield return 3;        // Error, yield return in try...catch
        yield break;           // Ok
    }
    catch {
        yield return 4;        // Error, yield return in try...catch
        yield break;           // Ok
    }

    D d = delegate { 
        yield return 5;        // Error, yield in an anonymous function
    }; 
}

int MyMethod() {
    yield return 1;            // Error, wrong return type for an iterator block
}

yield return 문의 식 형식에서 반복기의 yield 형식 (yield 형식)에 대 한 암시적 변환 (암시적변환)이 존재 해야 합니다.An implicit conversion (Implicit conversions) must exist from the type of the expression in the yield return statement to the yield type (Yield type) of the iterator.

yield return 문은 다음과 같이 실행 됩니다.A yield return statement is executed as follows:

  • 문에 지정 된 식이 평가 되 고, 암시적으로 yield 형식으로 변환 되며, 열거자 개체의 Current 속성에 할당 됩니다.The expression given in the statement is evaluated, implicitly converted to the yield type, and assigned to the Current property of the enumerator object.
  • 반복기 블록의 실행이 일시 중지 되었습니다.Execution of the iterator block is suspended. 문이 하나 이상의 블록 내에 있는 경우에는 연결 된 finally 블록이 현재 실행 되지 않습니다. try yield returnIf the yield return statement is within one or more try blocks, the associated finally blocks are not executed at this time.
  • 열거자 MoveNext 개체의 메서드는 호출자에 true 게 반환 되어 열거자 개체가 다음 항목으로 이동 했음을 나타냅니다.The MoveNext method of the enumerator object returns true to its caller, indicating that the enumerator object successfully advanced to the next item.

열거자 개체의 MoveNext 메서드에 대 한 다음 호출에서는 마지막으로 일시 중단 된 반복기 블록의 실행을 다시 시작 합니다.The next call to the enumerator object's MoveNext method resumes execution of the iterator block from where it was last suspended.

yield break 문은 다음과 같이 실행 됩니다.A yield break statement is executed as follows:

  • try try 문이연결finally 된 블록을 포함 하는 하나 이상의 블록으로 묶여 있는 경우 처음에는 제어가 가장 안쪽의 문 블록으로 전송 됩니다. finally yield breakIf the yield break statement is enclosed by one or more try blocks with associated finally blocks, control is initially transferred to the finally block of the innermost try statement. 제어가 finally 블록의 끝점에 도달 하면 다음 바깥쪽 try 문의 finally 블록으로 제어가 전달 됩니다.When and if control reaches the end point of a finally block, control is transferred to the finally block of the next enclosing try statement. 이 프로세스는 모든 바깥쪽 finally try 문의 블록이 실행 될 때까지 반복 됩니다.This process is repeated until the finally blocks of all enclosing try statements have been executed.
  • 컨트롤은 반복기 블록의 호출자에 게 반환 됩니다.Control is returned to the caller of the iterator block. 이는 열거자 개체 MoveNext 의 메서드 Dispose 또는 메서드 중 하나입니다.This is either the MoveNext method or Dispose method of the enumerator object.

문은 다른 곳에서 제어를 전달 하기 때문에 yield break 문의 끝점에는 연결할 수 없습니다. yield breakBecause a yield break statement unconditionally transfers control elsewhere, the end point of a yield break statement is never reachable.