VariáveisVariables

As variáveis representam locais de armazenamento.Variables represent storage locations. Cada variável tem um tipo que determina quais valores podem ser armazenados na variável.Every variable has a type that determines what values can be stored in the variable. O c# é um idioma de tipo seguro, e o compilador C# garante que os valores armazenados em variáveis sejam sempre do tipo apropriado.C# is a type-safe language, and the C# compiler guarantees that values stored in variables are always of the appropriate type. O valor de uma variável pode ser alterado por atribuição ou pelo uso dos ++ operadores e -- .The value of a variable can be changed through assignment or through use of the ++ and -- operators.

Uma variável deve ser definitivamente atribuída (atribuição definitiva) antes que seu valor possa ser obtido.A variable must be definitely assigned (Definite assignment) before its value can be obtained.

Conforme descrito nas seções a seguir, as variáveis são *inicialmente atribuídas _ ou _ inicialmente não atribuídas *.As described in the following sections, variables are either initially assigned _ or _initially unassigned**. Uma variável atribuída inicialmente tem um valor inicial bem definido e é sempre considerada definitivamente atribuída.An initially assigned variable has a well-defined initial value and is always considered definitely assigned. Uma variável inicialmente não atribuída não tem valor inicial.An initially unassigned variable has no initial value. Para que uma variável inicialmente não atribuída seja considerada definitivamente atribuída em determinado local, uma atribuição para a variável deve ocorrer em cada caminho de execução possível, levando a esse local.For an initially unassigned variable to be considered definitely assigned at a certain location, an assignment to the variable must occur in every possible execution path leading to that location.

Categorias variáveisVariable categories

O C# define sete categorias de variáveis: variáveis estáticas, variáveis de instância, elementos de matriz, parâmetros de valor, parâmetros de referência, parâmetros de saída e variáveis locais.C# defines seven categories of variables: static variables, instance variables, array elements, value parameters, reference parameters, output parameters, and local variables. As seções a seguir descrevem cada uma dessas categorias.The sections that follow describe each of these categories.

No exemploIn the example

class A
{
    public static int x;
    int y;

    void F(int[] v, int a, ref int b, out int c) {
        int i = 1;
        c = a + b++;
    }
}

x é uma variável estática, y é uma variável de instância, v[0] é um elemento de matriz, a é um parâmetro de valor, é um parâmetro de b referência, c é um parâmetro de saída e i é uma variável local.x is a static variable, y is an instance variable, v[0] is an array element, a is a value parameter, b is a reference parameter, c is an output parameter, and i is a local variable.

Variáveis estáticasStatic variables

Um campo declarado com o static modificador é chamado de uma variável estática.A field declared with the static modifier is called a static variable. Uma variável estática entra em existência antes da execução do construtor estático (construtores estáticos) para seu tipo recipiente e deixa de existir quando o domínio do aplicativo associado deixar de existir.A static variable comes into existence before execution of the static constructor (Static constructors) for its containing type, and ceases to exist when the associated application domain ceases to exist.

O valor inicial de uma variável estática é o valor padrão (valores padrão) do tipo da variável.The initial value of a static variable is the default value (Default values) of the variable's type.

Para fins de verificação de atribuição definitiva, uma variável estática é considerada inicialmente atribuída.For purposes of definite assignment checking, a static variable is considered initially assigned.

Variáveis de instânciaInstance variables

Um campo declarado sem o static modificador é chamado de variável de instância.A field declared without the static modifier is called an instance variable.

Variáveis de instância em classesInstance variables in classes

Uma variável de instância de uma classe entra em existência quando uma nova instância dessa classe é criada e deixa de existir quando não há nenhuma referência a essa instância e o destruidor da instância (se houver) tiver sido executado.An instance variable of a class comes into existence when a new instance of that class is created, and ceases to exist when there are no references to that instance and the instance's destructor (if any) has executed.

O valor inicial de uma variável de instância de uma classe é o valor padrão (valores padrão) do tipo da variável.The initial value of an instance variable of a class is the default value (Default values) of the variable's type.

Para fins de verificação de atribuição definitiva, uma variável de instância de uma classe é considerada inicialmente atribuída.For the purpose of definite assignment checking, an instance variable of a class is considered initially assigned.

Variáveis de instância em structsInstance variables in structs

Uma variável de instância de uma struct tem exatamente o mesmo tempo de vida que a variável de struct à qual ela pertence.An instance variable of a struct has exactly the same lifetime as the struct variable to which it belongs. Em outras palavras, quando uma variável de um tipo struct entra em existência ou deixa de existir, também as variáveis de instância do struct.In other words, when a variable of a struct type comes into existence or ceases to exist, so too do the instance variables of the struct.

O estado de atribuição inicial de uma variável de instância de uma struct é o mesmo da variável struct que a contém.The initial assignment state of an instance variable of a struct is the same as that of the containing struct variable. Em outras palavras, quando uma variável de struct é considerada inicialmente atribuída, também são suas variáveis de instância e, quando uma variável de struct é considerada inicialmente não atribuída, suas variáveis de instância são, da mesma forma, não atribuídas.In other words, when a struct variable is considered initially assigned, so too are its instance variables, and when a struct variable is considered initially unassigned, its instance variables are likewise unassigned.

Elementos da matrizArray elements

Os elementos de uma matriz entram em existência quando uma instância de matriz é criada e deixa de existir quando não há nenhuma referência a essa instância de matriz.The elements of an array come into existence when an array instance is created, and cease to exist when there are no references to that array instance.

O valor inicial de cada um dos elementos de uma matriz é o valor padrão (valores padrão) do tipo dos elementos da matriz.The initial value of each of the elements of an array is the default value (Default values) of the type of the array elements.

Para fins de verificação de atribuição definitiva, um elemento de matriz é considerado inicialmente atribuído.For the purpose of definite assignment checking, an array element is considered initially assigned.

Parâmetros de valorValue parameters

Um parâmetro declarado sem um ref out modificador ou é um parâmetro de valor.A parameter declared without a ref or out modifier is a value parameter.

Um parâmetro de valor entra em existência na invocação do membro da função (método, Construtor de instância, acessador ou operador) ou função anônima à qual o parâmetro pertence, e é inicializado com o valor do argumento fornecido na invocação.A value parameter comes into existence upon invocation of the function member (method, instance constructor, accessor, or operator) or anonymous function to which the parameter belongs, and is initialized with the value of the argument given in the invocation. Um parâmetro de valor normalmente deixa de existir no retorno do membro da função ou da função anônima.A value parameter normally ceases to exist upon return of the function member or anonymous function. No entanto, se o parâmetro de valor for capturado por uma função anônima (expressões de função anônima), seu tempo de vida se estenderá pelo menos até que a árvore de delegação ou expressão criada a partir dessa função anônima esteja qualificada para a coleta de lixo.However, if the value parameter is captured by an anonymous function (Anonymous function expressions), its life time extends at least until the delegate or expression tree created from that anonymous function is eligible for garbage collection.

Para fins de verificação de atribuição definitiva, um parâmetro value é considerado inicialmente atribuído.For the purpose of definite assignment checking, a value parameter is considered initially assigned.

Parâmetros de referênciaReference parameters

Um parâmetro declarado com um ref modificador é um parâmetro de referência.A parameter declared with a ref modifier is a reference parameter.

Um parâmetro de referência não cria um novo local de armazenamento.A reference parameter does not create a new storage location. Em vez disso, um parâmetro de referência representa o mesmo local de armazenamento que a variável fornecida como o argumento no membro da função ou invocação de função anônima.Instead, a reference parameter represents the same storage location as the variable given as the argument in the function member or anonymous function invocation. Assim, o valor de um parâmetro de referência é sempre o mesmo que a variável subjacente.Thus, the value of a reference parameter is always the same as the underlying variable.

As regras de atribuição definidas a seguir se aplicam aos parâmetros de referência.The following definite assignment rules apply to reference parameters. Observe as diferentes regras para os parâmetros de saída descritos em parâmetros de saída.Note the different rules for output parameters described in Output parameters.

  • Uma variável deve ser definitivamente atribuída (atribuiçãodefinida) antes de poder ser passada como um parâmetro de referência em um membro de função ou uma invocação de delegado.A variable must be definitely assigned (Definite assignment) before it can be passed as a reference parameter in a function member or delegate invocation.
  • Dentro de um membro de função ou função anônima, um parâmetro de referência é considerado inicialmente atribuído.Within a function member or anonymous function, a reference parameter is considered initially assigned.

Dentro de um método de instância ou acessador de instância de um tipo struct, a this palavra-chave se comporta exatamente como um parâmetro de referência do tipo struct (esse acesso).Within an instance method or instance accessor of a struct type, the this keyword behaves exactly as a reference parameter of the struct type (This access).

Parâmetros de saídaOutput parameters

Um parâmetro declarado com um out modificador é um parâmetro de saída.A parameter declared with an out modifier is an output parameter.

Um parâmetro de saída não cria um novo local de armazenamento.An output parameter does not create a new storage location. Em vez disso, um parâmetro de saída representa o mesmo local de armazenamento que a variável fornecida como o argumento no membro da função ou na invocação de delegado.Instead, an output parameter represents the same storage location as the variable given as the argument in the function member or delegate invocation. Assim, o valor de um parâmetro de saída é sempre o mesmo que a variável subjacente.Thus, the value of an output parameter is always the same as the underlying variable.

As regras de atribuição definidas a seguir se aplicam aos parâmetros de saída.The following definite assignment rules apply to output parameters. Observe as diferentes regras para parâmetros de referência descritos em parâmetros de referência.Note the different rules for reference parameters described in Reference parameters.

  • Uma variável não precisa ser definitivamente atribuída antes que possa ser passada como um parâmetro de saída em um membro de função ou invocação de delegado.A variable need not be definitely assigned before it can be passed as an output parameter in a function member or delegate invocation.
  • Após a conclusão normal de um membro de função ou de uma invocação de delegado, cada variável passada como um parâmetro de saída é considerada atribuída nesse caminho de execução.Following the normal completion of a function member or delegate invocation, each variable that was passed as an output parameter is considered assigned in that execution path.
  • Dentro de um membro de função ou função anônima, um parâmetro de saída é considerado inicialmente não atribuído.Within a function member or anonymous function, an output parameter is considered initially unassigned.
  • Cada parâmetro de saída de um membro de função ou função anônima deve ser definitivamente atribuído (atribuição definitiva) antes que o membro de função ou função anônima retorne normalmente.Every output parameter of a function member or anonymous function must be definitely assigned (Definite assignment) before the function member or anonymous function returns normally.

Dentro de um construtor de instância de um tipo struct, a this palavra-chave se comporta exatamente como um parâmetro de saída do tipo struct (esse acesso).Within an instance constructor of a struct type, the this keyword behaves exactly as an output parameter of the struct type (This access).

Variáveis locaisLocal variables

Uma *variável local _ é declarada por um _local_variable_declaration *, que pode ocorrer em um bloco, um for_statement, um switch_statement ou um using_statement; ou por um foreach_statement ou um specific_catch_clause para um try_statement.A local variable _ is declared by a _local_variable_declaration, which may occur in a block, a for_statement, a switch_statement or a using_statement; or by a foreach_statement or a specific_catch_clause for a try_statement.

O tempo de vida de uma variável local é a parte da execução do programa durante o qual o armazenamento tem a garantia de ser reservado para ele.The lifetime of a local variable is the portion of program execution during which storage is guaranteed to be reserved for it. Esse tempo de vida estende pelo menos da entrada para o bloco, for_statement, switch_statement, using_statement, foreach_statement ou specific_catch_clause com o qual está associado, até a execução desse bloco, for_statement, switch_statement, using_statement, foreach_statement ou specific_catch_clause termina de qualquer forma. This lifetime extends at least from entry into the block, for_statement, switch_statement, using_statement, foreach_statement, or specific_catch_clause with which it is associated, until execution of that block, for_statement, switch_statement, using_statement, foreach_statement, or specific_catch_clause ends in any way. (Inserir um bloco anexado ou chamar um método suspende, mas não termina, execução do bloco atual, for_statement, switch_statement, using_statement, foreach_statement ou specific_catch_clause.) Se a variável local for capturada por uma função anônima (variáveis externas capturadas), seu tempo de vida se estenderá pelo menos até que a árvore de delegação ou de expressão criada a partir da função anônima, juntamente com quaisquer outros objetos que venham a fazer referência à variável capturada, sejam elegíveis para coleta de lixo.(Entering an enclosed block or calling a method suspends, but does not end, execution of the current block, for_statement, switch_statement, using_statement, foreach_statement, or specific_catch_clause.) If the local variable is captured by an anonymous function (Captured outer variables), its lifetime extends at least until the delegate or expression tree created from the anonymous function, along with any other objects that come to reference the captured variable, are eligible for garbage collection.

Se o bloco pai, for_statement, switch_statement, using_statement, foreach_statement ou specific_catch_clause for inserido recursivamente, uma nova instância da variável local será criada a cada vez, e seu local_variable_initializer, se houver, será avaliado a cada vez.If the parent block, for_statement, switch_statement, using_statement, foreach_statement, or specific_catch_clause is entered recursively, a new instance of the local variable is created each time, and its local_variable_initializer, if any, is evaluated each time.

Uma variável local introduzida por um local_variable_declaration não é inicializada automaticamente e, portanto, não tem valor padrão.A local variable introduced by a local_variable_declaration is not automatically initialized and thus has no default value. Para fins de verificação de atribuição definitiva, uma variável local introduzida por um local_variable_declaration é considerada inicialmente não atribuída.For the purpose of definite assignment checking, a local variable introduced by a local_variable_declaration is considered initially unassigned. Um local_variable_declaration pode incluir um local_variable_initializer, caso em que a variável é considerada definitivamente atribuída somente após a expressão de inicialização (instruções de declaração).A local_variable_declaration may include a local_variable_initializer, in which case the variable is considered definitely assigned only after the initializing expression (Declaration statements).

Dentro do escopo de uma variável local introduzida por um local_variable_declaration, é um erro de tempo de compilação para se referir a essa variável local em uma posição textual que precede sua local_variable_declarator.Within the scope of a local variable introduced by a local_variable_declaration, it is a compile-time error to refer to that local variable in a textual position that precedes its local_variable_declarator. Se a declaração de variável local for implícita (declarações de variável local), também será um erro para se referir à variável dentro de seu local_variable_declarator.If the local variable declaration is implicit (Local variable declarations), it is also an error to refer to the variable within its local_variable_declarator.

Uma variável local introduzida por um foreach_statement ou um specific_catch_clause é considerada definitivamente atribuída em seu escopo inteiro.A local variable introduced by a foreach_statement or a specific_catch_clause is considered definitely assigned in its entire scope.

O tempo de vida real de uma variável local é dependente de implementação.The actual lifetime of a local variable is implementation-dependent. Por exemplo, um compilador pode determinar estaticamente que uma variável local em um bloco seja usada apenas para uma pequena parte desse bloco.For example, a compiler might statically determine that a local variable in a block is only used for a small portion of that block. Usando essa análise, o compilador pode gerar código que resulta no armazenamento da variável que tem um tempo de vida menor do que o bloco que a contém.Using this analysis, the compiler could generate code that results in the variable's storage having a shorter lifetime than its containing block.

O armazenamento referido por uma variável de referência local é recuperado independentemente do tempo de vida dessa variável de referência local (Gerenciamento de memória automático).The storage referred to by a local reference variable is reclaimed independently of the lifetime of that local reference variable (Automatic memory management).

Valores padrãoDefault values

As seguintes categorias de variáveis são inicializadas automaticamente para seus valores padrão:The following categories of variables are automatically initialized to their default values:

  • Variáveis estáticas.Static variables.
  • Variáveis de instância de instâncias de classe.Instance variables of class instances.
  • Elementos da matriz.Array elements.

O valor padrão de uma variável depende do tipo da variável e é determinado da seguinte maneira:The default value of a variable depends on the type of the variable and is determined as follows:

  • Para uma variável de um value_type, o valor padrão é o mesmo que o valor calculado pelo construtor padrão do Value_type(construtores padrão).For a variable of a value_type, the default value is the same as the value computed by the value_type's default constructor (Default constructors).
  • Para uma variável de um reference_type, o valor padrão é null .For a variable of a reference_type, the default value is null.

