Behind the Scenes Look at C#: Operators, continued - Operator overloading, first visit
(Page 2 of 5 )
Why do we need to overload operators? A student asked me this question two years ago. The expression "operator overloading" explains itself. You overload the operator with a new type to simulate the built-in types behavior. For example, the + operator has been overloaded to work with built-in types, so you can write arithmetic expressions like result = x + y (where result, x and y are of the decimal data type). With operator overloading, C# gave us the ability to write expressions like Course1 = Course1 + student1 instead of Course1.AddStudent(student1) to simulate the behaviors of built-in types and to express a level of abstraction to your types.
You can overload many of the operators except for the new operator, because it doesn't makes any sense to overload it; it's used to instantiate an object. The typeof operator can't be overloaded either, because it has one function (type information). The cast operator () and the array index operator [] can't be overloaded. The Assignment operator = and the Short Circuit OR ||, And && operators can't be overloaded.
In C# there's no construction that defines new operators, so we use operator overloading to overload the operators to work with our types. The rules of operator precedence apply to both built-in types and user-defined types. Let's take a look at an example of how to overload the + operator. Copy the following code and paste it into a file with the extension .cs, then compile the file.
using System;
namespace Operators
{
class Class1
{
static void Main(string[] args)
{
Number i = new Number();
i.aNumber = 90;
i.aDecimal = .5m;
i = i + 9;
Console.WriteLine(i.aNumber);
Console.WriteLine(i);
Console.ReadLine();
}
}
public class Number
{
public int aNumber;
public decimal aDecimal;
public static Number operator+(Number num, int x)
{
num.aNumber = num.aNumber + x;
return num;
}
public override string ToString()
{
return Convert.ToString(this.aNumber + this.aDecimal);
}
}
}
Run the application and you will get the following result to the console window:

I know that you have a lot of questions, such as how did we add an object of type Number to an int variable? And what does this static method with the operator+ keyword do?
First let's discuss the class Number. This class contains two public fields, one int to store an integer value and the other of type decimal to store a decimal value. It also contains two methods. The method ToString() just prints the string representation of the object and, in our class Number, it prints the value of the int field concatenated with the value of the decimal field. The magic of operator overloading comes with the static method operator+. Let's take a look at this method:
public static Number operator+(Number num, int x)
{
num.aNumber = num.aNumber + x;
return num;
}
This method overloads the + operator to work with the Number type. You should note that the logic of the operations that this operator performs is encapsulated inside the method. This method is public, so you can use the overloaded version of the addition operator on the Number class instances. If you think about, it you will find that this is a public method, so it can be called from client code. The method is also static, because it's a general method that can be used by all the instances of the class Number. So it's public and static, and so far it's much more like any method you code in C#.
Next is the return data type, which is of type Number, which makes sense (just a minute and we will talk about that). After the return data type comes the keyword operator, followed by the operator itself, which in our example is the addition operator +. Note the interesting parameter list. The first parameter is a Number type, and the second is of type int. This means that when you use (call) the + operator with the Number type, you need to supply an instance of type Number and an int instance. In our example you can't use the addition operator with two instances of the Number class, as with the following code:
static void Main(string[] args)
{
Number i = new Number();
i.aNumber = 90;
i.aDecimal = .5m;
Number o = new Number();
i.aNumber = 80;
i.aDecimal = .7m;
i = i + o;
Console.WriteLine(i.aNumber);
Console.WriteLine(i);
Console.ReadLine();
}
This code will not compile, and it will generate the following error: "Operator '+' cannot be applied to operands of type 'Operators.Number' and 'Operators.Number'" because the definition of the operator overload method accepts the first paramter of type Number and the second of type int. We will modify the method to accept two parameters of type Number later. At any rate, the code inside the method is very simple, we just add the value of the current Number instance to the x and return this new instance.
In the Main method we simply create an object of type Number and set both the int and the decimal fields, then we add the value 9 to the i object and print the value of i.aNumber, which is now 99 after the addition operator usage. The method ToString() is the default method on objects, so it can be called implicitly by specifying the name of the object. In our example "Console.WriteLine(i);", this method returns a string that represents the number (we just concatenate both the int and the decimal fields to prove that there's no change to the decimal field). I imagine you want to investigate the MSIL code to see what's going on behind that. Load the application with the Ildasm.exe tool and navigate to the Number class.

The C# compiler has generated a method called op_Addition in the class Number to do the job of addition, so as we said before the runtime doesn't know about operators because the MSIL code contains a method to do the job. Now navigate to the Main method.

The highlighted line is a call to the method op_Addition of the class Number. Note the parameters here. It's very interested because you can learn more than you can imagine from the MSIL code. I can't discuss all of the MSIL instructions we encounter because it will take a lot of pages, so I may write another series about MSIL code soon. Let's take a look at the op_Addition MSIL code.

The first thing that you have to note here is the add instruction. Think about it for a minute please. We need to add two integers (the num.aNumber and the argument x) and, as we already know, the MSIL add instruction adds two integers, so in the method we have used the + operator on two integers. These are steps for doing the overloading, and at the end of these steps you have to find the MSIL arithmetic instructions.
Let's go further with this example. Can we modify the above example to return an int instead of an object of type int?
Next: Can we do that? >>
More C# Articles
More By Michael Youssef