Operators

So, you've written your first program, and you've learned about the basic types in .NET. Now you need to learn how to do things with those types.

The most basic way that types interact is through operators. This tutorial will walk you through some of the more basic.

**Why is this important to learn about?**

Again, operators are the most basic way that you can create interactions between objects/values. How could you ever do math without knowing what plus, minus, times, and divide do? Well, those are mathematical operators. The same principles apply to programming operators: without them, you'll probably never get anything done.

**Definitions of terms used.**

**Note:**

*All examples were created using Visual Studio 2010, targetting the .NET Framework 4.0. We'll do our best to point out anything that might not work in older versions.*

**Operators**

If you followed the link in the definitions above, you'll see that C# has quite a few operators. Some are single character, some are multiple. Some are unary, some are binary; one is even ternary (one of my favorites, actually).

Thes operators, just like in mathematics, follow an order of operations. The MSDN list of C# operators lists them in groups of precedent. Operators in the same group are evaluated left-to-right.

**Parenthesis ( )**

Parenthesis have several functions. First and foremost, they're used for order-of-operations, just like in math. 5 + 1 * 3 equals 8, but (5 + 1) * 3 equals 18. It works the same way in C#. Operations inside of parenthesis are evaluated before those outside of them. Parenthesis are also used to invoke methods (we'll cover methods in another tutorial later), and for casting operations. Casting will also be covered later, but in breif: it's a way to convert one type to another.

Here's an example of casting:

int x = (int)3.141;

In that example, we're taking a double, and converting it into an integer. You can't cast any type to any other: cast operations must either be performed on classes that are related via inheritance, or be defined (using implicit or explicit) in the class definition. But that's out of scope of this tutorial.

**Unary Operators**

Unary operators take only one operand. A mathematical example would be the Factorial operator.

**Increment (++) and Decrement (--)**

If you've ever heard of C++, this is where the ++ comes from. ++

*increments*the the value it's applied to. This operator can be either postfix (x++;) or prefix (++x;). In either case, after the expression is evaluated, x will be one greater than it was before. These operators can only be applied to numeric types by default.

Now, there's a reason why you can use these operators either way, and it's

*quite important*. Before I explain, consider this code:

int a = 0; int b = 0; Console.WriteLine(++a); Console.WriteLine(b++);

As explained earlier, both a and b will have a value of 1 after this code is evaluated. However, if you've tried this yourself, you've noticed that the output doesn't match!

Output

Quote

1

0

0

Why, when both adds one to the variable? Because they evaluate at different times. ++a means "add one to the value of a, then return that value." b++ means "return the value of b, then add one to it". It's a very important distinction if you're not using it as a standalone operation. I suggest you get in the habit of using the prefix (++a) version unless you

*need*the postfix behavior. This will cause less confusion down the road.

*Note: the -- operator works exactly the same way, except decreasing the value by one instead of increasing.*

**Plus (+) and Minus (-) as Unary Operators**

These operate the same way mathmatical positive and negative signs do. +x simply returns x. -x returns x * -1.

**Boolean Negation (!)**

The bang (or exclamation point) operator negates boolean types. !true returns false, and !false returns true. This is often useful to invert a boolean statement:

bool respondedNo = false; while (!respondedNo) { Console.WriteLine("Continue?"); respondedNo = Console.ReadKey().Key == ConsoleKey.N; }

**Binary Operators**

Binary operators take two operands. These are the most familiar, since you've been using these since grade school.

**Important note:**None of these operators except for the assignment operators modify their operands. They

*return*the result of their evaluation. So if you do a + b, after it's evaluated, both a and b will still have their original values. You must either use it in further evaluation or assign the result to a variable for it to have any significance.

**Multiplicitive Operands (*, /, %)**

These three share precedence in the order of operations, and as such, are evaluated left-to-right. First is the Multiply operator (*). This returns the product of the operands to the left and right. The Divide operator (/) behaves the same, except dividing the two operands.

Console.WriteLine(10 * 5); Console.WriteLine(20 / 4);;

Quote

50

5

5

If you use ints to do division, you may find unexpected results. For example:

Console.WriteLine(1 / 3);

Output

Quote

0

You'd expect the output to be 0.3333 repeating, but

**it's not.**That's because integers can't possibly have decimal values, so the decimals are trimmed (

*not rounded! 0.999 becomes 0*). By changing one of the operands to a float/double/decimal, the entire operation is evaluated as a double.

Console.WriteLine(1 / 3.0);

Quote

0.333333333333333

*Note: Integer Division by zero will throw a DivideByZeroException. That's a bad thing, so don't do it. Dividing a floating-point number by zero will not result in an exception, but will return the value Double.NaN (Not a Number).*

This naturally leads us to the Modulus operator (%). Remember in grade school when you started learning division? You didn't learn with decimals, but with integer quotients and remainders. The modulus operation returns the remainder of integer division. For example:

Console.WriteLine(20 % 6);

Quote

2

20 / 6 is equal to 3.33 repeating. However, using integer division, it is 3. 6 * 3 is equal to 18. 20 - 18 equals 2. In other words, 20 / 6 = 18 R 2. Modulus returns the remainder. This doesn't sound immediately useful, but it can be if you know a bit of math. For instance, we can use it to determine even numbers:

for (int i = 0; i < 10; i++) { if (i % 2 == 0) Console.WriteLine("{0} is even.", i); else Console.WriteLine("{0} is odd.", i); }

Quote

0 is even.

1 is odd.

2 is even.

3 is odd.

4 is even.

5 is odd.

6 is even.

7 is odd.

8 is even.

9 is odd.

1 is odd.

