Scope of Declarations

You have seen declarations of various C# entities, such as classes, methods, properties, variables and parameters. Declarations introduce names that can be used to refer to such C# entities. The scope of a declaration is the portion of the application that can refer to the declared entity by its unqualified name. Such an entity is said to be "in scope" for that portion of the application. This section introduces several important scope issues. For more scope information, see Section 3.7, Scopes, of the C# Language Specification.

The basic scope rules are as follows:

  1. The scope of a parameter declaration is the body of the method in which the declaration appears.
  2. The scope of a local-variable declaration is from the point at which the declaration appears to the end of the block containing the declaration.
  3. The scope of a local-variable declaration that appears in the initialization section of a for statement's header is the body of the for statement and the other expressions in the header.
  4. The scope of a method, property or field of a class is the entire body of the class. This enables non-static methods and properties of a class to use any of the class's fields, methods and properties, regardless of the order in which they are declared. Similarly, static methods and properties can use any of the static members of the class.

Any block may contain variable declarations. If a local variable or parameter in a method has the same name as a field, the field is hidden until the block terminates execution. In Chapter 9, we discuss how to access hidden fields.

Error Prevention Tip 7 3

Use different names for fields and local variables to help prevent subtle logic errors that occur when a method is called and a local variable of the method hides a field of the same name in the class.

The application in Fig. 7.11 and Fig. 7.12 demonstrates scoping issues with fields and local variables. When the application begins execution, class ScopeTest's Main method (Fig. 7.12, lines 610) creates an object of class Scope (line 8) and calls the object's Begin method (line 9) to produce the application's output (shown in Fig. 7.12).

Figure 7.11. Scope class demonstrates instance and local variable scopes.

(This item is displayed on pages 299 - 300 in the print version)

1 // Fig. 7.11: Scope.cs 2 // Scope class demonstrates instance and local variable scopes. 3 using System; 4 5 public class Scope 6 { 7 // instance variable that is accessible to all methods of this class 8 private int x = 1; 9 10 // method Begin creates and initializes local variable x 11 // and calls methods UseLocalVariable and UseInstanceVariable 12 public void Begin() 13 { 14 int x = 5; // method's local variable x hides instance variable x 15 16 Console.WriteLine( "local x in method Begin is {0}", x ); 17 18 // UseLocalVariable has its own local x 19 UseLocalVariable(); 20 21 // UseInstanceVariable uses class Scope's instance variable x 22 UseInstanceVariable(); 23 24 // UseLocalVariable reinitializes its own local x 25 UseLocalVariable(); 26 27 // class Scope's instance variable x retains its value 28 UseInstanceVariable(); 29 30 Console.WriteLine( " local x in method Begin is {0}", x ); 31 } // end method Begin 32 33 // create and initialize local variable x during each call 34 public void UseLocalVariable() 35 { 36 int x = 25; // initialized each time UseLocalVariable is called 37 38 Console.WriteLine( 39 " local x on entering method UseLocalVariable is {0}", x ); 40 x++; // modifies this method's local variable x 41 Console.WriteLine( 42 "local x before exiting method UseLocalVariable is {0}", x ); 43 } // end method UseLocalVariable 44 45 // modify class Scope's instance variable x during each call 46 public void UseInstanceVariable() 47 { 48 Console.WriteLine( " instance variable x on entering {0} is {1}", 49 "method UseInstanceVariable", x ); 50 x *= 10; // modifies class Scope's instance variable x 51 Console.WriteLine( "instance variable x before exiting {0} is {1}", 52 "method UseInstanceVariable", x ); 53 } // end method UseInstanceVariable 54 } // end class Scope

Figure 7.12. Application to test class Scope.

(This item is displayed on page 300 in the print version)

1 // Fig. 7.12: ScopeTest.cs 2 // Application to test class Scope. 3 public class ScopeTest 4 { 5 // application starting point 6 public static void Main( string[] args ) 7 { 8 Scope testScope = new Scope(); 9 testScope.Begin(); 10 } // end Main 11 } // end class ScopeTest  

local x in method Begin is 5 local x on entering method UseLocalVariable is 25 local x before exiting method UseLocalVariable is 26 instance variable x on entering method UseInstanceVariable is 1 instance variable x before exiting method UseInstanceVariable is 10 local x on entering method UseLocalVariable is 25 local x before exiting method UseLocalVariable is 26 instance variable x on entering method UseInstanceVariable is 10 instance variable x before exiting method UseInstanceVariable is 100 local x in method Begin is 5

In class Scope (Fig. 7.11), line 8 declares and initializes the instance variable x to 1. This instance variable is hidden in any block (or method) that declares local variable named x. Method Begin (lines 1231) declares local variable x (line 14) and initializes it to 5. This local variable's value is output to show that instance variable x (whose value is 1) is hidden in method Begin. The application declares two other methodsUseLocalVariable (lines 3443) and UseInstanceVariable (lines 4653)that each take no arguments and do not return results. Method Begin calls each method twice (lines 1928). Method UseLocalVariable declares local variable x (line 36). When UseLocalVariable is first called (line 19), it creates local variable x and initializes it to 25 (line 36), outputs the value of x (lines 3839), increments x (line 40) and outputs the value of x again (lines 4142). When UseLocalVariable is called a second time (line 25), it re-creates local variable x and re-initializes it to 25, so the output of each UseLocalVariable call is identical.

Method UseInstanceVariable does not declare any local variables. Therefore, when it refers to x, instance variable x (line 8) of the class is used. When method UseInstanceVariable is first called (line 22), it outputs the value (1) of instance variable x (lines 4849), multiplies the instance variable x by 10 (line 50) and outputs the value (10) of instance variable x again (lines 5152) before returning. The next time method UseInstanceVariable is called (line 28), the instance variable has its modified value, 10, so the method outputs 10, then 100. Finally, in method Begin, the application outputs the value of local variable x again (line 30) to show that none of the method calls modified Begin's local variable x, because the methods all referred to variables named x in other scopes.

Method Overloading

Категории