VariabiliVariables

Le variabili rappresentano i percorsi di archiviazione.Variables represent storage locations. Ogni variabile dispone di un tipo che determina quali valori possono essere archiviati nella variabile.Every variable has a type that determines what values can be stored in the variable. C#è un linguaggio indipendente dai tipi e il C# compilatore garantisce che i valori archiviati nelle variabili siano sempre del tipo appropriato.C# is a type-safe language, and the C# compiler guarantees that values stored in variables are always of the appropriate type. Il valore di una variabile può essere modificato tramite l'assegnazione o l' ++ uso degli operatori e. --The value of a variable can be changed through assignment or through use of the ++ and -- operators.

Una variabile deve essere assegnata definitivamente (assegnazione definita) prima di poter ottenere il relativo valore.A variable must be definitely assigned (Definite assignment) before its value can be obtained.

Come descritto nelle sezioni seguenti, le variabili vengono inizialmente assegnate o inizialmente non assegnate.As described in the following sections, variables are either initially assigned or initially unassigned. Una variabile inizialmente assegnata ha un valore iniziale ben definito ed è sempre considerata assegnata definitivamente.An initially assigned variable has a well-defined initial value and is always considered definitely assigned. Una variabile inizialmente non assegnata non ha un valore iniziale.An initially unassigned variable has no initial value. Affinché una variabile inizialmente non assegnata venga considerata definitivamente assegnata in una determinata posizione, un'assegnazione alla variabile deve essere eseguita in ogni percorso di esecuzione possibile che conduce a tale posizione.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.

Categorie di variabiliVariable categories

C#definisce sette categorie di variabili: variabili statiche, variabili di istanza, elementi di matrice, parametri di valore, parametri di riferimento, parametri di output e variabili locali.C# defines seven categories of variables: static variables, instance variables, array elements, value parameters, reference parameters, output parameters, and local variables. Le sezioni seguenti descrivono ognuna di queste categorie.The sections that follow describe each of these categories.

Nell'esempioIn 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è una variabile statica, y è una variabile di istanza v[0] , è un elemento di a matrice, è un parametro b di valore, è un c parametro di riferimento, è un i parametro di output e è una variabile locale .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.

Variabili staticheStatic variables

Un campo dichiarato con il static modificatore è denominato variabile statica.A field declared with the static modifier is called a static variable. Una variabile statica è presente prima dell'esecuzione del costruttore statico (costruttori statici) per il tipo che lo contiene e cessa di esistere quando il dominio applicazione associato cessa di esistere.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.

Il valore iniziale di una variabile statica è il valore predefinito (valori predefiniti) del tipo della variabile.The initial value of a static variable is the default value (Default values) of the variable's type.

Ai fini del controllo di assegnazione definito, una variabile statica viene considerata inizialmente assegnata.For purposes of definite assignment checking, a static variable is considered initially assigned.

Variabili di istanzaInstance variables

Un campo dichiarato senza il static modificatore viene chiamato variabile di istanza.A field declared without the static modifier is called an instance variable.

Variabili di istanza nelle classiInstance variables in classes

Una variabile di istanza di una classe diventa disponibile quando viene creata una nuova istanza di tale classe e cessa di esistere quando non vi sono riferimenti a tale istanza e il distruttore dell'istanza, se presente, è stato eseguito.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.

Il valore iniziale di una variabile di istanza di una classe è il valore predefinito (valori predefiniti) del tipo della variabile.The initial value of an instance variable of a class is the default value (Default values) of the variable's type.

Ai fini del controllo di assegnazione definito, una variabile di istanza di una classe viene considerata inizialmente assegnata.For the purpose of definite assignment checking, an instance variable of a class is considered initially assigned.

Variabili di istanza negli structInstance variables in structs

Una variabile di istanza di uno struct ha esattamente la stessa durata della variabile struct a cui appartiene.An instance variable of a struct has exactly the same lifetime as the struct variable to which it belongs. In altre parole, quando una variabile di un tipo struct entra in vigore o cessa di esistere, è necessario eseguire anche le variabili di istanza dello 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.

Lo stato di assegnazione iniziale di una variabile di istanza di uno struct è identico a quello della variabile struct che lo contiene.The initial assignment state of an instance variable of a struct is the same as that of the containing struct variable. In altre parole, quando una variabile struct viene considerata inizialmente assegnata, anch ' essa sono variabili di istanza e, quando una variabile struct viene considerata inizialmente non assegnata, le variabili di istanza non vengono assegnate in modo analogo.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.

Elementi di matriceArray elements

Gli elementi di una matrice entrano in vigore quando viene creata un'istanza di matrice e smettono di esistere quando non vi sono riferimenti a tale istanza di matrice.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.

Il valore iniziale di ogni elemento di una matrice è il valore predefinito (valori predefiniti) del tipo degli elementi della matrice.The initial value of each of the elements of an array is the default value (Default values) of the type of the array elements.

Ai fini del controllo di assegnazione definito, viene considerato inizialmente assegnato un elemento di matrice.For the purpose of definite assignment checking, an array element is considered initially assigned.

Parametri valoreValue parameters

Un parametro dichiarato senza un ref modificatore o out è un parametro di valore.A parameter declared without a ref or out modifier is a value parameter.

Un parametro di valore entra in vigore alla chiamata del membro della funzione (metodo, costruttore di istanza, funzione di accesso o operatore) o funzione anonima a cui appartiene il parametro e viene inizializzato con il valore dell'argomento fornito nella chiamata.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. Un parametro di valore in genere smette di esistere al ritorno del membro della funzione o della funzione anonima.A value parameter normally ceases to exist upon return of the function member or anonymous function. Tuttavia, se il parametro value viene acquisito da una funzione anonima (espressioni di funzione anonima), la durata si estende almeno finché il delegato o l'albero delle espressioni creato da tale funzione anonima non sarà idoneo per Garbage Collection.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.

Ai fini del controllo di assegnazione definito, un parametro di valore viene considerato inizialmente assegnato.For the purpose of definite assignment checking, a value parameter is considered initially assigned.

Parametri per riferimentoReference parameters

Un parametro dichiarato con un ref modificatore è un parametro di riferimento.A parameter declared with a ref modifier is a reference parameter.

Un parametro di riferimento non crea un nuovo percorso di archiviazione.A reference parameter does not create a new storage location. Un parametro Reference rappresenta invece lo stesso percorso di archiviazione della variabile specificata come argomento nel membro della funzione o in una chiamata di funzione anonima.Instead, a reference parameter represents the same storage location as the variable given as the argument in the function member or anonymous function invocation. Pertanto, il valore di un parametro di riferimento è sempre lo stesso della variabile sottostante.Thus, the value of a reference parameter is always the same as the underlying variable.

