43 lines
2.1 KiB
XML
Raw Normal View History

<?xml version="1.0"?>
<clause number="14.5.2.1" title="Invariant meaning in blocks">
<paragraph>For each occurrence of a given identifier as a <non_terminal where="14.5.2">simple-name</non_terminal> in an expression, every other occurrence of the same identifier as a <non_terminal where="14.5.2">simple-name</non_terminal> in an expression within the immediately enclosing block (<hyperlink>15.2</hyperlink>) or <non_terminal where="15.7.2">switch-block</non_terminal> (<hyperlink>15.7.2</hyperlink>) must refer to the same entity. This rule ensures that the meaning of a name in the context of an expression is always the same within a block. </paragraph>
<paragraph>The example <code_example><![CDATA[
class Test
{
double x;
void F(bool b) {
x = 1.0;
if (b) {
int x = 1;
}
}
}
]]></code_example>results in a compile-time error because x refers to different entities within the outer block (the extent of which includes the nested block in the if statement). In contrast, the example <code_example><![CDATA[
class Test
{
double x;
void F(bool b) {
if (b) {
x = 1.0;
}
else {
int x = 1;
}
}
}
]]></code_example>is permitted because the name x is never used in the outer block. </paragraph>
<paragraph>Note that the rule of invariant meaning applies only to simple names. It is perfectly valid for the same identifier to have one meaning as a simple name and another meaning as right operand of a member access (<hyperlink>14.5.4</hyperlink>). <example>[Example: For example: <code_example><![CDATA[
struct Point
{
int x, y;
public Point(int x, int y) {
this.x = x;
this.y = y;
}
}
]]></code_example></example></paragraph>
<paragraph>
<example>The example above illustrates a common pattern of using the names of fields as parameter names in an instance constructor. In the example, the simple names x and y refer to the parameters, but that does not prevent the member access expressions this.x and this.y from accessing the fields. end example]</example>
</paragraph>
</clause>