[ Team LiB ] Previous Section Next Section

3.2 Variables and Constants

A variable is a storage location with a type. In the preceding examples, both x and y are variables. Variables can have values assigned to them, and those values can be changed programmatically.

WriteLine( )

The .NET Framework provides a useful method for writing output to the screen. The details of this method, System.Console.WriteLine( ), will become clearer as we progress through the book, but the fundamentals are straightforward. Call the method as shown in Example 3-1, passing in a string that you want printed to the console (the screen) and, optionally, parameters that will be substituted. In the following example:

System.Console.WriteLine("After assignment, myInt: {0}", myInt);

the string "After assignment, myInt:" is printed as is, followed by the value in the variable myInt. The location of the substitution parameter {0} specifies where the value of the first output variable, myInt, will be displayed—in this case at the end of the string. We see a great deal more about WriteLine( ) in coming chapters.

Create a variable by declaring its type and then giving it a name. You can initialize the variable when you declare it, and you can assign a new value to that variable at any time, changing the value held in the variable. This is illustrated in Example 3-1.

Example 3-1. Initializing and assigning a value to a variable
class Values
{
   static void Main( )
   {
      
      int myInt = 7
      System.Console.WriteLine("Initialized, myInt: {0}", 
         myInt); 
      
      myInt = 5;
      System.Console.WriteLine("After assignment, myInt: {0}", 
         myInt);
   }
}

Output:
Initialized, myInt: 7
After assignment, myInt: 5

Here we initialize the variable myInt to the value 7, display that value, reassign the variable with the value 5, and display it again.

VB6 programmers take note: In C#, the datatype comes before the variable name.

3.2.1 Definite Assignment

C# requires definite assignment: that is, variables must be initialized or assigned to before they are used. To test this rule, change the line that initializes myInt in Example 3-1 to:

int myInt;

and save the revised program shown in Example 3-2.

C and C++ programmers take note: C# requires that every variable must be assigned a definite value before use; this is checked by the compiler.

Example 3-2. Using an uninitialized variable
class Values
{
   static void Main( )
   {
      int myInt;
      System.Console.WriteLine 
      ("Uninitialized, myInt: {0}",myInt); 
      myInt = 5;
      System.Console.WriteLine("Assigned, myInt: {0}", myInt);
   }
}

When you try to compile this listing, the C# compiler will display the following error message:

3.1.cs(6,55): error CS0165: Use of unassigned local 
variable 'myInt'

It is not legal to use an uninitialized variable in C#. Example 3-2 is not legal.

So, does this mean you must initialize every variable in a program? In fact, no. You don't actually need to initialize a variable, but you must assign a value to it before you attempt to use it. Example 3-3 illustrates a correct program.

Example 3-3. Assigning without initializing
class Values
{
   static void Main( )
   {
      int myInt;
      myInt = 7;
      System.Console.WriteLine("Assigned, myInt: {0}", myInt);
      myInt = 5;
      System.Console.WriteLine("Reassigned, myInt: {0}", myInt);
   }
}

3.2.2 Constants

A constant is a variable whose value cannot be changed. Variables are a powerful tool, but there are times when you want to manipulate a defined value, one whose value you want to ensure remains constant. For example, you might need to work with the Fahrenheit freezing and boiling points of water in a program simulating a chemistry experiment. Your program will be clearer if you name the variables that store the values FreezingPoint and BoilingPoint, but you do not want to permit their values to be reassigned. How do you prevent reassignment? The answer is to use a constant.

Constants come in three flavors: literals, symbolic constants, and enumerations. In this assignment:

x = 32;

the value 32 is a literal constant. The value of 32 is always 32. You can't assign a new value to 32; you can't make 32 represent the value 99 no matter how you might try.

Symbolic constants assign a name to a constant value. You declare a symbolic constant using the const keyword and the following syntax:

const type identifier = value;

A constant must be initialized when it is declared, and once initialized it cannot be altered. For example:

const int FreezingPoint = 32;

In this declaration, 32 is a literal constant and FreezingPoint is a symbolic constant of type int. Example 3-4 illustrates the use of symbolic constants.

Example 3-4. Using symbolic constants
class Values
{
   static void Main( )
   {
      const int FreezingPoint = 32;   // degrees Farenheit
      const int BoilingPoint = 212;

      System.Console.WriteLine("Freezing point of water: {0}", 
            FreezingPoint );
      System.Console.WriteLine("Boiling point of water: {0}", 
            BoilingPoint );
      
      //BoilingPoint = 21;
   }
}

Example 3-4 creates two symbolic integer constants: FreezingPoint and BoilingPoint. As a matter of style, constant names are written in Pascal notation, but this is certainly not required by the language.

