Variables

 
Chapter 2 - C# Basics
bySimon Robinsonet al.
Wrox Press 2002
  

Variables

We declare variables in C# using the following syntax:

  datatype identifier;  

for example:

   int i;   

This statement declares an int named i . The compiler won't actually let us use this variable until we have initialized it with a value, but the declaration allocates four bytes on the stack to hold the value.

Once it has been declared, we can assign a value to the variable using the assignment operator, = :

   i = 10;   

We can also declare the variable and initialize its value at the same time:

   int i = 10;   

This syntax is identical to C++ and Java syntax, but very different from VB syntax for declaring variables. If you are coming from VB 6, you should also be aware that C# doesn't distinguish between objects and simple types, so there is no need for anything like the Set keyword, even if we want our variable to refer to an object. The C# syntax for declaring variables is the same no matter what the data type of the variable.

If we declare and initialize more than one variable in a single statement, all of the variables will be of the same data type:

   int x = 10, y =20;   // x and y are both ints   

To declare variables of different types, you need to use separate statements don't assign different data types within a multiple variable declaration:

   int x = 10;     bool y = true;               // Creates a variable that stores true or false     int x = 10, bool y = true;   // This won't compile!   

Initialization of Variables

Variable initialization demonstrates another example of C#'s emphasis on safety. Briefly, the C# compiler requires that any variable be initialized with some starting value before we refer to that variable in an operation. Most modern compilers will flag violations of this as a warning, but the ever vigilant C# compiler treats such violations as errors. This prevents us from unintentionally retrieving junk values from memory that is left over from other programs.

C# has two methods for ensuring that variables are initialized before use:

  • Variables that are fields in a class or struct, if not initialized explicitly, are by default zeroed out when they are created.

  • Variables that are local to a method must be explicitly initialized in your code prior to any statements in which their values are used. In this case, the initialization doesn't have to happen when the variable is declared, but the compiler will check all possible paths through the method and will flag an error if it detects any possibility of the value of a local variable being used before it is initialized.

C#'s approach contrasts with that of C++, in which the compiler leaves it up to the programmer to make sure that variables are initialized before use, and that of VB, in which all variables are zeroed out automatically.

