Operators

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

Although most of C#'s operators should be familiar to C and C++ developers, we will discuss the most important ones here for the benefit of new programmers and VB converts, and to shed some light on some of the changes introduced with C#.

C# supports the following operators, although four ( sizeof , * , - >, and &) are only available in unsafe code (code which bypasses C#'s type safety checking), which we will look at in Chapter 4:

Category

Operator

Arithmetic

+ - * / %

Logical

& ^ ~ && !

String concatenation

+

Increment and decrement

++ --

Bit shifting

<< >>

Comparison

== != < > < = > =

Assignment

= += -= *= /= %= & = = ^= << = >> =

Member access (for objects and structs)

.

Indexing (for arrays and indexers)

[]

Cast

()

Conditional (the Ternary Operator)

?:

Object Creation

new

Type information

sizeof (unsafe code only) is typeof as

Overflow exception control

checked unchecked

Indirection and Address

* - > & (unsafe code only) []

One of the biggest pitfalls to watch out for when using C# operators is that, like other C-style languages, it uses different operators for assignment = , and comparison == . For instance, the following statement means 'let x equal three':

   x = 3;   

If we now want to compare x to a value, we need to use the double equals sign == :

   if (x == 3)   

Fortunately, C#'s very strict type safety rules prevent the very common C error we mentioned earlier in the chapter, where using an assignment operator instead of the comparison operator caused unpredictable behavior. This means that in C# the following statement will generate an error, and won't compile:

   if (x = 3)   

VB programmers who are used to using the ampersand, &, to concatenate strings will have to make an adjustment. In C#, the plus sign + is used instead, while & denotes a bit-wise AND between two different integer values. allows you to perform a bit-wise OR between two integers. VB programmers also might not recognize the % ( modulus ) arithmetic operator. This returns the remainder after division, so for example x % 5 will return 2 if x is equal to 7 .

You will use few pointers in C#, and so, you will use few indirection operators - >. Specifically, the only place you will use them is within blocks of unsafe code, because that's the only place in C# where pointers are allowed.

Operator Shortcuts

The following table shows the full list of shortcut assignment operators available in C#:

Shortcut Operator

Equivalent To

x++ , ++x

x = x + 1

x-- , --x

x = x - 1

x += y

x = x + y

x -= y

x = x y

x *= y

x = x * y

x /= y

x = x / y

x %= y

x = x % y

x >> = y

x = x >> y

x << = y

x = x << y

x & = y

x = x & y

x = y

x = x y

x ^= y

x = x ^ y

You may be wondering why there are two examples each for the ++ increment and the -- decrement operators. Placing the operator before the expression is known as a prefix , and placing the operator after the expression is known as a postfix . The expressions x++ and ++x are both equivalent to x = x + 1 , but there is a difference in the way they behave. The increment and decrement operators can act both as whole expressions and within expressions.

As lines on their own, they are identical and correspond to the statement x = x + 1 . When they are used within expressions, however, there is a difference. The prefix example ++x will increment the value of x before the expression is evaluated; in other words, x is incremented and the new value is used in the expression. In contrast, the postfix operator increments the value of x after the expression is evaluated the expression is evaluated using the original value. The following example shows the difference between the two operators:

   int x = 5;     if (++x == 6)     {     Console.WriteLine("This will execute");     }     if (x++ == 7)     {     Console.WriteLine("This won't");     }   

The first if condition evaluates to true , because x is incremented from 5 to 6 before the expression is evaluated. The condition in the second if statement is false , however, because x is only incremented to 7 after the entire expression has been evaluated.

The prefix and postfix operators --x and x-- behave in the same way, but decrement rather than increment the operand.

The other shortcut operators, such as += and -= , require two operands, and are used to modify the value of the first operand by performing an arithmetic, logical, or bit-wise operation on it. For example, the next two lines are equivalent:

   x += 5;     x = x + 5;   

The Ternary Operator