These constants serve the same purpose as always using the literal values 32 and 212 for the freezing and boiling points of water in expressions that require them, but because these constants have names, they convey far more meaning. Also, if you decide to switch this program to Celsius, you can reinitialize these constants at compile time, to 0 and 100, respectively; all the rest of the code ought to continue to work.

To prove to yourself that the constant cannot be reassigned, try uncommenting the last line of the program (shown in bold). When you recompile, you should receive this error:

error CS0131: The left-hand side of an assignment must be 
a variable, property or indexer

3.2.3 Enumerations

Enumerations provide a powerful alternative to constants. An enumeration is a distinct value type, consisting of a set of named constants (called the enumerator list).

Java programmers take note: Enumerations were mysteriously left out of the Java language; they are a useful feature and you'd do well to incorporate them into your programming style.

In Example 3-4, you created two related constants:

const int FreezingPoint = 32;  
const int BoilingPoint = 212; 

You might wish to add a number of other useful constants to this list, such as:

const int LightJacketWeather = 60;
const int SwimmingWeather = 72;
const int WickedCold = 0;

This process is somewhat cumbersome, and there is no logical connection among these various constants. C# provides the enumeration to solve these problems:

enum Temperatures
{
   WickedCold = 0,
   FreezingPoint = 32,
   LightJacketWeather = 60,
   SwimmingWeather = 72,
   BoilingPoint = 212,
}

Every enumeration has an underlying type, which can be any integral type (integer, short, long, etc.) except for char. The technical definition of an enumeration is:

[attributes] [modifiers]  enum identifier  
     [: base-type ] { enumerator-list }; 

The optional attributes and modifiers are considered later in this book. For now, let's focus on the rest of this declaration. An enumeration begins with the keyword enum, which is generally followed by an identifier, such as:

enum Temperatures

The base type is the underlying type for the enumeration. If you leave out this optional value (and often you will) it defaults to int, but you are free to use any of the integral types (e.g., ushort, long) except for char. For example, the following fragment declares an enumeration of unsigned integers (uint):

enum ServingSizes :uint
{
    Small = 1,
    Regular = 2,
    Large = 3
}

Notice that an enum declaration ends with the enumerator list. The enumerator list contains the constant assignments for the enumeration, each separated by a comma.

Example 3-5 rewrites Example 3-4 to use an enumeration.

Example 3-5. Using enumerations to simplify your code
class Values
{

   enum Temperatures
   {
      WickedCold = 0,
      FreezingPoint = 32,
      LightJacketWeather = 60,
      SwimmingWeather = 72,
      BoilingPoint = 212,
   }

   static void Main( )
   {

      System.Console.WriteLine("Freezing point of water: {0}", 
         (int) Temperatures.FreezingPoint );
      System.Console.WriteLine("Boiling point of water: {0}", 
         (int) Temperatures.BoilingPoint );

   }
}

As you can see, an enum must be qualified by its enumtype (e.g., Temperatures.WickedCold). By default, an enumeration value is displayed using its symbolic name (such as BoilingPoint or FreezingPoint). When you want to display the value of an enumerated constant, you must cast the constant to its underlying type (int). The integer value is passed to WriteLine, and that value is displayed.

Each constant in an enumeration corresponds to a numerical value—in this case, an integer. If you don't specifically set it otherwise, the enumeration begins at 0 and each subsequent value counts up from the previous.

If you create the following enumeration:

enum SomeValues
{
   First,
   Second,
   Third = 20,
   Fourth
}

the value of First will be 0, Second will be 1, Third will be 20, and Fourth will be 21.

Enums are formal types; therefore an explicit conversion is required to convert between an enum type and an integral type.

C and C++ programmers take note: C#'s use of enums is subtly different from C++, which restricts assignment to an enum type from an integer but allows an enum to be promoted to an integer for assignment of an enum to an integer.

3.2.4 Strings

It is nearly impossible to write a C# program without creating strings. A string object holds a string of characters.

You declare a string variable using the string keyword much as you would create an instance of any object:

string myString;

A string literal is created by placing double quotes around a string of letters:

"Hello World"

It is common to initialize a string variable with a string literal:

string myString = "Hello World";

Strings are covered in much greater detail in Chapter 10.

3.2.5 Identifiers

Identifiers are names that programmers choose for their types, methods, variables, constants, objects, and so forth. An identifier must begin with a letter or an underscore.

The Microsoft naming conventions suggest using camel notation (initial lowercase such as someName) for variable names and Pascal notation (initial uppercase such as SomeOtherName) for method names and most other identifiers.

Microsoft no longer recommends using Hungarian notation (e.g., iSomeInteger) or underscores (e.g., SOME_VALUE).

Identifiers cannot clash with keywords. Thus, you cannot create a variable named int or class. In addition, identifiers are case-sensitive, so C# treats myVariable and MyVariable as two different variable names.

    [ Team LiB ] Previous Section Next Section