Le seguenti regole di assegnazione definite si applicano ai parametri di riferimento.The following definite assignment rules apply to reference parameters. Si notino le diverse regole per i parametri di output descritti in parametri di output.Note the different rules for output parameters described in Output parameters.

  • Una variabile deve essere assegnata definitivamente (assegnazione definita) prima di poter essere passata come parametro di riferimento in una chiamata a un membro di funzione o a un delegato.A variable must be definitely assigned (Definite assignment) before it can be passed as a reference parameter in a function member or delegate invocation.
  • All'interno di un membro di funzione o di una funzione anonima, viene considerato inizialmente assegnato un parametro di riferimento.Within a function member or anonymous function, a reference parameter is considered initially assigned.

All'interno di un metodo di istanza o di una funzione di accesso this dell'istanza di un tipo struct, la parola chiave si comporta esattamente come un parametro di riferimento del tipo struct (questo accesso).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).

Parametri di outputOutput parameters

Un parametro dichiarato con un out modificatore è un parametro di output.A parameter declared with an out modifier is an output parameter.

Un parametro di output non crea un nuovo percorso di archiviazione.An output parameter does not create a new storage location. Un parametro di output rappresenta invece lo stesso percorso di archiviazione della variabile specificata come argomento nel membro della funzione o nella chiamata al delegato.Instead, an output parameter represents the same storage location as the variable given as the argument in the function member or delegate invocation. Pertanto, il valore di un parametro di output corrisponde sempre alla variabile sottostante.Thus, the value of an output parameter is always the same as the underlying variable.

Le seguenti regole di assegnazione definite si applicano ai parametri di output.The following definite assignment rules apply to output parameters. Si notino le diverse regole per i parametri di riferimento descritti in parametri di riferimento.Note the different rules for reference parameters described in Reference parameters.

  • Una variabile non deve essere definitivamente assegnata prima di poter essere passata come parametro di output in una chiamata a un membro di funzione o a un delegato.A variable need not be definitely assigned before it can be passed as an output parameter in a function member or delegate invocation.
  • Dopo il normale completamento di un membro di funzione o di una chiamata a un delegato, ogni variabile passata come parametro di output viene considerata assegnata in tale percorso di esecuzione.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.
  • All'interno di un membro di funzione o di una funzione anonima, un parametro di output viene considerato inizialmente non assegnato.Within a function member or anonymous function, an output parameter is considered initially unassigned.
  • Ogni parametro di output di un membro di funzione o di una funzione anonima deve essere assegnato definitivamente (assegnazione definita) prima che il membro della funzione o la funzione anonima restituisca 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.

All'interno di un costruttore di istanza di un tipo this struct, la parola chiave si comporta esattamente come un parametro di output del tipo struct (questo accesso).Within an instance constructor of a struct type, the this keyword behaves exactly as an output parameter of the struct type (This access).

Variabili localiLocal variables

Una variabile locale viene dichiarata da un local_variable_declaration, che può verificarsi in un blocco, un for_Statement, un switch_Statement o un using_statement; o da un foreach_statement o un specific_catch_clause per un 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.

La durata di una variabile locale è la parte dell'esecuzione del programma durante la quale è garantita la riservatezza dell'archiviazione.The lifetime of a local variable is the portion of program execution during which storage is guaranteed to be reserved for it. Questa durata estende almeno dall'immissione nel blocco, for_Statement, switch_Statement, using_statement, foreach_statemento specific_catch_clause a cui è associato, fino a l'esecuzione di tale blocco, for_Statement, switch_Statement, using_statement, foreach_statemento specific_catch_clause termina in qualsiasi modo.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. (L'immissione di un blocco racchiuso o la chiamata di un metodo viene sospesa, ma non termina, l'esecuzione del bloccocorrente, for_Statement, switch_Statement, using_statement, foreach_statemento specific_ catch_clause.) Se la variabile locale viene acquisita da una funzione anonima (variabili esterne acquisite), la durata si estende almeno fino a quando il delegato o l'albero delle espressioni creato dalla funzione anonima, insieme ad altri oggetti che fanno riferimento al la variabile acquisita è idonea per Garbage Collection.(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 il bloccopadre, for_Statement, switch_Statement, using_statement, foreach_statemento specific_catch_clause viene immesso in modo ricorsivo, viene creata una nuova istanza della variabile locale Time e il relativo local_variable_initializer, se presente, viene valutato ogni volta.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.

Una variabile locale introdotta da un local_variable_declaration non viene inizializzata automaticamente e pertanto non ha alcun valore predefinito.A local variable introduced by a local_variable_declaration is not automatically initialized and thus has no default value. Ai fini del controllo di assegnazione definito, una variabile locale introdotta da un local_variable_declaration viene considerata inizialmente non assegnata.For the purpose of definite assignment checking, a local variable introduced by a local_variable_declaration is considered initially unassigned. Un local_variable_declaration può includere un local_variable_initializer, nel qual caso la variabile viene considerata assegnata definitivamente solo dopo l'espressione di inizializzazione (istruzioni di dichiarazione).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).

Nell'ambito di una variabile locale introdotta da un local_variable_declaration, si tratta di un errore in fase di compilazione per fare riferimento a tale variabile locale in una posizione testuale che precede il 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 la dichiarazione di variabile locale è implicita (dichiarazioni di variabili locali), è anche un errore fare riferimento alla variabile all'interno di 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.

Una variabile locale introdotta da un foreach_statement o un specific_catch_clause viene considerata definitivamente assegnata nell'intero ambito.A local variable introduced by a foreach_statement or a specific_catch_clause is considered definitely assigned in its entire scope.

La durata effettiva di una variabile locale è dipendente dall'implementazione.The actual lifetime of a local variable is implementation-dependent. Un compilatore, ad esempio, potrebbe determinare in modo statico che una variabile locale in un blocco viene utilizzata solo per una piccola parte di tale blocco.For example, a compiler might statically determine that a local variable in a block is only used for a small portion of that block. Utilizzando questa analisi, il compilatore potrebbe generare codice che comportano una durata più breve del relativo spazio di archiviazione della variabile rispetto al blocco che lo contiene.Using this analysis, the compiler could generate code that results in the variable's storage having a shorter lifetime than its containing block.

Lo spazio di archiviazione a cui fa riferimento una variabile di riferimento locale viene recuperato indipendentemente dalla durata della variabile di riferimento locale (gestione automatica della memoria).The storage referred to by a local reference variable is reclaimed independently of the lifetime of that local reference variable (Automatic memory management).

Valori predefinitiDefault values

Le seguenti categorie di variabili vengono inizializzate automaticamente sui rispettivi valori predefiniti:The following categories of variables are automatically initialized to their default values:

  • Variabili statiche.Static variables.
  • Variabili di istanza delle istanze della classe.Instance variables of class instances.
  • Elementi di matrice.Array elements.

Il valore predefinito di una variabile dipende dal tipo della variabile e viene determinato nel modo seguente:The default value of a variable depends on the type of the variable and is determined as follows:

  • Per una variabile di un value_type, il valore predefinito è lo stesso del valore calcolato dal costruttore predefinito di value_type(costruttori predefiniti).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).
  • Per una variabile di un reference_type, il valore predefinito è null.For a variable of a reference_type, the default value is null.

L'inizializzazione dei valori predefiniti viene in genere eseguita con il gestore della memoria o Garbage Collector inizializzare la memoria su tutti i bit-zero prima che venga allocato per l'utilizzo.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. Per questo motivo, è consigliabile utilizzare All-bits-zero per rappresentare il riferimento null.For this reason, it is convenient to use all-bits-zero to represent the null reference.

Assegnazione definitaDefinite assignment

In una determinata posizione nel codice eseguibile di un membro di funzione, una variabile viene definita definitivamente assegnata se il compilatore è in grado di dimostrare, da un'analisi di flusso statica specifica (regole precise per determinare l'assegnazione definita), che la variabile è stata inizializzata automaticamente o è stata la destinazione di almeno un'assegnazione.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. Dichiarate in modo informale, le regole di assegnazione definitiva sono:Informally stated, the rules of definite assignment are:

La specifica formale sottostante le regole informali precedenti è descritta in variabili inizialmente assegnate, variabili inizialmente non assegnatee regole precise per determinare l'assegnazione definita.The formal specification underlying the above informal rules is described in Initially assigned variables, Initially unassigned variables, and Precise rules for determining definite assignment.

Gli Stati di assegnazione definiti delle variabili di istanza di una variabile struct_type vengono rilevati singolarmente e collettivamente.The definite assignment states of instance variables of a struct_type variable are tracked individually as well as collectively. Oltre alle regole precedenti, le regole seguenti si applicano alle variabili struct_type e alle relative variabili di istanza:In addition to the rules above, the following rules apply to struct_type variables and their instance variables:

  • Una variabile di istanza viene considerata definitivamente assegnata se la variabile struct_type che lo contiene viene considerata definitivamente assegnata.An instance variable is considered definitely assigned if its containing struct_type variable is considered definitely assigned.
  • Una variabile struct_type viene considerata definitivamente assegnata se ogni variabile di istanza viene considerata assegnata definitivamente.A struct_type variable is considered definitely assigned if each of its instance variables is considered definitely assigned.

L'assegnazione definita è un requisito nei contesti seguenti:Definite assignment is a requirement in the following contexts:

  • Una variabile deve essere assegnata in modo sicuro in ogni posizione in cui viene ottenuto il relativo valore.A variable must be definitely assigned at each location where its value is obtained. In questo modo si garantisce che non si verifichino mai valori non definiti.This ensures that undefined values never occur. L'occorrenza di una variabile in un'espressione viene considerata come ottenere il valore della variabile, tranne quandoThe occurrence of a variable in an expression is considered to obtain the value of the variable, except when
    • la variabile è l'operando sinistro di un'assegnazione semplice,the variable is the left operand of a simple assignment,
    • la variabile viene passata come parametro di output othe variable is passed as an output parameter, or
    • la variabile è una variabile struct_type e si verifica come operando sinistro di un accesso ai membri.the variable is a struct_type variable and occurs as the left operand of a member access.
  • Una variabile deve essere assegnata in modo sicuro in ogni posizione in cui viene passata come parametro di riferimento.A variable must be definitely assigned at each location where it is passed as a reference parameter. In questo modo il membro della funzione richiamato può considerare il parametro di riferimento inizialmente assegnato.This ensures that the function member being invoked can consider the reference parameter initially assigned.
  • Tutti i parametri di output di un membro di funzione devono essere assegnati in modo sicuro in ogni posizione in cui il return membro della funzione restituisce (tramite un'istruzione o tramite l'esecuzione che raggiunge la fine del corpo del membro della funzione).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). Ciò garantisce che i membri di funzione non restituiscano valori non definiti nei parametri di output, consentendo al compilatore di prendere in considerazione la chiamata di un membro di funzione che accetta una variabile come parametro di output equivalente a un'assegnazione alla variabile.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.
  • La this variabile di un costruttore di istanza di struct_type deve essere assegnata in modo sicuro in ogni posizione in cui il costruttore dell'istanza restituisce.The this variable of a struct_type instance constructor must be definitely assigned at each location where that instance constructor returns.

Variabili assegnate inizialmenteInitially assigned variables

Le categorie di variabili seguenti sono classificate inizialmente come assegnate:The following categories of variables are classified as initially assigned:

  • Variabili statiche.Static variables.
  • Variabili di istanza delle istanze della classe.Instance variables of class instances.
  • Variabili di istanza delle variabili struct inizialmente assegnate.Instance variables of initially assigned struct variables.
  • Elementi di matrice.Array elements.
  • Parametri del valore.Value parameters.
  • Parametri di riferimento.Reference parameters.
  • Variabili dichiarate catch in una clausola foreach o in un'istruzione.Variables declared in a catch clause or a foreach statement.

Variabili inizialmente non assegnateInitially unassigned variables

Le categorie di variabili seguenti sono classificate inizialmente come non assegnate:The following categories of variables are classified as initially unassigned:

  • Variabili di istanza di variabili struct inizialmente non assegnate.Instance variables of initially unassigned struct variables.
  • Parametri di output, inclusa this la variabile dei costruttori di istanze struct.Output parameters, including the this variable of struct instance constructors.
  • Variabili locali, ad eccezione di quelle dichiarate in foreach una catch clausola o in un'istruzione.Local variables, except those declared in a catch clause or a foreach statement.

Regole precise per determinare l'assegnazione definitivaPrecise rules for determining definite assignment

Per determinare che ogni variabile utilizzata è assegnata definitivamente, il compilatore deve usare un processo equivalente a quello descritto in questa sezione.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.

Il compilatore elabora il corpo di ogni membro di funzione che dispone di una o più variabili inizialmente non assegnate.The compiler processes the body of each function member that has one or more initially unassigned variables. Per ogni variabile inizialmente non assegnata v, il compilatore determina uno stato di assegnazione definito per v in ognuno dei punti seguenti del membro della funzione: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:

  • All'inizio di ogni istruzioneAt the beginning of each statement
  • Al punto finale (punti finali e raggiungibilità) di ogni istruzioneAt the end point (End points and reachability) of each statement
  • In ogni arco che trasferisce il controllo a un'altra istruzione o al punto finale di un'istruzioneOn each arc which transfers control to another statement or to the end point of a statement
  • All'inizio di ogni espressioneAt the beginning of each expression
  • Alla fine di ogni espressioneAt the end of each expression

