Unlicensed-425-428_7-PDF_C# Programming Language, The, 4th

advertisement
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
Download