2 is even.

3 is odd.

4 is even.

5 is odd.

6 is even.

7 is odd.

8 is even.

9 is odd.

**Additive Operators (+, -)**

These both share a precedence, below that of the multiplicitive operators. Just like in actual mathematics. For numeric types, + and - do exactly what you think they do: return the result of adding or subtracting the operators respectively.

However, + has another function: string concatenation. Concatenation basically means joining together. Here's an example of concatenating strings:

string a = "Hello"; string b = "World"; string c = a + " " + b; Console.WriteLine(c);

Quote

Hello World

**Important note:**Strings aren't numbers! There is a huge, huge difference between adding numbers and concatenating strings. Since strings can represent numbers though, it may

*look*confusing. But remember, if it's a string, it'll be joined up, not added together.

Console.WriteLine(1 + 2); Console.WriteLine("1" + "2");

Quote

3

12

12

**Equality Operators (==, !=)**

C# makes an important distinction that not all languages make: "Equality and Assignment are different things, therefore should use different operators." What that means is, there's a difference between saying "I want to assign the value of b to a," and "I want to know if a is equal to b."

To support that distinction, C# uses == as the comparison operator.

if(x == 1) //do something

In the preceeding example, we

*compare*x to 1. The result will be either true or false, depending on if x is equal to 1.

**Important note**: The equality operator compares values for value types, but for most reference types, it checks to see if both operands are pointing to the same block of memory. This is a hugely important distinction, since two objects can be what

*you*would consider equal, but in distinct memory, so the compiler won't consider them equal. You can define equality for reference types by overriding the .Equals method, which is outside the scope of this tutoria..

The != (not equals) operator is the exact opposite. It returns true when the operands are

*not*equal, and false when they are.

**Other Comparison Operators (&&,||)**

These operators are all about boolean logic. If you've ever taken a logic class, you should have covered this. Basically, they're a way of expressing AND (&&) and OR (||). && has a higher precedence in order of operations than ||.

&& will return true if

*both*of the operands are true. Otherwise it will return false.

|| will return true if

*one*of the operands are true. Only if both are false will it return false.

To see this in action:

bool x = true; bool y = false; if (x && y) Console.WriteLine("Both were true."); else Console.WriteLine("At least one was false."); if (x || y) Console.WriteLine("At least one was true."); else Console.WriteLine("Both were false.");

Quote

At least one was false.

At least one was true.

At least one was true.

*Note:*There are also

*bitwise*versions of these operators, (&, |), as well as a bitwise XOR (^). XOR returns true if one and only one of the operands are true, otherwise false. Against bools, the bitwise operators work exactly the same. However, they also operate against integral values as well. They compare each bit of the binary representation of the int, and return the result. It's not something you generally need to concern yourself with, and is outside the scope of this tutorial.

**Assignment operators (=, +=, -=, *=, /=, %=)**

As already discussed in the Equality Operators section, assignment and equality are different things. Assignment means "take the evaluated value on the right, and assign it into the variable on the left, then return that value if necessary" Of course, this means that there must be a variable on the left for this to be a valid expression. Some examples of assignment:

int x = 1; //assign 1 to x. int y = x + 1; //evaluate x + 1, then assign the result (2) to y.

It's important to note that once an assignment is evaluated, it returns the value on the right as a result. This means that an assignment can be used in

*another*assignment!

int x = 1; int y; int z = y = 2;

In this example, z is to be assigned the result of (y = 2). So the compiler evaluates y = 2. 2 is assigned to y, then 2 is returned. Now that y = 2 evaluated to 2, z is assigned 2.

This is convoluted and not generally used.

Now, there are several other operators mentioned (+=, -=, /=, *=, %=). Basically, these are the combination of assignment and arithmatic. For example: x += 5; is exactly the same as x = x + 5. See? A combination of assignment and arithmatic. This works the same for each of these operators, except with their own arithmatic operator (- for -=, * for *=, etc).

**Ternary Operator**

This is the only ternary operator in C#: the conditional operator (?:). Here's an example of the pattern it follows:

x = a ? b : c;

That is the equivalent of this:

if(a) x = b; else x = c;

Therefore, a must evaluate to a bool, and b and c must evaluate to the same type as x.

A somewhat more practical example:

string longString = "abcdefghijklmnop"; string shortString = longString.Length > 5 ? longString.Substring(0, 5) : longString;

This says "if longString is longer than 5, assign the Substring of longString to shortString. Otherwise, just assign longString to shortString."

**In Conclusion**

This in no way covered every operator that C# includes. There are several that are rarely used, or are simply more advanced than the scope of this topic. You can see all of them here:

http://msdn.microsof...(v=VS.100).aspx

Each is a link that you can follow to see it in action.

Another note: when defining a class, operators can be overloaded. We'll cover this in a later tutorial, but I want you to be aware that this is possible. Overloading an operator means that it can do something other than it's default operation. For example, the minus (-) operator is overloaded on DateTime in two ways: if you subtract a TimeSpan from a DateTime, you'll get a new DateTime. If you subtract a DateTime from a DateTime, you'll get a TimeSpan. Example:

DateTime dt1 = new DateTime(2011, 3, 21); //subtract a timespan of 5 days from dt1 to create dt2 DateTime dt2 = dt1 - TimeSpan.FromDays(5); //now, let's subtract dt2 from dt1 to get a timespan back TimeSpan difference = dt1 - dt2;

You don't need to understand how to do it at the moment, just the fact that some objects may have operators that behave differently than normal.

Hope you've enjoyed this installment of the C# Learning Series! Next one's coming soon!

See all the C# Learning Series tutorials here!