Pro Visual C++ 2005 for C# Developers

You 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 you use this variable until you have initialized it with a value, but the declaration allocates four bytes on the stack to hold the value.

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

i = 10;

You 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 Visual Basic syntax for declaring variables. If you are coming from Visual Basic 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 you want your 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 you 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

Notice the // and the text after in the preceding examples. These are comments. The // character sequence tells the compiler to ignore the text that follows. Comments in code are further explained later in this chapter.

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 you 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 you 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:

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 Visual Basic, in which all variables are zeroed out automatically.

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

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

Notice that this code snippet demonstrates defining Main() so it returns an int instead of void.

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

Use of unassigned local variable 'd'

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

Something objSomething;

In C++, this 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. You create a reference as shown in the previous example 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:

Scope clashes for local variables

It's common in a large program to use the same variable name for different variables in different parts of the program. This is fine as long as the variables are scoped to completely different parts of the program so there is no possibility for ambiguity. However, bear in mind that local variables with the same name can't be declared twice in the same scope, so you 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 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 you declare the variable i twice in this code, within the same method. You can do this because i is declared in two separate loops, so each i variable is local to its own loop.

Here's another example:

public static int Main() { int j = 20; for (int i = 0; i < 10; i++) { int j = 30; // Can't Console.WriteLine(j + i); } return 0; }

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

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

This is because the variable j, which is 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.

Scope clashes for fields and local variables

In certain circumstances, however, you 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 you 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 the following code snippet:

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 you 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 (when the Main() method terminates, and the program ends); and the j defined in Main(). In this case, the new variable named j that you declare in the Main() method hides the class-level variable with the same name, so when you run this code, the number 30 will be displayed.

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

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

If you were accessing an instance field (a field that belongs to a specific instance of the class), you would need to use the this keyword instead. This keyword performs the same role as this in C++ and Java, and Me in Visual Basic.

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 Visual Basic and C++ developers. C++ developers should, however, note that C# does not 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:

At least three advantages exist to using constants in your programs:

Категории