A inicialização para valores padrão normalmente é feita por ter o Gerenciador de memória ou o coletor de lixo inicializar a memória para todos os bits-zero antes que ele seja alocado para uso.Initialization to default values is typically done by having the memory manager or garbage collector initialize memory to all-bits-zero before it is allocated for use. Por esse motivo, é conveniente usar todos os bits-zero para representar a referência nula.For this reason, it is convenient to use all-bits-zero to represent the null reference.

Atribuição definidaDefinite assignment

Em um determinado local no código executável de um membro de função, uma variável é considerada definitivamente atribuída se o compilador puder provar, por uma análise de fluxo estático específica (regras exatas para determinar a atribuição definitiva), se a variável tiver sido inicializada automaticamente ou se tiver sido o destino de pelo menos uma atribuição.At a given location in the executable code of a function member, a variable is said to be definitely assigned if the compiler can prove, by a particular static flow analysis (Precise rules for determining definite assignment), that the variable has been automatically initialized or has been the target of at least one assignment. Indicado informalmente, as regras de atribuição definitiva são:Informally stated, the rules of definite assignment are:

A especificação formal subjacente às regras informais acima é descrita em variáveis atribuídas inicialmente, variáveis inicialmente não atribuídase regras precisas para determinar a atribuição definitiva.The formal specification underlying the above informal rules is described in Initially assigned variables, Initially unassigned variables, and Precise rules for determining definite assignment.

Os Estados de atribuição definitivos de variáveis de instância de uma variável struct_type são acompanhados individualmente, bem como coletivamente.The definite assignment states of instance variables of a struct_type variable are tracked individually as well as collectively. Além das regras acima, as regras a seguir se aplicam a struct_type variáveis e suas variáveis de instância:In addition to the rules above, the following rules apply to struct_type variables and their instance variables:

  • Uma variável de instância é considerada definitivamente atribuída se a variável que a contém struct_type é considerada definitivamente atribuída.An instance variable is considered definitely assigned if its containing struct_type variable is considered definitely assigned.
  • Uma variável struct_type será considerada definitivamente atribuída se cada uma de suas variáveis de instância for considerada definitivamente atribuída.A struct_type variable is considered definitely assigned if each of its instance variables is considered definitely assigned.

A atribuição definitiva é um requisito nos seguintes contextos:Definite assignment is a requirement in the following contexts:

  • Uma variável deve ser atribuída definitivamente em cada local em que seu valor é obtido.A variable must be definitely assigned at each location where its value is obtained. Isso garante que os valores indefinidos nunca ocorram.This ensures that undefined values never occur. A ocorrência de uma variável em uma expressão é considerada para obter o valor da variável, exceto quandoThe occurrence of a variable in an expression is considered to obtain the value of the variable, except when
    • a variável é o operando esquerdo de uma atribuição simples,the variable is the left operand of a simple assignment,
    • a variável é passada como um parâmetro de saída outhe variable is passed as an output parameter, or
    • a variável é uma struct_type variável e ocorre como o operando esquerdo de um acesso de membro.the variable is a struct_type variable and occurs as the left operand of a member access.
  • Uma variável deve ser definitivamente atribuída em cada local em que é passada como um parâmetro de referência.A variable must be definitely assigned at each location where it is passed as a reference parameter. Isso garante que o membro da função que está sendo invocado pode considerar o parâmetro de referência inicialmente atribuído.This ensures that the function member being invoked can consider the reference parameter initially assigned.
  • Todos os parâmetros de saída de um membro de função devem ser definitivamente atribuídos em cada local em que o membro da função retorna (por meio de uma return instrução ou por meio da execução que chega ao final do corpo do membro da função).All output parameters of a function member must be definitely assigned at each location where the function member returns (through a return statement or through execution reaching the end of the function member body). Isso garante que os membros da função não retornem valores indefinidos nos parâmetros de saída, permitindo que o compilador considere uma invocação de membro de função que usa uma variável como um parâmetro de saída equivalente a uma atribuição para a variável.This ensures that function members do not return undefined values in output parameters, thus enabling the compiler to consider a function member invocation that takes a variable as an output parameter equivalent to an assignment to the variable.
  • A this variável de um construtor de instância de struct_type deve ser definitivamente atribuída em cada local em que o construtor de instância retorna.The this variable of a struct_type instance constructor must be definitely assigned at each location where that instance constructor returns.

Variáveis inicialmente atribuídasInitially assigned variables

As seguintes categorias de variáveis são classificadas como atribuídas inicialmente:The following categories of variables are classified as initially assigned:

  • Variáveis estáticas.Static variables.
  • Variáveis de instância de instâncias de classe.Instance variables of class instances.
  • Variáveis de instância de variáveis de struct inicialmente atribuídas.Instance variables of initially assigned struct variables.
  • Elementos da matriz.Array elements.
  • Parâmetros de valor.Value parameters.
  • Parâmetros de referência.Reference parameters.
  • Variáveis declaradas em uma catch cláusula ou em uma foreach instrução.Variables declared in a catch clause or a foreach statement.

Variáveis inicialmente não atribuídasInitially unassigned variables

As seguintes categorias de variáveis são classificadas como inicialmente não atribuídas:The following categories of variables are classified as initially unassigned:

  • Variáveis de instância de variáveis struct inicialmente não atribuídas.Instance variables of initially unassigned struct variables.
  • Parâmetros de saída, incluindo a this variável de construtores de instância de struct.Output parameters, including the this variable of struct instance constructors.
  • Variáveis locais, exceto aquelas declaradas em uma catch cláusula ou uma foreach instrução.Local variables, except those declared in a catch clause or a foreach statement.

Regras precisas para determinar a atribuição definitivaPrecise rules for determining definite assignment

Para determinar se cada variável usada é definitivamente atribuída, o compilador deve usar um processo que seja equivalente ao descrito nesta seção.In order to determine that each used variable is definitely assigned, the compiler must use a process that is equivalent to the one described in this section.

O compilador processa o corpo de cada membro de função que tem uma ou mais variáveis não atribuídas inicialmente.The compiler processes the body of each function member that has one or more initially unassigned variables. Para cada variável v inicialmente não atribuída, o compilador determina um *estado de atribuição definitivo _ para _v * em cada um dos seguintes pontos no membro da função:For each initially unassigned variable v, the compiler determines a definite assignment state _ for _v at each of the following points in the function member:

  • No início de cada instruçãoAt the beginning of each statement
  • No ponto de extremidade (pontos de extremidade e acessibilidade) de cada instruçãoAt the end point (End points and reachability) of each statement
  • Em cada arco que transfere o controle para outra instrução ou para o ponto final de uma instruçãoOn each arc which transfers control to another statement or to the end point of a statement
  • No início de cada expressãoAt the beginning of each expression
  • No final de cada expressãoAt the end of each expression

O estado de atribuição definitivo de v pode ser:The definite assignment state of v can be either:

  • Definitivamente atribuído.Definitely assigned. Isso indica que em todos os fluxos de controle possíveis para esse ponto, v recebeu um valor.This indicates that on all possible control flows to this point, v has been assigned a value.
  • Não é definitivamente atribuído.Not definitely assigned. Para o estado de uma variável no final de uma expressão do tipo bool , o estado de uma variável que não está definitivamente atribuída pode (mas não necessariamente) se enquadrar em um dos seguintes subcaminhos:For the state of a variable at the end of an expression of type bool, the state of a variable that isn't definitely assigned may (but doesn't necessarily) fall into one of the following sub-states:
    • Atribuído definitivamente após a expressão true.Definitely assigned after true expression. Esse estado indica que v é definitivamente atribuído se a expressão booliana for avaliada como true, mas não será necessariamente atribuído se a expressão booliana for avaliada como false.This state indicates that v is definitely assigned if the boolean expression evaluated as true, but is not necessarily assigned if the boolean expression evaluated as false.
    • Definitivamente atribuída após expressão false.Definitely assigned after false expression. Esse estado indica que v é definitivamente atribuído se a expressão booliana for avaliada como false, mas não será necessariamente atribuída se a expressão booliana for avaliada como true.This state indicates that v is definitely assigned if the boolean expression evaluated as false, but is not necessarily assigned if the boolean expression evaluated as true.

As regras a seguir regem como o estado de uma variável v é determinado em cada local.The following rules govern how the state of a variable v is determined at each location.