For example, we can't do the following in C#:

   public static int Main()     {     int d;     Console.WriteLine(d);   // Can't do this! Need to initialize d before use     return 0;     }   

Notice that for this code snippet we have demonstrated defining Main() so it returns an int instead of void .

When we attempt to compile these lines, we will receive this kind of error message:

 Use of unassigned local variable 'd' 

The same rules apply to reference types as well. Consider the statement:

   Something objSomething;   

In C++, the above line would create an instance of the Something class on the stack. In C#, this same line of code would only create a reference for a Something object, but this reference does not yet actually refer to any object. Any attempt to call a method or property against this variable would result in an error.

Instantiating a reference object in C# requires use of the new keyword. We create a reference as above, and then point the reference at an object allocated on the heap using the new keyword:

   objSomething = new Something();   // This creates a Something on the heap   

Variable Scope

The scope of a variable is the region of code from which the variable can be accessed. In general, the scope is determined by the following rules:

  • A field (also known as a member variable) of a class is in scope for as long as its containing class is in scope (this is the same as for C++, Java, and VB).

  • A local variable is in scope until a closing brace indicates the end of the block statement or method in which it was declared.

  • A local variable that is declared in a for , while , or similar statement is in scope in the body of that loop. (C++ people will note that this is the same behavior as the ANSI standard for C++. Early versions of the MS C++ compiler did not comply with this standard, but scoped such variables to remain in scope after the loop terminated ).

You should also note that variables with the same name can't be declared twice in the same scope, so we can't do this:

   int x = 20;     // some more code     int x = 30;   

Consider the following code sample:

   using System;     namespace Wrox.ProCSharp.Basics     {     public class ScopeTest     {     public static int Main()     {     for (int i = 0; i < 10; i++)     {     Console.WriteLine(i);     }   // i goes out of scope here     // We can declare a variable named i again, because     // there's no other variable with that name in scope     for (int i = 9; i >= 0; i--)     {     Console.WriteLine(i);     }   // i goes out of scope here     return 0;     }     }     }   

This code simply prints out the numbers from 0 to 9, and then back again from 9 to 0, using a for loop. The important thing to note is that we declare the variable i twice in this code, within the same method. The reason that we can do this is that i is declared in two separate loops , so each i variable is local to its own loop.

Let's have a look at another example:

   public static int Main()     {     int j = 20;     for (int i = 0; i < 10; i++)     {     int j = 30;   // Can't do this - j is still in scope     Console.WriteLine(j + i);     }     return 0;     }   

If we try to compile this, we'll get an error:

 ScopeTest.cs(12,14): error CS0136: A local variable named 'j' cannot be declared in this scope because it would give a different meaning to 'j', which is already used in a 'parent or current' scope to denote something else 

This is because the variable j , which we defined before the start of the for loop, is still in scope within the for loop, and won't go out of scope until the Main() method has finished executing. Although, the second j (the illegal one) is in the loop's scope, that scope is nested within the Main() method's scope. The compiler has no way to distinguish between these two variables, so it won't allow the second one to be declared. This is again different from C++ where variable hiding is permitted.

Fields and Local Variables

In certain circumstances, however, we can distinguish between two identifiers with the same name (although not the same fully qualified name) and the same scope, and in this case the compiler will allow us to declare the second variable. The reason is that C# makes a fundamental distinction between variables that are declared at the type level (fields), and variables declared within methods (local variables):

Consider this code:

 using System; namespace Wrox.ProCSharp.Basics {    class ScopeTest2    {   static int j = 20;     public static void Main()     {     int j = 30;     Console.WriteLine(j);     return;     }   } } 

This code will compile, even though we have two variables named j in scope within the Main() method the j that was defined at the class level, and doesn't go out of scope until the class is destroyed (in this case, when the Main() method terminates, and the program ends) and the j defined in Main(). In this case, the new variable named j which we declare in the Main() method hides the class-level variable with the same name, so when we run this code, the number 30 will be displayed.

However, what if we want to refer to the class-level variable? We can actually refer to fields of a class or struct from outside the object, using the syntax object.fieldname . In the example above, we are accessing a static field (we will look at what this means in the next section) from a static method, so we can't use an instance of the class; we just use the name of the class itself:

 ...       public static void Main()       {          int j = 30;   Console.WriteLine(ScopeTest2.j);   }       ... 

If we were accessing an instance field (a field that belongs to a specific instance of the class), we would need to use the this keyword instead. The this keyword is used within a class or struct to obtain a reference to the current instance; we will look at this in more detail later on in the chapter. this performs the same role as this in C++ and Java, and Me in VB.

Constants

Prefixing a variable with the const keyword when it is declared and initialized designates that variable as a constant. As the name implies, a constant is a variable whose value cannot be changed throughout its lifetime:

   const int a = 100;   // This value cannot be changed   

Constants will be familiar to developers in VB and C++. C++ developers should, however, note that C# doesn't permit all the subtleties of C++ constants. In C++, not only could variables be declared as constant, but depending on the declaration, you could have constant pointers, variable pointers to constants, constant methods (that don't change the contents of the containing object), constant parameters to methods, and so on. These subtleties have been discarded in C#, and all you can do is declare local variables and fields to be constant.

Constants have the following characteristics:

  • They must be initialized when they are declared, and once a value has been assigned, it can never be overwritten.

  • The value of a constant must be computable at compiletime. Therefore, we can't initialize a constant with a value taken from a variable. If you need to do this, you will need to use a read-only field.

  • Constants are always implicitly static. However, notice that we don't have to (and, in fact, aren't permitted to) include the static modifier in the constant declaration.

There are at least three advantages to using constants in your programs:

  • Constants make your programs easier to read by replacing 'magic numbers' and 'magic strings' with readable names whose values are easy to understand.

  • Constants make your programs easier to modify. Say, for instance, that you have a SalesTax constant in one of your C# programs, and that constant is assigned a value of 6%. If the sales tax rate changes at a later point in time, you can modify the behavior of all tax calculations simply by assigning a new value to the constant; you don't have to hunt throughout your code for the value .06 and change each one, hoping that you've found all of them.

  • Constants make it easier to avoid mistakes in your programs. If you attempt to assign another value to a constant somewhere in your program after you've already assigned it a value, the compiler will flag the error.

  


Professional C#. 2nd Edition
Performance Consulting: A Practical Guide for HR and Learning Professionals
ISBN: 1576754359
EAN: 2147483647
Year: 2002
Pages: 244

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net