Lo stato di assegnazione definito di v può essere uno dei seguenti:The definite assignment state of v can be either:

  • Assegnato definitivamente.Definitely assigned. Ciò indica che in tutti i flussi di controllo possibili fino a questo punto è stato assegnato un valore a v .This indicates that on all possible control flows to this point, v has been assigned a value.
  • Non assegnato definitivamente.Not definitely assigned. Per lo stato di una variabile alla fine di un'espressione di tipo bool, lo stato di una variabile che non è assegnata definitivamente può (ma non necessariamente) rientrare in uno degli stati secondari seguenti: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:
    • Assegnato definitivamente dopo un'espressione true.Definitely assigned after true expression. Questo stato indica che v viene assegnato definitivamente se l'espressione booleana è stata valutata come true, ma non è necessariamente assegnata se l'espressione booleana viene valutata come 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.
    • Assegnato definitivamente dopo un'espressione false.Definitely assigned after false expression. Questo stato indica che v viene assegnato definitivamente se l'espressione booleana viene valutata come false, ma non viene necessariamente assegnata se l'espressione booleana restituisce 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.

Le regole seguenti determinano il modo in cui viene determinato lo stato di una variabile v in ogni posizione.The following rules govern how the state of a variable v is determined at each location.

Regole generali per le istruzioniGeneral rules for statements

  • v non viene assegnato definitivamente all'inizio del corpo di un membro di funzione.v is not definitely assigned at the beginning of a function member body.
  • v viene assegnato definitivamente all'inizio di un'istruzione non raggiungibile.v is definitely assigned at the beginning of any unreachable statement.
  • Lo stato di assegnazione definito di v all'inizio di qualsiasi altra istruzione è determinato dal controllo dello stato di assegnazione definito di v in tutti i trasferimenti di flusso di controllo destinati all'inizio dell'istruzione.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 solo se) v viene assegnato in modo sicuro a tutti questi trasferimenti del flusso di controllo, v viene assegnato definitivamente all'inizio dell'istruzione.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. Il set di possibili trasferimenti del flusso di controllo viene determinato in modo analogo al controllo della raggiungibilità delle istruzioni (punti finali e raggiungibilità).The set of possible control flow transfers is determined in the same way as for checking statement reachability (End points and reachability).
  • Stato di assegnazione definito di v in corrispondenza del punto finale di un blocco checked, unchecked do, if foreach for while,,,,, lock, using, o switchl'istruzione viene determinata controllando lo stato di assegnazione definito di v in tutti i trasferimenti del flusso di controllo che hanno come destinazione il punto finale dell'istruzione.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 è assegnato definitivamente a tutti questi trasferimenti del flusso di controllo, v viene assegnato definitivamente al punto finale dell'istruzione.If v is definitely assigned on all such control flow transfers, then v is definitely assigned at the end point of the statement. In caso contrario v non è assegnato definitivamente al punto finale dell'istruzione.Otherwise; v is not definitely assigned at the end point of the statement. Il set di possibili trasferimenti del flusso di controllo viene determinato in modo analogo al controllo della raggiungibilità delle istruzioni (punti finali e raggiungibilità).The set of possible control flow transfers is determined in the same way as for checking statement reachability (End points and reachability).

Istruzioni Block, checked e uncheckedBlock statements, checked, and unchecked statements

Lo stato di assegnazione definito di v nel controllo viene trasferito alla prima istruzione dell'elenco di istruzioni nel blocco (o al punto finale del blocco, se l'elenco di istruzioni è vuoto) equivale all'istruzione di assegnazione definita di v prima del blocco istruzione checked, o 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.

Istruzioni di espressioneExpression statements

Per un'istruzione di espressione stmt costituita dall'espressione expr:For an expression statement stmt that consists of the expression expr:

  • v ha lo stesso stato di assegnazione definita all'inizio di expr come all'inizio di stmt.v has the same definite assignment state at the beginning of expr as at the beginning of stmt.
  • Se v viene assegnato definitivamente alla fine di expr, viene assegnato definitivamente al punto finale di stmt; in caso contrario non viene assegnato definitivamente al punto finale di 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.

Istruzioni di dichiarazioneDeclaration statements

  • Se stmt è un'istruzione di dichiarazione senza inizializzatori, v ha lo stesso stato di assegnazione definito al punto finale di stmt come all'inizio di 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 è un'istruzione di dichiarazione con inizializzatori, lo stato di assegnazione definito per v viene determinato come se stmt fosse un elenco di istruzioni, con un'istruzione di assegnazione per ogni dichiarazione con un inizializzatore (nell'ordine di Dichiarazione).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).

Istruzioni IfIf statements

Per un' if istruzione stmt nel formato:For an if statement stmt of the form:

if ( expr ) then_stmt else else_stmt
  • v ha lo stesso stato di assegnazione definita all'inizio di expr come all'inizio di stmt.v has the same definite assignment state at the beginning of expr as at the beginning of stmt.
  • Se la v viene assegnata definitivamente alla fine di expr, viene definitivamente assegnata al trasferimento del flusso di controllo a then_stmt e a else_stmt o all'endpoint di stmt se non è presente alcuna clausola 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 ha lo stato "assegnato definitivamente dopo l'espressione true" alla fine di expr, viene definitivamente assegnato al trasferimento del flusso di controllo a then_stmte non è assegnato definitivamente al trasferimento del flusso di controllo a else_ stmt o all'endpoint di stmt se non è presente alcuna clausola 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 ha lo stato "assegnata in modo definitivo dopo false Expression" alla fine di expr, viene definitivamente assegnato al trasferimento del flusso di controllo a else_stmte non assegnato definitivamente al trasferimento del flusso di controllo a 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. Viene assegnato in modo sicuro all'endpoint di stmt , se e solo se viene assegnato definitivamente all'endpoint di 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.
  • In caso contrario, v viene considerato non assegnato definitivamente al trasferimento del flusso di controllo a then_stmt o else_stmtoppure all'endpoint di stmt se non è presente alcuna clausola 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.

Istruzioni switchSwitch statements

In un' switch istruzione stmt con un'espressione di controllo expr:In a switch statement stmt with a controlling expression expr:

  • Lo stato di assegnazione definito di v all'inizio di expr corrisponde allo stato di v all'inizio di 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.
  • Lo stato di assegnazione definito di v nel trasferimento del flusso di controllo a un elenco di istruzioni switch Block raggiungibili è identico allo stato di assegnazione definito di v alla fine di 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.

Istruzioni whileWhile statements

Per un' while istruzione stmt nel formato:For a while statement stmt of the form:

while ( expr ) while_body
  • v ha lo stesso stato di assegnazione definita all'inizio di expr come all'inizio di stmt.v has the same definite assignment state at the beginning of expr as at the beginning of stmt.
  • Se la v viene assegnata definitivamente alla fine di expr, viene definitivamente assegnata al trasferimento del flusso di controllo a while_body e al punto finale di 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 ha lo stato "assegnato definitivamente dopo l'espressione true" alla fine di expr, viene definitivamente assegnato al trasferimento del flusso di controllo a while_body, ma non assegnato definitivamente all'endpoint di 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 ha lo stato "assegnata in modo definitivo dopo false Expression" alla fine di expr, viene definitivamente assegnato nel trasferimento del flusso di controllo al punto finale di stmt, ma non è stato assegnato in modo definitivo sul trasferimento del flusso di controllo a 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.

Istruzioni doDo statements

Per un' do istruzione stmt nel formato:For a do statement stmt of the form:

do do_body while ( expr ) ;
  • v ha lo stesso stato di assegnazione definito nel trasferimento del flusso di controllo dall'inizio di stmt a do_body come all'inizio di 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 ha lo stesso stato di assegnazione definita all'inizio di expr come nel punto finale di do_body.v has the same definite assignment state at the beginning of expr as at the end point of do_body.
  • Se la v viene assegnata definitivamente alla fine di expr, viene definitivamente assegnata al punto finale di stmtnel trasferimento del flusso di controllo.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 ha lo stato "definitely Assigned after false Expression" alla fine di expr, viene assegnato definitivamente nel trasferimento del flusso di controllo al punto finale di 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.

Istruzioni forFor statements

Controllo di assegnazione definito per for un'istruzione nel formato:Definite assignment checking for a for statement of the form:

for ( for_initializer ; for_condition ; for_iterator ) embedded_statement

viene eseguita come se l'istruzione fosse scritta:is done as if the statement were written:

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

Se for_condition viene omesso dall' for istruzione, la valutazione dell'assegnazione definita procede come se for_condition venisse sostituito con true nell'espansione precedente.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.

Istruzioni break, continue e GOTOBreak, continue, and goto statements

Lo stato di assegnazione definito di v nel trasferimento del flusso di controllo causato breakda un'istruzione goto , continueo equivale allo stato di assegnazione definito di v all'inizio dell'istruzione.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.

Istruzioni throwThrow statements

Per un'istruzione stmt nel formatoFor a statement stmt of the form

throw expr ;

Lo stato di assegnazione definito di v all'inizio di expr corrisponde allo stato di assegnazione definito di v all'inizio di 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.

Istruzioni returnReturn statements

Per un'istruzione stmt nel formatoFor a statement stmt of the form

return expr ;
  • Lo stato di assegnazione definito di v all'inizio di expr corrisponde allo stato di assegnazione definito di v all'inizio di 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 è un parametro di output, è necessario che sia assegnato definitivamente quanto segue:If v is an output parameter, then it must be definitely assigned either:
    • dopo exprafter expr
    • o alla fine del finally blocco di un oggetto try - ocheracchiudereturn l'istruzione. catch try - finally - finallyor at the end of the finally block of a try-finally or try-catch-finally that encloses the return statement.

Per un'istruzione stmt nel formato:For a statement stmt of the form:

return ;
  • Se v è un parametro di output, è necessario che sia assegnato definitivamente quanto segue:If v is an output parameter, then it must be definitely assigned either:
    • prima di stmtbefore stmt
    • o alla fine del finally blocco di un oggetto try - ocheracchiudereturn l'istruzione. catch try - finally - finallyor at the end of the finally block of a try-finally or try-catch-finally that encloses the return statement.

Istruzioni try-catchTry-catch statements

Per un'istruzione stmt nel formato:For a statement stmt of the form:

try try_block
catch(...) catch_block_1
...
catch(...) catch_block_n
  • Lo stato di assegnazione definito di v all'inizio di try_block è lo stesso dello stato di assegnazione definito di v all'inizio di 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.
  • Lo stato di assegnazione definito di v all'inizio di catch_block_i (per qualsiasi i) corrisponde allo stato di assegnazione definito di v all'inizio di 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.
  • Lo stato di assegnazione definito di v all'endpoint di stmt viene assegnato definitivamente se (e solo se) v viene assegnato definitivamente all'endpoint di try_block e ogni catch_block_i (per ogni i da 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).

Istruzioni try-finallyTry-finally statements

Per un' try istruzione stmt nel formato:For a try statement stmt of the form:

try try_block finally finally_block
  • Lo stato di assegnazione definito di v all'inizio di try_block è lo stesso dello stato di assegnazione definito di v all'inizio di 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.
  • Lo stato di assegnazione definito di v all'inizio di finally_block è lo stesso dello stato di assegnazione definito di v all'inizio di 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.
  • Lo stato di assegnazione definito di v all'endpoint di stmt viene assegnato definitivamente se (e solo se) viene soddisfatta almeno una delle condizioni seguenti: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:
    • v viene assegnato definitivamente all'endpoint di try_blockv is definitely assigned at the end-point of try_block
    • v viene assegnato definitivamente all'endpoint di finally_blockv is definitely assigned at the end-point of finally_block

Se viene eseguito il trasferimento di un flusso di controllo goto (ad esempio, un'istruzione) che inizia all'interno di try_blocke termina all'esterno di try_block, v viene anche considerato definitivamente assegnato a tale trasferimento del flusso di controllo se v è assegnato definitivamente all'endpoint di 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. (Non si tratta di un solo se, se v è assegnato definitivamente per un altro motivo in questo trasferimento del flusso di controllo, viene comunque considerato assegnato definitivamente).(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.)

Istruzioni try-catch-finallyTry-catch-finally statements

Analisi di assegnazione definita per try un' - catch - istruzione nelformato:finallyDefinite 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*

viene eseguita come se l'istruzione fosse un' try - try - finally istruzione che include un' catch istruzione: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

Nell'esempio seguente viene illustrato il modo in cui i try diversi blocchi di un'istruzione (istruzione try) influiscono sull'assegnazione definita.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

    }
}

Istruzioni foreachForeach statements

Per un' foreach istruzione stmt nel formato:For a foreach statement stmt of the form:

foreach ( type identifier in expr ) embedded_statement
  • Lo stato di assegnazione definito di v all'inizio di expr corrisponde allo stato di v all'inizio di 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.
  • Lo stato di assegnazione definito di v nel trasferimento del flusso di controllo a embedded_statement o al punto finale di stmt è uguale allo stato di v alla fine di 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.

Istruzioni usingUsing statements

Per un' using istruzione stmt nel formato:For a using statement stmt of the form:

using ( resource_acquisition ) embedded_statement
  • Lo stato di assegnazione definito di v all'inizio di resource_acquisition è uguale allo stato di v all'inizio di 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.
  • Lo stato di assegnazione definito di v nel trasferimento del flusso di controllo a embedded_statement è lo stesso dello stato v alla fine di 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.

Istruzioni lockLock statements

Per un' lock istruzione stmt nel formato:For a lock statement stmt of the form:

lock ( expr ) embedded_statement
  • Lo stato di assegnazione definito di v all'inizio di expr corrisponde allo stato di v all'inizio di 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.
  • Lo stato di assegnazione definito di v nel trasferimento del flusso di controllo a embedded_statement corrisponde allo stato di v alla fine di 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.

Istruzioni yieldYield statements

Per un' yield return istruzione stmt nel formato:For a yield return statement stmt of the form:

yield return expr ;
  • Lo stato di assegnazione definito di v all'inizio di expr corrisponde allo stato di v all'inizio di 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.
  • Lo stato di assegnazione definito di v alla fine di stmt è uguale a quello di v alla fine di 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.
  • Un' yield break istruzione non ha alcun effetto sullo stato di assegnazione definito.A yield break statement has no effect on the definite assignment state.

Regole generali per le espressioni sempliciGeneral rules for simple expressions

La regola seguente si applica a questi tipi di espressioni: i valori letterali (valori letterali), i nomi semplici (nomi semplici), le espressioni di accesso ai membri (accesso ai membri), le espressioni di accesso di base non indicizzate (accesso di base), typeofespressioni (operatore typeof), espressioni con valore predefinito (espressioni con valore predefinito) nameof ed espressioni (espressioni 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).

  • Lo stato di assegnazione definito di v alla fine di tale espressione corrisponde allo stato di assegnazione definito di v all'inizio dell'espressione.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.

Regole generali per le espressioni con espressioni incorporateGeneral rules for expressions with embedded expressions

Le regole seguenti si applicano a questi tipi di espressioni: espressioni tra parentesi (espressioni racchiuse tra parentesi), espressioni di accesso agli elementi (accesso agli elementi), espressioni di accesso di base con indicizzazione (accesso di base), incremento e espressioni di decremento (operatori di incremento e decremento suffisso, operatori di incremento e decremento di prefisso), espressioni cast (espressioni cast), unario +, -, ~, * espressioni, Binary +, -, *, /, %, <<, >>, <, <=, >, >=, ==, !=, is, as, &, |, ^ espressioni (operatori aritmetici, operatori Shift, relazionali e test di tipo operatori, operatori logici), espressioni di assegnazione composta (assegnazione composta), checked ed unchecked espressioni (operatori checked e unchecked), più matrici e Delegate espressioni di creazione (nuovo operatore).The 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).

Ognuna di queste espressioni ha una o più sottoespressioni che vengono valutate in modo non condizionale in un ordine fisso.Each of these expressions has one or more sub-expressions that are unconditionally evaluated in a fixed order. Ad esempio, l'operatore % binario valuta il lato sinistro dell'operatore, quindi la parte destra.For example, the binary % operator evaluates the left hand side of the operator, then the right hand side. Un'operazione di indicizzazione valuta l'espressione indicizzata, quindi valuta ognuna delle espressioni di indice, in ordine da sinistra a destra.An indexing operation evaluates the indexed expression, and then evaluates each of the index expressions, in order from left to right. Per un'espressione expr, che include sottoespressioni E1, E2,..., en, valutate nell'ordine seguente:For an expression expr, which has sub-expressions e1, e2, ..., eN, evaluated in that order:

  • Lo stato di assegnazione definito di v all'inizio di E1 corrisponde allo stato di assegnazione definito all'inizio di 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.
  • Lo stato di assegnazione definito di v all'inizio di ei (maggiore di uno) corrisponde allo stato di assegnazione definito alla fine della sottoespressione precedente.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.
  • Lo stato di assegnazione definito di v alla fine di expr corrisponde allo stato di assegnazione definito alla fine di enThe definite assignment state of v at the end of expr is the same as the definite assignment state at the end of eN

Espressioni di chiamata ed espressioni di creazione di oggettiInvocation expressions and object creation expressions

Per un'espressione di chiamata expr nel formato:For an invocation expression expr of the form:

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

o un'espressione di creazione di oggetti nel formato seguente:or an object creation expression of the form:

new type ( arg1 , arg2 , ... , argN )
  • Per un'espressione di chiamata, lo stato di assegnazione definito di v prima di primary_expression è lo stesso dello stato v prima di expr.For an invocation expression, the definite assignment state of v before primary_expression is the same as the state of v before expr.
  • Per un'espressione di chiamata, lo stato di assegnazione definito di v prima di arg1 è lo stesso dello stato v dopo 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.
  • Per un'espressione di creazione di un oggetto, lo stato di assegnazione definito di v prima di arg1 è lo stesso dello stato v prima di expr.For an object creation expression, the definite assignment state of v before arg1 is the same as the state of v before expr.
  • Per ogni argomento Argi, lo stato di assegnazione definito di v dopo Argi è determinato dalle regole di espressione normali, ignorando ref eventuali out modificatori o.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.
  • Per ogni argomento Argi per i maggiori di uno, lo stato di assegnazione definito di v prima di Argi è lo stesso dello stato v dopo l' argprecedente.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 la variabile v out viene passata come argomento (ad esempio, un argomento del out vform) in uno degli argomenti, lo stato di v dopo expr viene assegnato 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. In caso contrario lo stato v dopo expr corrisponde allo stato di v dopo argN.Otherwise; the state of v after expr is the same as the state of v after argN.
  • Per gli inizializzatori di matrice (espressioni di creazione di matrici), inizializzatori di oggetto (inizializzatori di oggetto), inizializzatori di insieme (inizializzatori di insieme) e inizializzatori di oggetti anonimi (creazione dioggetti anonimi espressioni), lo stato di assegnazione definito è determinato dall'espansione che questi costrutti sono definiti in termini di.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.

Espressioni di assegnazione sempliciSimple assignment expressions

