Statements

Extensive commonality exists in the syntax and functionality of statements in C# and Java:

  • All statements must end with a semicolon.

  • Block statements are formed using braces.

  • An empty statement is represented by a single semicolon. In both languages, it’s considered a good idea to comment the existence of any empty statement.

Labeled Statements

Labeled statements are implemented by C# and Java in the same way, differing only in how jumps are performed. In Java, jumps are made to a labeled statement using the continue or break statement, as shown in the following example:

mylabel:
// statements
while (/* some condition */) {
    break mylabel;
}

In C#, the break and continue statements do not take targets. To jump to a labeled statement, use the goto statement:

mylabel:
//statements
while (/* some condition */) {
    goto mylabel;
}

The break, continue, and goto statements are discussed in detail later in the Jump Statements section.

Selection and Iteration Statements

The following selection and iteration statements are the same in syntax and function:

  • The if...else if...else statement

  • The while statement

  • The do statement

  • The for statement

The following sections discuss the difference between the Java and C# switch statement and introduce a new C# iterator, the foreach statement.

The switch Statement

The switch statement in C# differs from Java in three ways:

  • C# supports a broader range of data types for the switch expression, including enumerations, chars, and built in integer types. Most usefully, C# supports the use of strings as switch expressions.

  • C# does not support falling through case clauses. A compile-time error occurs if a case clause is not terminated with a break or goto statement. C# does allow multiple case expressions on a single statement block.

  • C# supports goto statements to jump from one case clause to another. Following a goto statement with a break statement results in a compiler warning.

The example below demonstrates these differences:

public void MyMethod(string color) {

    switch (color.ToLower()) {    // Note – using a string

        case "orange":
        case "red":
            SomeMethod();
            goto default;    // Note – jump to default clause

        case "aqua":
        case "blue":
            SomeOtherMethod();
            break;

        case "green":
            SomeThirdMethod();
            goto case "red";    // Note – jump to "red" clause

        default:
            SomeDefaultMethod();
            break;
    }
}

The foreach Statement

The C# foreach statement iterates through the elements of a collection. For the purpose of the foreach statement, a collection is

  • Any type that implements the System.IEnumerable interface.

  • Any array (because System.Array implements IEnumerable).

  • Any type that implements a pattern equivalent to IEnumerable.

The syntax of a foreach statement is

foreach (type identifier in collection) statement

The type and identifier declare a read-only local iteration variable that’s available within the scope of the statement.

The following example of the foreach statement iterates through the contents of a string array and prints out each element:

string[] days = new string[] {"Monday", "Tuesday", "Wednesday"};
foreach (string myString in days) {
    System.Console.WriteLine(myString);
}
  • The type of the iteration variable must be the same as the collection element type, or an explicit conversion must exist between the two.

  • A compiler error occurs if an attempt is made to assign a value to the read-only iteration variable inside the statement.

More Info

For more detail about the foreach keyword, see Chapter 9.

Jump Statements

C# provides equivalents for all of the Java statements used to transfer processing control, but functional differences exist between most of them. In addition, C# also defines the goto statement.

The return Statement

The return statement has the same function and syntax in both C# and Java.

The throw Statement

See the section Exceptions and Exception Handling in Chapter 6 for details of the throw statement.

The break and continue Statements

C# supports both the break and continue statements but does not support the use of label identifiers as targets of these statements.

  • The break statement exits the nearest enclosing switch, while, do, for or foreach statement.

  • The continue statement starts a new iteration of the nearest enclosing while, do, for, or foreach statement.

  • Use the goto statement, discussed in the next section, to jump to a labeled statement in C#.

The goto Statement

The C# goto statement allows an unconditional jump to a labeled statement. The goto might cause execution to jump either forward or backward in the code, but the goto statement must be within the scope of the target labeled statement. Because Java doesn’t currently implement the goto keyword, the nearest equivalent of the C# goto statement in Java is targeted break or continue statements, although these do not provide the same levels of flexibility. Note the following:

  • Using goto to jump out of a try or catch block will cause the finally block to execute.

  • A compile-time error occurs if the goto statement is used to jump out of a finally block.

Other Statements

This section discusses statements not related to selection, iteration, and the transfer of processing control. The try and fixed statements are listed here for completeness; a detailed description of each statement is included in Chapter 6.

The try Statement

See Chapter 6 in Chapter 6 for details of the try statement.

The lock Statement

The C# keyword lock is nearly equivalent to the Java keyword synchronized. The principle difference is that the lock keyword cannot be used as a modifier to synchronize access to an entire method. It’s applicable only to statement blocks, as in the following example:

public void SampleMethod() {
    lock(SomeObject) {
        // statements needing synchronized access
    }
    return;
}

More Info

Use of the lock statement is covered in detail in Chapter 13.

The checked and unchecked Keywords

Arithmetic overflow occurs when the result of an integer type mathematical operation or conversion is greater or smaller than can be represented by the defined data type. For example, in Java and C#, a short can contain integer values between -32,768 and 32,767. The following code demonstrates arithmetic overflow in Java:

short x = 32767;
x++;
System.out.println(x);

The output from the above code will be -32768.

Java handles integral arithmetic overflow by truncating the high-order bits, resulting in the cyclical effect just demonstrated. In C#, the checked and unchecked keywords allow control of the compile-time and run-time handling of integral arithmetic overflow.

Technically, the checked and unchecked keywords are operators as well as statements. The checked and unchecked keywords use the same syntax. An example of a checked expression and statement is included in the following code fragment:

// A checked expression
int b = checked (x * 5);

// A checked statement block
checked {
    int p = x++;
    int q = x * 5;
    int r = p * q;
}

A compiler error is reported if the value of the checked expression can be resolved at compile time and overflow occurs. If the value of the checked expression cannot be determined until run time, overflow causes a System.OverflowException to be thrown. The use of the unchecked keyword forces truncation, causing any errors or exceptions to be suppressed and resulting in the same cyclic behavior seen with Java.

If neither checked nor unchecked is specified in the code, the following defaults are used:

  • For constant values, the compiler checks for overflow and an error will be reported, as though the checked keyword had been specified.

  • For variable values, the runtime will allow truncated values, as though the unchecked keyword had been specified.

The default compile-time overflow checking can be modified by using the /checked compiler flag. See Chapter 3 for details of compiler flags.

The using Statement

The using keyword represents both a statement and a directive. The using directive is for importing namespaces into an application. See the Namespaces section earlier in this chapter for details. The using statement is a mechanism for efficiently acquiring, using, and disposing of a class or struct that implements the System.IDisposable interface. For example, if MyClass and MyStruct are types that implement IDisposable, the syntax of the using command is as follows:

using (MyClass x = new MyClass(), MyStruct y = new MyStruct()) {
    // do something with x and y
    x.someMethod();
    y.someOtherMethod();
} // x and y are automatically disposed of

The objects specified in the using statement are available within the scope of the statement block. At the end of the statement block, the Dispose method of the IDisposable interface is automatically called on each object. The using statement automatically wraps the necessary try...catch...finally structure around the statement block. This ensures that the objects are disposed of irrespective of whether an exception causes the program to leave the statement block or the statement exits normally.

The fixed Statement

For information on the fixed statement, see the Unsafe Code section in Chapter 6.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset