8.5 Statements n n ERIC LIPPERT Declaration For example, the finally block might always throw an exception, in which case there would be a reachable goto targeting a potentially unreachable label. n n PETER SESToFT See also the annotations in the discussion of the goto statement in §8.9.3. 8.5 Declaration Statements A declaration-statement declares a local variable or constant. Declaration statements are permitted in blocks, but are not permitted as embedded statements. declaration-statement: local-variable-declaration local-constant-declaration ; ; 8.5.1 Local Variable Declarations A local-variable-declaration declares one or more local variables. local-variable-declaration: local-variable-type local-variable-declarators local-variable-type: type var local-variable-declarators: local-variable-declarator local-variable-declarators , local-variable-declarator local-variable-declarator: identifier identifier = local-variable-initializer local-variable-initializer: expression array-initializer 407 www.it-ebooks.info 8. Statements The local-variable-type of a local-variable-declaration either directly specifies the type of the variables introduced by the declaration, or indicates with the identifier var that the type should be inferred based on an initializer. The type is followed by a list of local-variabledeclarators, each of which introduces a new variable. A local-variable-declarator consists of an identifier that names the variable, optionally followed by an "=" token and a local-variableinitializer that gives the initial value of the variable. St a t e m e n t s In the context of a local variable declaration, the identifier var acts as a contextual keyword (§2.4.3).When the local-variable-type is specified as var and no type named var is in scope, the declaration is an implicitly typed local variable declaration, whose type is inferred from the type of the associated initializer expression. Implicitly typed local variable declarations are subject to the following restrictions: • • The local-variable-declaration cannot include multiple local-variable-declarators. • The local-variable-initializer must be an expression. • The initializer expression must have a compile-time type. • The initializer expression cannot refer to the declared variable itself. 8. The local-variable-declarator must include a local-variable-initializer. n n ERIC LIPPERT In an early design for this feature, it was legal to have multiple declarators. var a = 1, b = 2.5; When C# developers were shown this code, roughly half said that it should have the same semantics as double a = 1, b = 2.5; The other half said that it should have the same semantics as int a = 1; double b = 2.5; Both sides thought that their interpretation was the "obviously correct" one. When faced with a syntax that admits two incompatible "obviously correct" interpretations, often the best thing to do is to disallow the syntax entirely rather than to breed confusion. n n CHRIS SELLS I think multiple variable declarations in the same statement just to 8. 408 St a t e m e n t s reuse the type name should be illegal, too. www.it-ebooks.info 8.5 Statements ERIC LIPPERT n n Declaration This constraint stands in contrast to an explicitly typed local vari- able declaration, which does permit an initializer to reference itself. For example, int j = M(out j); is strange, but legal. If this expression were var j = M(out j), then overload resolution could not determine the type returned by M, and hence the type of j, until the type of the argument was known. Of course, the type of the argument is exactly what we are trying to determine. Rather than attempting to solve this "chicken and egg" problem, the language specification simply makes this case illegal. The following are examples of incorrect implicitly typed local variable declarations: var var var var var x; y z u v = = = = {1, 2, 3}; null; x => x + 1; v++; // // // // // Error: Error: Error: Error: Error: no initializer to infer type from array initializer not permitted null does not have a type anonymous functions do not have a type initializer cannot refer to variable itself The value of a local variable is obtained in an expression using a simple-name (§7.6.2), and the value of a local variable is modified using an assignment (§7.17). A local variable must be definitely assigned (§5.3) at each location where its value is obtained. n n CHRIS SELLS I really love implicitly typed local variable declarations when the type is anonymous (in which case, you have to use them) or when the type of the variable is made explicit as part of the statement that initializes it, but not because you're too lazy to type! For example: var var var var a b v d = = = = new { Name = "Bob", Age = 42 }; // Good 1; // Good new Person(); // Good GetPerson(); // BAD! The compiler is perfectly happy with d as an implicitly typed variable, but pity the poor human reader! 409 www.it-ebooks.info 8. Statements n n ERIC LIPPERT I generally agree with the annotation above but would make n n St a t e m e n t s one additional point: var works well when the writer of the code is attempting to communicate "the storage type of this variable is unimportant; what is important is the meaning of the variable, not its implementation details." For example, I'll often write code like "var attributes = ParseMethodAttributes(); "—I am saying here that it doesn't matter whether what comes back is AttributeSyntax[] or List<AttributeSyntax>. What matters is that the collection of attributes has been parsed. BILL WAGNER I freely admit to being guilty of using var extensively. In fact, my 8. habit is to use implicitly typed variables for almost everything except simple types. I find that it's much more important to have a semantic understanding of a variable rather than a syntactic understanding of a variable. In Chris's example, GetPerson() would logically return a Person, or an IPerson, or something derived from Person or from implementing IPerson. In all those cases, I'm fine with that bit of ambiguity. I understand the concept of "a variable that represents something person-like" without knowing its exact type. The scope of a local variable declared in a local-variable-declaration is the block in which the declaration occurs. It is an error to refer to a local variable in a textual position that precedes the local-variable-declarator of the local variable. Within the scope of a local variable, it is a compile-time error to declare another local variable or constant with the same name. A local variable declaration that declares multiple variables is equivalent to multiple declarations of single variables with the same type. Furthermore, a variable initializer in a local variable declaration corresponds exactly to an assignment statement that is inserted immediately after the declaration. St a t e m e n t s The example void F() { int x = 1, y, z = x * 2; } 410 { x; x = 1; y; z; z = x * 2; St a t e m e n t s void F() int int int } 8. corresponds exactly to www.it-ebooks.info