Regras gerais para instruçõesGeneral rules for statements

  • v não é definitivamente atribuído no início de um corpo de membro de função.v is not definitely assigned at the beginning of a function member body.
  • o v é definitivamente atribuído no início de qualquer instrução inacessível.v is definitely assigned at the beginning of any unreachable statement.
  • O estado de atribuição definitivo de v no início de qualquer outra instrução é determinado verificando o estado de atribuição definido de v em todas as transferências de fluxo de controle direcionadas ao início dessa instrução.The definite assignment state of v at the beginning of any other statement is determined by checking the definite assignment state of v on all control flow transfers that target the beginning of that statement. Se (e somente se) v for definitivamente atribuído a todas as transferências de fluxo de controle, v será definitivamente atribuído no início da instrução.If (and only if) v is definitely assigned on all such control flow transfers, then v is definitely assigned at the beginning of the statement. O conjunto de possíveis transferências de fluxo de controle é determinado da mesma forma que para verificar a acessibilidade da instrução (pontos de extremidade e acessibilidade).The set of possible control flow transfers is determined in the same way as for checking statement reachability (End points and reachability).
  • O estado de atribuição definitivo de v no ponto de extremidade de uma instrução Block,,,,,,,,, checked unchecked if while do for foreach lock using ou switch é determinado verificando o estado de atribuição definido de v em todas as transferências de fluxo de controle direcionadas ao ponto de extremidade dessa instrução.The definite assignment state of v at the end point of a block, checked, unchecked, if, while, do, for, foreach, lock, using, or switch statement is determined by checking the definite assignment state of v on all control flow transfers that target the end point of that statement. Se v for definitivamente atribuído a todas essas transferências de fluxo de controle, então v será definitivamente atribuído no ponto de extremidade da instrução.If v is definitely assigned on all such control flow transfers, then v is definitely assigned at the end point of the statement. , v não é definitivamente atribuído no ponto de extremidade da instrução.Otherwise; v is not definitely assigned at the end point of the statement. O conjunto de possíveis transferências de fluxo de controle é determinado da mesma forma que para verificar a acessibilidade da instrução (pontos de extremidade e acessibilidade).The set of possible control flow transfers is determined in the same way as for checking statement reachability (End points and reachability).

Instruções Block, instruções marcadas e desmarcadasBlock statements, checked, and unchecked statements

O estado de atribuição definitivo de v na transferência de controle para a primeira instrução da lista de instruções no bloco (ou até o ponto final do bloco, se a lista de instruções estiver vazia) é igual à instrução de atribuição definitiva de v antes da checked instrução ou do bloco unchecked .The definite assignment state of v on the control transfer to the first statement of the statement list in the block (or to the end point of the block, if the statement list is empty) is the same as the definite assignment statement of v before the block, checked, or unchecked statement.

Instruções de expressãoExpression statements

Para uma instrução de expressão stmt que consiste na expressão Expression:For an expression statement stmt that consists of the expression expr:

  • v tem o mesmo estado de atribuição definitivo no início de expr como no início de stmt.v has the same definite assignment state at the beginning of expr as at the beginning of stmt.
  • Se for definitivamente atribuído ao final de expr, ele será definitivamente atribuído no ponto final de stmt; , Ele não é definitivamente atribuído no ponto de extremidade de stmt.If v if definitely assigned at the end of expr, it is definitely assigned at the end point of stmt; otherwise; it is not definitely assigned at the end point of stmt.

Instruções de declaraçãoDeclaration statements

  • Se stmt for uma instrução de declaração sem inicializadores, v terá o mesmo estado de atribuição definitivo no ponto de extremidade de stmt como no início de stmt.If stmt is a declaration statement without initializers, then v has the same definite assignment state at the end point of stmt as at the beginning of stmt.
  • Se stmt for uma instrução de declaração com inicializadores, o estado de atribuição definitivo para v será determinado como se stmt fosse uma lista de instruções, com uma instrução de atribuição para cada declaração com um inicializador (na ordem de declaração).If stmt is a declaration statement with initializers, then the definite assignment state for v is determined as if stmt were a statement list, with one assignment statement for each declaration with an initializer (in the order of declaration).

Instruções IfIf statements

Para uma if instrução stmt do formulário:For an if statement stmt of the form:

if ( expr ) then_stmt else else_stmt
  • v tem o mesmo estado de atribuição definitivo no início de expr como no início de stmt.v has the same definite assignment state at the beginning of expr as at the beginning of stmt.
  • Se v for definitivamente atribuído ao final de expr, ele será definitivamente atribuído na transferência de fluxo de controle para then_stmt e para else_stmt ou para o ponto de extremidade de stmt se não houver nenhuma cláusula else.If v is definitely assigned at the end of expr, then it is definitely assigned on the control flow transfer to then_stmt and to either else_stmt or to the end-point of stmt if there is no else clause.
  • Se v tiver o estado "definitivamente atribuído após expressão verdadeira" no final de expr, ele será definitivamente atribuído na transferência de fluxo de controle para then_stmt e não definitivamente atribuído na transferência de fluxo de controle para else_stmt ou para o ponto de extremidade de stmt se não houver nenhuma cláusula else.If v has the state "definitely assigned after true expression" at the end of expr, then it is definitely assigned on the control flow transfer to then_stmt, and not definitely assigned on the control flow transfer to either else_stmt or to the end-point of stmt if there is no else clause.
  • Se v tiver o estado "definitivamente atribuído após expressão falsa" no final de expr, ele será definitivamente atribuído na transferência de fluxo de controle para else_stmt e não definitivamente atribuído na transferência de fluxo de controle para then_stmt.If v has the state "definitely assigned after false expression" at the end of expr, then it is definitely assigned on the control flow transfer to else_stmt, and not definitely assigned on the control flow transfer to then_stmt. Ele é definitivamente atribuído no ponto de extremidade de stmt se e somente se ele for definitivamente atribuído no ponto de extremidade de then_stmt.It is definitely assigned at the end-point of stmt if and only if it is definitely assigned at the end-point of then_stmt.
  • Caso contrário, v é considerado não definitivamente atribuído na transferência de fluxo de controle para o then_stmt ou else_stmt, ou para o ponto de extremidade de stmt se não houver nenhuma cláusula else.Otherwise, v is considered not definitely assigned on the control flow transfer to either the then_stmt or else_stmt, or to the end-point of stmt if there is no else clause.

Instruções switchSwitch statements

Em uma switch instrução stmt com uma expr de expressão de controle:In a switch statement stmt with a controlling expression expr:

  • O estado de atribuição definitivo de v no início de expr é o mesmo que o estado de v no início de stmt.The definite assignment state of v at the beginning of expr is the same as the state of v at the beginning of stmt.
  • O estado de atribuição definitivo de v na transferência de fluxo de controle para uma lista de instrução de bloqueio de switch acessível é igual ao estado de atribuição definido de v no final de expr.The definite assignment state of v on the control flow transfer to a reachable switch block statement list is the same as the definite assignment state of v at the end of expr.

Instruções whileWhile statements

Para uma while instrução stmt do formulário:For a while statement stmt of the form:

while ( expr ) while_body
  • v tem o mesmo estado de atribuição definitivo no início de expr como no início de stmt.v has the same definite assignment state at the beginning of expr as at the beginning of stmt.
  • Se v for definitivamente atribuído ao final de expr, ele será definitivamente atribuído na transferência de fluxo de controle para while_body e para o ponto final de stmt.If v is definitely assigned at the end of expr, then it is definitely assigned on the control flow transfer to while_body and to the end point of stmt.
  • Se v tiver o estado "definitivamente atribuído após expressão verdadeira" no final de expr, ele será definitivamente atribuído na transferência de fluxo de controle para while_body, mas não definitivamente atribuído no ponto de extremidade de stmt.If v has the state "definitely assigned after true expression" at the end of expr, then it is definitely assigned on the control flow transfer to while_body, but not definitely assigned at the end-point of stmt.
  • Se v tiver o estado "definitivamente atribuído após expressão falsa" no final de expr, ele será definitivamente atribuído na transferência de fluxo de controle para o ponto final de stmt, mas não definitivamente atribuído na transferência de fluxo de controle para while_body.If v has the state "definitely assigned after false expression" at the end of expr, then it is definitely assigned on the control flow transfer to the end point of stmt, but not definitely assigned on the control flow transfer to while_body.

Instruções doDo statements

Para uma do instrução stmt do formulário:For a do statement stmt of the form:

do do_body while ( expr ) ;
  • v tem o mesmo estado de atribuição definitivo na transferência de fluxo de controle do início de stmt para do_body como no início de stmt.v has the same definite assignment state on the control flow transfer from the beginning of stmt to do_body as at the beginning of stmt.
  • v tem o mesmo estado de atribuição definitivo no início de expr como no ponto de extremidade de do_body.v has the same definite assignment state at the beginning of expr as at the end point of do_body.
  • Se v for definitivamente atribuído ao final de expr, ele será definitivamente atribuído na transferência de fluxo de controle para o ponto final de stmt.If v is definitely assigned at the end of expr, then it is definitely assigned on the control flow transfer to the end point of stmt.
  • Se v tiver o estado "definitivamente atribuído após expressão falsa" no final de expr, ele será definitivamente atribuído na transferência de fluxo de controle para o ponto final de stmt.If v has the state "definitely assigned after false expression" at the end of expr, then it is definitely assigned on the control flow transfer to the end point of stmt.

Instruções forFor statements

Verificação de atribuição definitiva para uma for instrução do formulário:Definite assignment checking for a for statement of the form:

for ( for_initializer ; for_condition ; for_iterator ) embedded_statement

é feito como se a instrução fosse gravada:is done as if the statement were written:

{
    for_initializer ;
    while ( for_condition ) {
        embedded_statement ;
        for_iterator ;
    }
}

Se o for_condition for omitido da for instrução, a avaliação da atribuição definitiva continuará como se for_condition substituídos true por na expansão acima.If the for_condition is omitted from the for statement, then evaluation of definite assignment proceeds as if for_condition were replaced with true in the above expansion.

Instruções Break, continue e gotoBreak, continue, and goto statements

O estado de atribuição definitivo de v na transferência de fluxo de controle causada por uma break continue instrução, ou goto é igual ao estado de atribuição definido de v no início da instrução.The definite assignment state of v on the control flow transfer caused by a break, continue, or goto statement is the same as the definite assignment state of v at the beginning of the statement.

Instruções throwThrow statements

Para uma instrução stmt do formulárioFor a statement stmt of the form

throw expr ;

O estado de atribuição definitivo de v no início de expr é o mesmo que o estado de atribuição definido de v no início de stmt.The definite assignment state of v at the beginning of expr is the same as the definite assignment state of v at the beginning of stmt.

Instruções de retornoReturn statements

Para uma instrução stmt do formulárioFor a statement stmt of the form

return expr ;
  • O estado de atribuição definitivo de v no início de expr é o mesmo que o estado de atribuição definido de v no início de stmt.The definite assignment state of v at the beginning of expr is the same as the definite assignment state of v at the beginning of stmt.
  • Se v for um parâmetro de saída, ele deverá ser definitivamente atribuído a:If v is an output parameter, then it must be definitely assigned either:
    • Depois de exprafter expr
    • ou no final do finally bloco de um try - finally ou try - catch - finally que inclui a return instrução.or at the end of the finally block of a try-finally or try-catch-finally that encloses the return statement.

Para uma instrução stmt do formulário:For a statement stmt of the form:

return ;
  • Se v for um parâmetro de saída, ele deverá ser definitivamente atribuído a:If v is an output parameter, then it must be definitely assigned either:
    • antes de stmtbefore stmt
    • ou no final do finally bloco de um try - finally ou try - catch - finally que inclui a return instrução.or at the end of the finally block of a try-finally or try-catch-finally that encloses the return statement.

Instruções Try-CatchTry-catch statements

Para uma instrução stmt do formulário:For a statement stmt of the form:

try try_block
catch(...) catch_block_1
...
catch(...) catch_block_n
  • O estado de atribuição definitivo de v no início de try_block é o mesmo que o estado de atribuição definido de v no início de stmt.The definite assignment state of v at the beginning of try_block is the same as the definite assignment state of v at the beginning of stmt.
  • O estado de atribuição definitivo de v no início de catch_block_i (para qualquer i) é igual ao estado de atribuição definitivo de v no início de stmt.The definite assignment state of v at the beginning of catch_block_i (for any i) is the same as the definite assignment state of v at the beginning of stmt.
  • O estado de atribuição definitivo de v no ponto de extremidade de stmt é definitivamente atribuído se (e somente se) v for definitivamente atribuído no ponto de extremidade de try_block e a cada catch_block_i (para cada i de 1 a n).The definite assignment state of v at the end-point of stmt is definitely assigned if (and only if) v is definitely assigned at the end-point of try_block and every catch_block_i (for every i from 1 to n).

Instruções try – finallyTry-finally statements

Para uma try instrução stmt do formulário:For a try statement stmt of the form:

try try_block finally finally_block
  • O estado de atribuição definitivo de v no início de try_block é o mesmo que o estado de atribuição definido de v no início de stmt.The definite assignment state of v at the beginning of try_block is the same as the definite assignment state of v at the beginning of stmt.
  • O estado de atribuição definitivo de v no início de finally_block é o mesmo que o estado de atribuição definido de v no início de stmt.The definite assignment state of v at the beginning of finally_block is the same as the definite assignment state of v at the beginning of stmt.
  • O estado de atribuição definitivo de v no ponto de extremidade de stmt é definitivamente atribuído se (e somente se) pelo menos uma das seguintes opções for verdadeira:The definite assignment state of v at the end-point of stmt is definitely assigned if (and only if) at least one of the following is true:
    • o v é definitivamente atribuído no ponto de extremidade de try_blockv is definitely assigned at the end-point of try_block
    • o v é definitivamente atribuído no ponto de extremidade de finally_blockv is definitely assigned at the end-point of finally_block

Se for feita uma transferência de fluxo de controle (por exemplo, uma goto instrução) que começa dentro de try_block e termina fora do try_block, então v também será considerado definitivamente atribuído na transferência do fluxo de controle se v for definitivamente atribuído no ponto de extremidade de finally_block.If a control flow transfer (for example, a goto statement) is made that begins within try_block, and ends outside of try_block, then v is also considered definitely assigned on that control flow transfer if v is definitely assigned at the end-point of finally_block. (Isso não é apenas se — se v for definitivamente atribuído por outro motivo nessa transferência de fluxo de controle, ele ainda será considerado definitivamente atribuído.)(This is not an only if—if v is definitely assigned for another reason on this control flow transfer, then it is still considered definitely assigned.)

Instruções try – catch-finallyTry-catch-finally statements

Análise de atribuição definitiva para uma try - catch - finally instrução do formulário:Definite assignment analysis for a try-catch-finally statement of the form:

try try_block
catch(...) catch_block_1
...
catch(...) catch_block_n
finally *finally_block*

é feito como se a instrução fosse uma try - finally instrução delimitando uma try - catch instrução:is done as if the statement were a try-finally statement enclosing a try-catch statement:

try {
    try try_block
    catch(...) catch_block_1
    ...
    catch(...) catch_block_n
}
finally finally_block

O exemplo a seguir demonstra como os diferentes blocos de uma try instrução (a instrução try) afetam a atribuição definitiva.The following example demonstrates how the different blocks of a try statement (The try statement) affect definite assignment.

class A
{
    static void F() {
        int i, j;
        try {
            goto LABEL;
            // neither i nor j definitely assigned
            i = 1;
            // i definitely assigned
        }

        catch {
            // neither i nor j definitely assigned
            i = 3;
            // i definitely assigned
        }

        finally {
            // neither i nor j definitely assigned
            j = 5;
            // j definitely assigned
            }
        // i and j definitely assigned
        LABEL:;
        // j definitely assigned

    }
}

Instruções ForeachForeach statements

Para uma foreach instrução stmt do formulário:For a foreach statement stmt of the form:

foreach ( type identifier in expr ) embedded_statement
  • O estado de atribuição definitivo de v no início de expr é o mesmo que o estado de v no início de stmt.The definite assignment state of v at the beginning of expr is the same as the state of v at the beginning of stmt.
  • O estado de atribuição definitivo de v na transferência de fluxo de controle para embedded_statement ou para o ponto final de stmt é o mesmo que o estado de v no final de expr.The definite assignment state of v on the control flow transfer to embedded_statement or to the end point of stmt is the same as the state of v at the end of expr.

Como usar instruçõesUsing statements

Para uma using instrução stmt do formulário:For a using statement stmt of the form:

using ( resource_acquisition ) embedded_statement
  • O estado de atribuição definitivo de v no início de resource_acquisition é o mesmo que o estado de v no início de stmt.The definite assignment state of v at the beginning of resource_acquisition is the same as the state of v at the beginning of stmt.
  • O estado de atribuição definitivo de v na transferência de fluxo de controle para embedded_statement é o mesmo que o estado de v no final de resource_acquisition.The definite assignment state of v on the control flow transfer to embedded_statement is the same as the state of v at the end of resource_acquisition.

Instruções LockLock statements

Para uma lock instrução stmt do formulário:For a lock statement stmt of the form:

lock ( expr ) embedded_statement
  • O estado de atribuição definitivo de v no início de expr é o mesmo que o estado de v no início de stmt.The definite assignment state of v at the beginning of expr is the same as the state of v at the beginning of stmt.
  • O estado de atribuição definitivo de v na transferência de fluxo de controle para embedded_statement é o mesmo que o estado de v no final de expr.The definite assignment state of v on the control flow transfer to embedded_statement is the same as the state of v at the end of expr.

Instruções yieldYield statements

Para uma yield return instrução stmt do formulário:For a yield return statement stmt of the form:

yield return expr ;
  • O estado de atribuição definitivo de v no início de expr é o mesmo que o estado de v no início de stmt.The definite assignment state of v at the beginning of expr is the same as the state of v at the beginning of stmt.
  • O estado de atribuição definitivo de v no final de stmt é igual ao estado de v no final de expr.The definite assignment state of v at the end of stmt is the same as the state of v at the end of expr.
  • Uma yield break instrução não tem nenhum efeito sobre o estado de atribuição definitivo.A yield break statement has no effect on the definite assignment state.

Regras gerais para expressões simplesGeneral rules for simple expressions

A regra a seguir se aplica a esses tipos de expressões: literais (literais), nomes simples (nomes simples), expressões de acesso de membro (acesso de membro), expressões de acesso base não indexadas (acesso de base), typeof expressões (o operador typeof), expressões de valor padrão (expressões devalor padrão) e nameof expressões (expressões nameof).The following rule applies to these kinds of expressions: literals (Literals), simple names (Simple names), member access expressions (Member access), non-indexed base access expressions (Base access), typeof expressions (The typeof operator), default value expressions (Default value expressions) and nameof expressions (Nameof expressions).

  • O estado de atribuição definitivo de v no final de tal expressão é igual ao estado de atribuição definido de v no início da expressão.The definite assignment state of v at the end of such an expression is the same as the definite assignment state of v at the beginning of the expression.

Regras gerais para expressões com expressões inseridasGeneral rules for expressions with embedded expressions

As regras a seguir se aplicam a esses tipos de expressões: expressões entre parênteses (expressões entre parênteses), expressões de acesso de elemento (acesso de elemento), expressões de acesso de base com indexação (acesso de base), expressões de incremento e decréscimo (incremento de sufixo e diminuição de operadores, incremento de prefixo e operadores de decréscimo),expressões de conversãounário + , - , ~ , * expressões, binary + , - , * , / , % ,,,,,,,,,,,, << >> < <= > >= == != is as & | , ^ expressões (operadores aritméticos, operadores de deslocamento, operadores relacionais e de teste de tipo, operadores lógicos), expressões de atribuição de composição (atribuição composta) checked e unchecked expressões (os operadores marcados e não verificados), além de expressões de criaçãodematriz e delegadoThe following rules apply to these kinds of expressions: parenthesized expressions (Parenthesized expressions), element access expressions (Element access), base access expressions with indexing (Base access), increment and decrement expressions (Postfix increment and decrement operators, Prefix increment and decrement operators), cast expressions (Cast expressions), unary +, -, ~, * expressions, binary +, -, *, /, %, <<, >>, <, <=, >, >=, ==, !=, is, as, &, |, ^ expressions (Arithmetic operators, Shift operators, Relational and type-testing operators, Logical operators), compound assignment expressions (Compound assignment), checked and unchecked expressions (The checked and unchecked operators), plus array and delegate creation expressions (The new operator).

Cada uma dessas expressões tem uma ou mais subexpressãos que são avaliadas incondicionalmente em uma ordem fixa.Each of these expressions has one or more sub-expressions that are unconditionally evaluated in a fixed order. Por exemplo, o % operador binário avalia o lado esquerdo do operador e, em seguida, o lado direito.For example, the binary % operator evaluates the left hand side of the operator, then the right hand side. Uma operação de indexação avalia a expressão indexada e, em seguida, avalia cada uma das expressões de índice, na ordem da esquerda para a direita.An indexing operation evaluates the indexed expression, and then evaluates each of the index expressions, in order from left to right. Para uma expr de expressão, que tem subexpressãos E1, E2,..., en, avaliadas nessa ordem:For an expression expr, which has sub-expressions e1, e2, ..., eN, evaluated in that order:

  • O estado de atribuição definitivo de v no início do E1 é o mesmo que o estado de atribuição definido no início de expr.The definite assignment state of v at the beginning of e1 is the same as the definite assignment state at the beginning of expr.
  • O estado de atribuição definitivo de v no início de Ei (i maior que um) é o mesmo que o estado de atribuição definido no final da subexpressão anterior.The definite assignment state of v at the beginning of ei (i greater than one) is the same as the definite assignment state at the end of the previous sub-expression.
  • O estado de atribuição definitivo de v no final de expr é igual ao estado de atribuição definido no final de enThe definite assignment state of v at the end of expr is the same as the definite assignment state at the end of eN

Expressões de invocação e expressões de criação de objetoInvocation expressions and object creation expressions

Para uma expr de expressão de invocação do formulário:For an invocation expression expr of the form:

primary_expression ( arg1 , arg2 , ... , argN )

ou uma expressão de criação de objeto do formulário:or an object creation expression of the form:

new type ( arg1 , arg2 , ... , argN )
  • Para uma expressão de invocação, o estado de atribuição definitivo de v antes de primary_expression é o mesmo que o estado de v antes de expr.For an invocation expression, the definite assignment state of v before primary_expression is the same as the state of v before expr.
  • Para uma expressão de invocação, o estado de atribuição definitivo de v antes de arg1 é igual ao estado de v após primary_expression.For an invocation expression, the definite assignment state of v before arg1 is the same as the state of v after primary_expression.
  • Para uma expressão de criação de objeto, o estado de atribuição definitivo de v antes de arg1 é o mesmo que o estado de v antes de expr.For an object creation expression, the definite assignment state of v before arg1 is the same as the state of v before expr.
  • Para cada argumento Argi, o estado de atribuição definitivo de v após Argi é determinado pelas regras de expressão normal, ignorando quaisquer ref out modificadores ou.For each argument argi, the definite assignment state of v after argi is determined by the normal expression rules, ignoring any ref or out modifiers.
  • Para cada argumento Argi para qualquer i maior que um, o estado de atribuição definitivo de v antes de Argi é o mesmo que o estado de v após o ARG anterior.For each argument argi for any i greater than one, the definite assignment state of v before argi is the same as the state of v after the previous arg.
  • Se a variável v for passada como um out argumento (ou seja, um argumento do formulário out v ) em qualquer um dos argumentos, o estado de v após expr será atribuído definitivamente.If the variable v is passed as an out argument (i.e., an argument of the form out v) in any of the arguments, then the state of v after expr is definitely assigned. , o estado de v After expr é o mesmo que o estado de v após argN.Otherwise; the state of v after expr is the same as the state of v after argN.
  • Para inicializadores de matriz(expressões de criação de matriz), inicializadores de objeto (inicializadores de objeto), inicializadores de coleção (inicializadores de coleção) e inicializadores de objeto anônimos (expressões de criação deobjeto anônimo), o estado de atribuição definitivo é determinado pela expansão de que essas construções são definidas em termos de.For array initializers (Array creation expressions), object initializers (Object initializers), collection initializers (Collection initializers) and anonymous object initializers (Anonymous object creation expressions), the definite assignment state is determined by the expansion that these constructs are defined in terms of.

Expressões de atribuição simplesSimple assignment expressions