Per un'espressione expr nel formato w = expr_rhs:For an expression expr of the form w = expr_rhs:

  • Lo stato di assegnazione definito di v prima di expr_rhs è lo stesso dello stato di assegnazione definito di v prima di expr.The definite assignment state of v before expr_rhs is the same as the definite assignment state of v before expr.
  • Lo stato di assegnazione definito di v dopo expr è determinato da:The definite assignment state of v after expr is determined by:
    • Se w è la stessa variabile di v, lo stato di assegnazione definito di v dopo expr viene assegnato definitivamente.If w is the same variable as v, then the definite assignment state of v after expr is definitely assigned.
    • In caso contrario, se l'assegnazione si verifica all'interno del costruttore di istanza di un tipo struct, se w è un accesso alla proprietà che designa una proprietà implementata automaticamente P nell'istanza da costruire e v è il campo sottostante nascosto di P, lo stato di assegnazione definito di v dopo expr viene assegnato 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.
    • In caso contrario, lo stato di assegnazione definito di v dopo expr corrisponde allo stato di assegnazione definito di v dopo expr_rhs.Otherwise, the definite assignment state of v after expr is the same as the definite assignment state of v after expr_rhs.

espressioni & & (condizionale e)&& (conditional AND) expressions

Per un'espressione expr nel formato expr_first && expr_second:For an expression expr of the form expr_first && expr_second:

  • Lo stato di assegnazione definito di v prima di expr_first è lo stesso dello stato di assegnazione definito di v prima di expr.The definite assignment state of v before expr_first is the same as the definite assignment state of v before expr.
  • Lo stato di assegnazione definito di v prima di expr_second viene assegnato definitivamente se lo stato di v dopo expr_first è definitivamente assegnato o "assegnato definitivamente dopo l'espressione true".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". In caso contrario, non viene assegnato definitivamente.Otherwise, it is not definitely assigned.
  • Lo stato di assegnazione definito di v dopo expr è determinato da:The definite assignment state of v after expr is determined by:
    • Se expr_first è un'espressione costante con il valore false, lo stato di assegnazione definito di v dopo expr corrisponde allo stato di assegnazione definito di v dopo 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.
    • In caso contrario, se lo stato di v dopo expr_first è assegnato definitivamente, lo stato di v dopo expr viene assegnato definitivamente.Otherwise, if the state of v after expr_first is definitely assigned, then the state of v after expr is definitely assigned.
    • In caso contrario, se lo stato di v dopo expr_second è assegnato definitivamente e lo stato di v dopo expr_first è "definitivamente assegnato dopo false Expression", lo stato di v dopo expr è sicuramente assegnato.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.
    • In caso contrario, se lo stato di v dopo expr_second è assegnato definitivamente o "assegnato definitivamente dopo l'espressione true", lo stato di v dopo expr è "definitely Assigned after true Expression".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".
    • In caso contrario, se lo stato di v dopo expr_first è "definitely Assigned after false Expression" e lo stato di v dopo expr_second è "definitely Assigned after false Expression", lo stato di v dopo expr è "assegnato definitivamente dopo false Expression".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".
    • In caso contrario, lo stato di v dopo expr non viene assegnato definitivamente.Otherwise, the state of v after expr is not definitely assigned.

Nell'esempioIn 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
    }
}

la variabile i viene considerata definitivamente assegnata in una delle istruzioni incorporate di if un'istruzione ma non nell'altra.the variable i is considered definitely assigned in one of the embedded statements of an if statement but not in the other. Nell'istruzione nel metodo F, la variabile i viene assegnata definitivamente nella prima istruzione incorporata perché l'esecuzione dell'espressione (i = y) precede sempre l'esecuzione di questa istruzione incorporata. ifIn 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. Al contrario, la variabile i non viene assegnata definitivamente nella seconda istruzione incorporata, x >= 0 perché potrebbe avere testato false, causando la i mancata assegnazione della variabile.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.

|| espressioni (condizionali o)|| (conditional OR) expressions

Per un'espressione expr nel formato expr_first || expr_second:For an expression expr of the form expr_first || expr_second:

  • Lo stato di assegnazione definito di v prima di expr_first è lo stesso dello stato di assegnazione definito di v prima di expr.The definite assignment state of v before expr_first is the same as the definite assignment state of v before expr.
  • Lo stato di assegnazione definito di v prima di expr_second viene assegnato definitivamente se lo stato di v dopo expr_first è definitivamente assegnato o "assegnato definitivamente dopo false Expression".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". In caso contrario, non viene assegnato definitivamente.Otherwise, it is not definitely assigned.
  • L'istruzione di assegnazione definita di v dopo expr è determinata da:The definite assignment statement of v after expr is determined by:
    • Se expr_first è un'espressione costante con il valore true, lo stato di assegnazione definito di v dopo expr corrisponde allo stato di assegnazione definito di v dopo 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.
    • In caso contrario, se lo stato di v dopo expr_first è assegnato definitivamente, lo stato di v dopo expr viene assegnato definitivamente.Otherwise, if the state of v after expr_first is definitely assigned, then the state of v after expr is definitely assigned.
    • In caso contrario, se lo stato di v dopo expr_second è assegnato definitivamente e lo stato di v dopo expr_first è "definitivamente assegnato dopo l'espressione true", lo stato di v dopo expr è sicuramente assegnato.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.
    • In caso contrario, se lo stato di v dopo expr_second è assegnato definitivamente o "assegnato definitivamente dopo false Expression", lo stato di v dopo expr sarà "definitely Assigned after false Expression".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".
    • In caso contrario, se lo stato di v dopo expr_first è "assegnato definitivamente dopo l'espressione true" e lo stato di v dopo expr_second è "definitivamente assegnato dopo l'espressione true", lo stato di v dopo expr è "assegnato definitivamente dopo l'espressione true".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".
    • In caso contrario, lo stato di v dopo expr non viene assegnato definitivamente.Otherwise, the state of v after expr is not definitely assigned.

Nell'esempioIn 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
    }
}

la variabile i viene considerata definitivamente assegnata in una delle istruzioni incorporate di if un'istruzione ma non nell'altra.the variable i is considered definitely assigned in one of the embedded statements of an if statement but not in the other. Nell'istruzione nel metodo G, la variabile i viene assegnata definitivamente nella seconda istruzione incorporata perché l'esecuzione dell'espressione (i = y) precede sempre l'esecuzione di questa istruzione incorporata. ifIn 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. Al contrario, la variabile i non viene assegnata definitivamente nella prima istruzione incorporata, x >= 0 perché potrebbe avere testato true, causando la i mancata assegnazione della variabile.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.

!! espressioni (negazione logica)(logical negation) expressions