The ternary operator, ?: , is a shorthand form of the if...else construction. It gets its name from the fact that it involves three operands. It allows us to evaluate a condition, returning one value if that condition is true, or another value if it is false. The syntax is:

  condition  ?  true   _   value  :  false   _   value  

Here, condition is the Boolean expression to be evaluated, true_value is the value that will be returned if condition is true, and false_value is the value that will be returned otherwise .

When used sparingly, the ternary operator can add a dash of terseness to your programs. It is especially handy for providing one of a couple of arguments to a function that is being invoked. You can use it to quickly convert a Boolean value to a string value of true or false . It is also quite handy for displaying a correct singular or plural form, for example:

   int x = 1;     string s = x.ToString() + " ";     s += (x == 1 ? "man" : "men");     Console.WriteLine(s);   

This code will display 1 man if x is equal to one, but will display the correct plural form for any other number. Note, however, that if your output needs to be localized to different languages then you will probably have to write more sophisticated routines to take account of the different grammatical rules of different languages.

checked and unchecked

Consider the following code:

   byte b = 255;     b++;     Console.WriteLine(b.ToString());   

The byte data type can only hold values in the range zero to 255, so incrementing the value of b causes an overflow. How the CLR handles this depends on a number of issues, including compiler options, so whenever there's a risk of an unintentional overflow, we really need some way of making sure that we get the result we want.

To do this, C# provides the checked and unchecked operators. If we mark a block of code as checked , the CLR will enforce overflow checking, and throw an exception if an overflow occurs. Let's change our code to include the checked operator:

 byte b = 255;   checked     {     b++;     }   Console.WriteLine(b.ToString()); 

When we try to run this, we will get an error message like this:

 Unhandled Exception: System.OverflowException: Arithmetic operation resulted in an overflow.    at Wrox.ProCSharp.Basics.OverflowTest.Main(String[] args) 

We can enforce overflow checking for all unmarked code in our program by compiling with the /checked option.

If we want to suppress overflow checking, we can mark the code as unchecked :

 byte b = 255;   unchecked     {     b++;     }   Console.WriteLine(b.ToString()); 

In this case, no exception will be raised, but we will lose data since the byte type can't hold a value of 256, the overflowing bits will be discarded, and our b variable will hold a value of zero.

Note that unchecked is the default behavior. The only time where you are likely to need to explicitly use the unchecked keyword is if you need a few unchecked lines of code inside a larger block that you have explicitly marked as checked .

is

The is operator allows us to check whether an object is compatible with a specific type. For example, to check whether a variable is compatible with the object type:

By the phrase is 'compatible', we mean that an object is either of that type or is derived from that type.

   int i = 10;     if (i is object)     {     Console.WriteLine("i is an object");     }   

int , like all other C# data types, inherits from object , therefore the expression i is object will evaluate to true , and the message will be displayed.

The as operator is used to perform certain explicit type conversions.

sizeof

We can determine the size (in bytes) required by a value type on the stack using the sizeof operator:

   string s = "A string";     unsafe     {     Console.WriteLine(sizeof(int));     }   

This will display the number 4 , as int s are four bytes long.

Notice that we can only use the sizeof operator in unsafe code. We will look at unsafe code in more detail in Chapter 4.

typeof

The typeof operator returns a Type object representing a specified type. For example, typeof(string) will return a Type object representing the System.String type. This is useful when we want to use reflection to find out information about an object dynamically. We will look at reflection in Chapter 5.

Operator Precedence

The following table shows the order of precedence of the C# operators. The operators at the top of the table are those with the highest precedence (that is, the ones which are evaluated first in an expression containing multiple operators):

Group

Operators

 

() . [] x++ x-- new typeof sizeof checked unchecked

Unary

+ - ! ~ ++x --x and casts

Multiplication/Division

* / %

Addition/Subtraction

+ -

Bitwise shift operators

<< >>

Relational

< > < = > = is as

Comparison

== !=

Bitwise AND

&

Bitwise XOR

^

Bitwise OR

Boolean AND

&&

Boolean OR

Ternary operator

?:

Assignment

= += -= *= /= %= & = = ^= << = >> = >>> =

  


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