Para uma expr de expressão do formulário w = expr_rhs :For an expression expr of the form w = expr_rhs:

  • O estado de atribuição definitivo de v antes de expr_rhs é o mesmo que o estado de atribuição definido de v antes de expr.The definite assignment state of v before expr_rhs is the same as the definite assignment state of v before expr.
  • O estado de atribuição definitivo de v após expr é determinado por:The definite assignment state of v after expr is determined by:
    • Se w for a mesma variável que v, o estado de atribuição definitivo de v após expr será atribuído definitivamente.If w is the same variable as v, then the definite assignment state of v after expr is definitely assigned.
    • Caso contrário, se a atribuição ocorrer dentro do construtor de instância de um tipo struct, se w for um acesso de propriedade que designa uma propriedade automaticamente implementada p na instância que está sendo construída e v for o campo de apoio oculto de p, o estado de atribuição definido de v após expr será atribuído definitivamente.Otherwise, if the assignment occurs within the instance constructor of a struct type, if w is a property access designating an automatically implemented property P on the instance being constructed and v is the hidden backing field of P, then the definite assignment state of v after expr is definitely assigned.
    • Caso contrário, o estado de atribuição definitivo de v após expr será o mesmo que o estado de atribuição definido de v após expr_rhs.Otherwise, the definite assignment state of v after expr is the same as the definite assignment state of v after expr_rhs.

Expressões && (condicional e)&& (conditional AND) expressions

Para uma expr de expressão do formulário expr_first && expr_second :For an expression expr of the form expr_first && expr_second:

  • O estado de atribuição definitivo de v antes de expr_first é o mesmo que o estado de atribuição definido de v antes de expr.The definite assignment state of v before expr_first is the same as the definite assignment state of v before expr.
  • O estado de atribuição definitivo de v antes de expr_second será definitivamente atribuído se o estado de v após expr_first for definitivamente atribuído ou "definitivamente atribuído após a expressão verdadeira".The definite assignment state of v before expr_second is definitely assigned if the state of v after expr_first is either definitely assigned or "definitely assigned after true expression". Caso contrário, ele não é definitivamente atribuído.Otherwise, it is not definitely assigned.
  • O estado de atribuição definitivo de v após expr é determinado por:The definite assignment state of v after expr is determined by:
    • Se expr_first for uma expressão constante com o valor false , o estado de atribuição definitivo de v após expr será o mesmo que o estado de atribuição definido de v após expr_first.If expr_first is a constant expression with the value false, then the definite assignment state of v after expr is the same as the definite assignment state of v after expr_first.
    • Caso contrário, se o estado de v após expr_first for definitivamente atribuído, o estado de v após expr será atribuído definitivamente.Otherwise, if the state of v after expr_first is definitely assigned, then the state of v after expr is definitely assigned.
    • Caso contrário, se o estado de v após expr_second for definitivamente atribuído, e o estado de v After expr_first for "definitivamente atribuído após a expressão falsa", o estado de v após expr será atribuído definitivamente.Otherwise, if the state of v after expr_second is definitely assigned, and the state of v after expr_first is "definitely assigned after false expression", then the state of v after expr is definitely assigned.
    • Caso contrário, se o estado de v após expr_second for definitivamente atribuído ou "definitivamente atribuído após a expressão verdadeira", o estado de v após expr será "definitivamente atribuído após a expressão verdadeira".Otherwise, if the state of v after expr_second is definitely assigned or "definitely assigned after true expression", then the state of v after expr is "definitely assigned after true expression".
    • Caso contrário, se o estado de v após expr_first for "definitivamente atribuído após a expressão falsa", e o estado de v após expr_second for "definitivamente atribuído após a expressão falsa", o estado de v após expr será "definitivamente atribuído após a expressão falsa".Otherwise, if the state of v after expr_first is "definitely assigned after false expression", and the state of v after expr_second is "definitely assigned after false expression", then the state of v after expr is "definitely assigned after false expression".
    • Caso contrário, o estado de v após expr não será atribuído definitivamente.Otherwise, the state of v after expr is not definitely assigned.

No exemploIn the example

class A
{
    static void F(int x, int y) {
        int i;
        if (x >= 0 && (i = y) >= 0) {
            // i definitely assigned
        }
        else {
            // i not definitely assigned
        }
        // i not definitely assigned
    }
}

a variável i é considerada definitivamente atribuída em uma das instruções inseridas de uma if instrução, mas não no outro.the variable i is considered definitely assigned in one of the embedded statements of an if statement but not in the other. Na if instrução no método F , a variável i é definitivamente atribuída na primeira instrução inserida porque a execução da expressão (i = y) sempre precede a execução dessa instrução inserida.In the if statement in method F, the variable i is definitely assigned in the first embedded statement because execution of the expression (i = y) always precedes execution of this embedded statement. Por outro lado, a variável i não é definitivamente atribuída na segunda instrução incorporada, pois x >= 0 pode ter testado false, resultando na não atribuição da variável i .In contrast, the variable i is not definitely assigned in the second embedded statement, since x >= 0 might have tested false, resulting in the variable i being unassigned.

|| expressões (condicionais ou)|| (conditional OR) expressions

Para uma expr de expressão do formulário expr_first || expr_second :For an expression expr of the form expr_first || expr_second:

  • O estado de atribuição definitivo de v antes de expr_first é o mesmo que o estado de atribuição definido de v antes de expr.The definite assignment state of v before expr_first is the same as the definite assignment state of v before expr.
  • O estado de atribuição definitivo de v antes de expr_second será definitivamente atribuído se o estado de v após expr_first for definitivamente atribuído ou "definitivamente atribuído após a expressão falsa".The definite assignment state of v before expr_second is definitely assigned if the state of v after expr_first is either definitely assigned or "definitely assigned after false expression". Caso contrário, ele não é definitivamente atribuído.Otherwise, it is not definitely assigned.
  • A instrução de atribuição definitiva de v após expr é determinada por:The definite assignment statement of v after expr is determined by:
    • Se expr_first for uma expressão constante com o valor true , o estado de atribuição definitivo de v após expr será o mesmo que o estado de atribuição definido de v após expr_first.If expr_first is a constant expression with the value true, then the definite assignment state of v after expr is the same as the definite assignment state of v after expr_first.
    • Caso contrário, se o estado de v após expr_first for definitivamente atribuído, o estado de v após expr será atribuído definitivamente.Otherwise, if the state of v after expr_first is definitely assigned, then the state of v after expr is definitely assigned.
    • Caso contrário, se o estado de v após expr_second for definitivamente atribuído, e o estado de v After expr_first for "definitivamente atribuído após a expressão verdadeira", o estado de v após expr será atribuído definitivamente.Otherwise, if the state of v after expr_second is definitely assigned, and the state of v after expr_first is "definitely assigned after true expression", then the state of v after expr is definitely assigned.
    • Caso contrário, se o estado de v após expr_second for definitivamente atribuído ou "definitivamente atribuído após a expressão falsa", o estado de v após expr será "definitivamente atribuído após a expressão falsa".Otherwise, if the state of v after expr_second is definitely assigned or "definitely assigned after false expression", then the state of v after expr is "definitely assigned after false expression".
    • Caso contrário, se o estado de v após expr_first for "definitivamente atribuída após a expressão verdadeira", e o estado de v após expr_second for "definitivamente atribuído após a expressão verdadeira", o estado de v após expr será "definitivamente atribuído após a expressão verdadeira".Otherwise, if the state of v after expr_first is "definitely assigned after true expression", and the state of v after expr_second is "definitely assigned after true expression", then the state of v after expr is "definitely assigned after true expression".
    • Caso contrário, o estado de v após expr não será atribuído definitivamente.Otherwise, the state of v after expr is not definitely assigned.

No exemploIn the example

class A
{
    static void G(int x, int y) {
        int i;
        if (x >= 0 || (i = y) >= 0) {
            // i not definitely assigned
        }
        else {
            // i definitely assigned
        }
        // i not definitely assigned
    }
}

a variável i é considerada definitivamente atribuída em uma das instruções inseridas de uma if instrução, mas não no outro.the variable i is considered definitely assigned in one of the embedded statements of an if statement but not in the other. Na if instrução no método G , a variável i é definitivamente atribuída na segunda instrução inserida porque a execução da expressão (i = y) sempre precede a execução dessa instrução inserida.In the if statement in method G, the variable i is definitely assigned in the second embedded statement because execution of the expression (i = y) always precedes execution of this embedded statement. Por outro lado, a variável i não é definitivamente atribuída na primeira instrução inserida, pois x >= 0 pode ter testado verdadeiro, resultando na não atribuição da variável i .In contrast, the variable i is not definitely assigned in the first embedded statement, since x >= 0 might have tested true, resulting in the variable i being unassigned.