Per un'espressione expr nel formato ! expr_operand:For an expression expr of the form ! expr_operand:

  • Lo stato di assegnazione definito di v prima di expr_operand è lo stesso dello stato di assegnazione definito di v prima di expr.The definite assignment state of v before expr_operand is the same as the definite assignment state of v before expr.
  • Lo stato di assegnazione definito di v dopo expr è determinato da:The definite assignment state of v after expr is determined by:
    • Se lo stato di v after * expr_operand * viene assegnato definitivamente, lo stato di v dopo expr viene assegnato definitivamente.If the state of v after *expr_operand *is definitely assigned, then the state of v after expr is definitely assigned.
    • Se lo stato di v after * expr_operand * non è assegnato definitivamente, lo stato di v dopo expr non viene assegnato 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 lo stato di v after * expr_operand * è "definitely Assigned after false Expression", lo stato di v after expr è "definitely Assigned after true Expression".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 lo stato di v after * expr_operand * è "assegnato definitivamente dopo l'espressione true", lo stato di v dopo expr è "definitely Assigned after false Expression".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".

???? espressioni (Unione di valori null)(null coalescing) expressions

Per un'espressione expr nel formato expr_first ?? expr_second:For an expression expr of the form expr_first ?? expr_second:

  • Lo stato di assegnazione definito di v prima di expr_first è lo stesso dello stato di assegnazione definito di v prima di expr.The definite assignment state of v before expr_first is the same as the definite assignment state of v before expr.
  • Lo stato di assegnazione definito di v prima di expr_second è lo stesso dello stato di assegnazione definito di v dopo expr_first.The definite assignment state of v before expr_second is the same as the definite assignment state of v after expr_first.
  • L'istruzione di assegnazione definita di v dopo expr è determinata da:The definite assignment statement of v after expr is determined by:
    • Se expr_first è un'espressione costante (espressioni costanti) con valore null, lo stato di v dopo expr sarà lo stesso dello stato v dopo 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.
  • In caso contrario, lo stato di v dopo expr corrisponde allo stato di assegnazione definito di v dopo expr_first.Otherwise, the state of v after expr is the same as the definite assignment state of v after expr_first.

espressioni?: (condizionale)?: (conditional) expressions

Per un'espressione expr nel formato expr_cond ? expr_true : expr_false:For an expression expr of the form expr_cond ? expr_true : expr_false:

  • Lo stato di assegnazione definito di v prima di expr_cond è uguale allo stato di v prima di expr.The definite assignment state of v before expr_cond is the same as the state of v before expr.
  • Lo stato di assegnazione definito di v prima di expr_true viene assegnato definitivamente se e solo se uno degli elementi seguenti include:The definite assignment state of v before expr_true is definitely assigned if and only if one of the following holds:
    • expr_cond è un'espressione costante con il valorefalseexpr_cond is a constant expression with the value false
    • lo stato di v dopo expr_cond è assegnato definitivamente o "assegnato definitivamente dopo l'espressione true".the state of v after expr_cond is definitely assigned or "definitely assigned after true expression".
  • Lo stato di assegnazione definito di v prima di expr_false viene assegnato definitivamente se e solo se uno degli elementi seguenti include:The definite assignment state of v before expr_false is definitely assigned if and only if one of the following holds:
    • expr_cond è un'espressione costante con il valoretrueexpr_cond is a constant expression with the value true
  • lo stato di v dopo expr_cond è assegnato definitivamente o "assegnato definitivamente dopo false Expression".the state of v after expr_cond is definitely assigned or "definitely assigned after false expression".
  • Lo stato di assegnazione definito di v dopo expr è determinato da:The definite assignment state of v after expr is determined by:
    • Se expr_cond è un'espressione costante (espressioni costanti) con valore true , lo stato di v dopo expr sarà lo stesso dello stato v dopo 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.
    • In caso contrario, se expr_cond è un'espressione costante (espressioni costanti) false con valore, lo stato di v dopo expr sarà lo stesso dello stato v dopo 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.
    • In caso contrario, se lo stato di v dopo expr_true è assegnato definitivamente e lo stato di v dopo expr_false è definitivamente assegnato, lo stato di v dopo expr viene assegnato 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.
    • In caso contrario, lo stato di v dopo expr non viene assegnato definitivamente.Otherwise, the state of v after expr is not definitely assigned.

Funzioni anonimeAnonymous functions

Per lambda_expression o anonymous_method_expression expr con corpo ( blocco o espressione):For a lambda_expression or anonymous_method_expression expr with a body (either block or expression) body:

  • Lo stato di assegnazione definito di una variabile esterna v before Body corrisponde allo stato di v prima di expr.The definite assignment state of an outer variable v before body is the same as the state of v before expr. Ovvero lo stato di assegnazione definito delle variabili esterne viene ereditato dal contesto della funzione anonima.That is, definite assignment state of outer variables is inherited from the context of the anonymous function.
  • Lo stato di assegnazione definito di una variabile esterna v dopo expr è identico a quello di v prima di expr.The definite assignment state of an outer variable v after expr is the same as the state of v before expr.

EsempioThe 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);
}

genera un errore in fase di compilazione max perché non è assegnato definitivamente quando viene dichiarata la funzione anonima.generates a compile-time error since max is not definitely assigned where the anonymous function is declared. EsempioThe example

delegate void D();

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

    d();

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

genera inoltre un errore in fase di compilazione perché l'assegnazione n a nella funzione anonima non ha alcun effetto sullo stato di n assegnazione definito all'esterno della funzione anonima.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.

Riferimenti a variabiliVariable references

Un variable_reference è un' espressione classificata come variabile.A variable_reference is an expression that is classified as a variable. Un variable_reference indica un percorso di archiviazione a cui è possibile accedere sia per recuperare il valore corrente sia per archiviare un nuovo valore.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
    ;

In C e C++un variable_reference è noto come lvalue.In C and C++, a variable_reference is known as an lvalue.

Atomicità dei riferimenti a variabiliAtomicity of variable references

Le letture e le scritture dei tipi di dati seguenti boolsono charatomiche sbyte: short byte,,, int, float, ushort, uint,, e tipi di riferimento.Reads and writes of the following data types are atomic: bool, char, byte, sbyte, short, ushort, uint, int, float, and reference types. Inoltre, le letture e le scritture dei tipi enum con un tipo sottostante nell'elenco precedente sono anche atomiche.In addition, reads and writes of enum types with an underlying type in the previous list are also atomic. Le letture e le scritture di altri longtipi ulong, tra cui decimal,, doublee, nonché i tipi definiti dall'utente, non sono necessariamente atomiche.Reads and writes of other types, including long, ulong, double, and decimal, as well as user-defined types, are not guaranteed to be atomic. Oltre alle funzioni di libreria progettate a tale scopo, non esiste alcuna garanzia di Atomic read-modify-write, ad esempio in caso di incremento o decremento.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.