!! (negação lógica) expressões(logical negation) expressions

Para uma expr de expressão do formulário ! expr_operand :For an expression expr of the form ! expr_operand:

  • O estado de atribuição definitivo de v antes de expr_operand é o mesmo que o estado de atribuição definido de v antes de expr.The definite assignment state of v before expr_operand is the same as the definite assignment state of v before expr.
  • O estado de atribuição definitivo de v após expr é determinado por:The definite assignment state of v after expr is determined by:
    • Se o estado de v após * expr_operand * for definitivamente atribuído, o estado de v após expr será atribuído definitivamente.If the state of v after *expr_operand *is definitely assigned, then the state of v after expr is definitely assigned.
    • Se o estado de v após * expr_operand * não for definitivamente atribuído, o estado de v após expr não será atribuído definitivamente.If the state of v after *expr_operand *is not definitely assigned, then the state of v after expr is not definitely assigned.
    • Se o estado de v após * expr_operand * for "definitivamente atribuído após a expressão falsa", o estado de v após expr será "definitivamente atribuído após a expressão verdadeira".If the state of v after *expr_operand *is "definitely assigned after false expression", then the state of v after expr is "definitely assigned after true expression".
    • Se o estado de v após * expr_operand * for "definitivamente atribuído após a expressão verdadeira", o estado de v após expr será "definitivamente atribuído após a expressão falsa".If the state of v after *expr_operand *is "definitely assigned after true expression", then the state of v after expr is "definitely assigned after false expression".

???? (União nula) expressões(null coalescing) expressions

Para uma expr de expressão do formulário expr_first ?? expr_second :For an expression expr of the form expr_first ?? expr_second:

  • O estado de atribuição definitivo de v antes de expr_first é o mesmo que o estado de atribuição definido de v antes de expr.The definite assignment state of v before expr_first is the same as the definite assignment state of v before expr.
  • O estado de atribuição definitivo de v antes de expr_second é o mesmo que o estado de atribuição definido de v após expr_first.The definite assignment state of v before expr_second is the same as the definite assignment state of v after expr_first.
  • A instrução de atribuição definitiva de v após expr é determinada por:The definite assignment statement of v after expr is determined by:
    • Se expr_first for uma expressão constante (expressões constantes) com valor NULL, o estado de v após expr será o mesmo que o estado de v após expr_second.If expr_first is a constant expression (Constant expressions) with value null, then the state of v after expr is the same as the state of v after expr_second.
  • Caso contrário, o estado de v After expr será o mesmo que o estado de atribuição definido de v após expr_first.Otherwise, the state of v after expr is the same as the definite assignment state of v after expr_first.

expressões?: (condicionais)?: (conditional) expressions

Para uma expr de expressão do formulário expr_cond ? expr_true : expr_false :For an expression expr of the form expr_cond ? expr_true : expr_false:

  • O estado de atribuição definitivo de v antes de expr_cond é o mesmo que o estado de v antes de expr.The definite assignment state of v before expr_cond is the same as the state of v before expr.
  • O estado de atribuição definitivo de v antes de expr_true é definitivamente atribuído se e somente se uma das seguintes isenções:The definite assignment state of v before expr_true is definitely assigned if and only if one of the following holds:
    • expr_cond é uma expressão constante com o valor falseexpr_cond is a constant expression with the value false
    • o estado de v após expr_cond é definitivamente atribuído ou "definitivamente atribuído após a expressão verdadeira".the state of v after expr_cond is definitely assigned or "definitely assigned after true expression".
  • O estado de atribuição definitivo de v antes de expr_false é definitivamente atribuído se e somente se uma das seguintes isenções:The definite assignment state of v before expr_false is definitely assigned if and only if one of the following holds:
    • expr_cond é uma expressão constante com o valor trueexpr_cond is a constant expression with the value true
    • o estado de v após expr_cond é definitivamente atribuído ou "definitivamente atribuído após expressão falsa".the state of v after expr_cond is definitely assigned or "definitely assigned after false expression".
  • O estado de atribuição definitivo de v após expr é determinado por:The definite assignment state of v after expr is determined by:
    • Se expr_cond for uma expressão constante (expressões constantes) com valor true , o estado de v após expr será o mesmo que o estado de v após expr_true.If expr_cond is a constant expression (Constant expressions) with value true then the state of v after expr is the same as the state of v after expr_true.
    • Caso contrário, se expr_cond for uma expressão constante (expressões constantes) com valor false , o estado de v após expr será o mesmo que o estado de v após expr_false.Otherwise, if expr_cond is a constant expression (Constant expressions) with value false then the state of v after expr is the same as the state of v after expr_false.
    • Caso contrário, se o estado de v após expr_true for definitivamente atribuído e o estado de v após expr_false for definitivamente atribuído, o estado de v após expr será atribuído definitivamente.Otherwise, if the state of v after expr_true is definitely assigned and the state of v after expr_false is definitely assigned, then the state of v after expr is definitely assigned.
    • Caso contrário, o estado de v após expr não será atribuído definitivamente.Otherwise, the state of v after expr is not definitely assigned.

Funções anônimasAnonymous functions

Para um lambda_expression ou expr de anonymous_method_expression com um corpo ( bloco ou expressão) corpo:For a lambda_expression or anonymous_method_expression expr with a body (either block or expression) body:

  • O estado de atribuição definitivo de uma variável externa v para o corpo é o mesmo que o estado de v antes de expr.The definite assignment state of an outer variable v before body is the same as the state of v before expr. Ou seja, o estado de atribuição definitivo de variáveis externas é herdado do contexto da função anônima.That is, definite assignment state of outer variables is inherited from the context of the anonymous function.
  • O estado de atribuição definitivo de uma variável externa v depois de expr é o mesmo que o estado de v antes de expr.The definite assignment state of an outer variable v after expr is the same as the state of v before expr.

O exemploThe example

delegate bool Filter(int i);

void F() {
    int max;

    // Error, max is not definitely assigned
    Filter f = (int n) => n < max;

    max = 5;
    DoWork(f);
}

gera um erro de tempo de compilação porque max não é definitivamente atribuído onde a função anônima é declarada.generates a compile-time error since max is not definitely assigned where the anonymous function is declared. O exemploThe example

delegate void D();

void F() {
    int n;
    D d = () => { n = 1; };

    d();

    // Error, n is not definitely assigned
    Console.WriteLine(n);
}

também gera um erro de tempo de compilação porque a atribuição para n na função anônima não tem nenhum efeito sobre o estado de atribuição definitivo de n fora da função anônima.also generates a compile-time error since the assignment to n in the anonymous function has no affect on the definite assignment state of n outside the anonymous function.

Referências de variáveisVariable references

Uma variable_reference é uma expressão que é classificada como uma variável.A variable_reference is an expression that is classified as a variable. Um variable_reference denota um local de armazenamento que pode ser acessado para buscar o valor atual e para armazenar um novo valor.A variable_reference denotes a storage location that can be accessed both to fetch the current value and to store a new value.

variable_reference
    : expression
    ;

Em C e C++, um variable_reference é conhecido como um lvalue.In C and C++, a variable_reference is known as an lvalue.

Atomicidade de referências de variáveisAtomicity of variable references

Leituras e gravações dos seguintes tipos de dados são Atomic: bool , char , byte ,,, sbyte short ushort , uint , int , float e tipos de referência.Reads and writes of the following data types are atomic: bool, char, byte, sbyte, short, ushort, uint, int, float, and reference types. Além disso, leituras e gravações de tipos de enumeração com um tipo subjacente na lista anterior também são atômicas.In addition, reads and writes of enum types with an underlying type in the previous list are also atomic. As leituras e gravações de outros tipos, incluindo long ,, ulong double e decimal , bem como tipos definidos pelo usuário, não têm garantia de serem atômicas.Reads and writes of other types, including long, ulong, double, and decimal, as well as user-defined types, are not guaranteed to be atomic. Além das funções de biblioteca projetadas para essa finalidade, não há nenhuma garantia de leitura-modificação-gravação atômica, como no caso de incremento ou decréscimo.Aside from the library functions designed for that purpose, there is no guarantee of atomic read-modify-write, such as in the case of increment or decrement.