C# Operator Overloading

Discussion in 'C#' started by usmanmalik, Feb 11, 2014.

  1. usmanmalik

    usmanmalik New Member

    Joined:
    Dec 28, 2013
    Messages:
    19
    Likes Received:
    14
    Trophy Points:
    0
    Operator overloading is one of the most fascinating and interesting object oriented programing concept which was first integrated in C++ language. As we know that C# integrates the robustness of C++ with delicacies of Java; therefore it has also inherited the concept of operator overloading from C++.

    If you have been integrating object oriented principles while writing programs, you should have an idea about method overloading. In method overloading we write different methods with same name to achieve different functionality from them. Operator overloading extends this concept to C# operators. With operator overloading you can add, subtract and perform virtually all functionality on objects which you achieve with ordinary operators. For example, you can add two objects like

    Object o1, o2, o3;

    o3= o1 + o2;

    This article has been divided into three sections. In the first section, you will learn how you can overload operators to operate on two objects of custom data types. In the following section, we have extended the concept and have explained how overloaded operators can operate on custom and primitive data types simultaneously and in the last and final section we have described how operator overloading can be used for data conversion purposes, we have described with the help of example, how you can convert primitive data types to user defined or custom data types and vice-versa. Now, let us get straight to the business.

    Operator Overloading Rules



    There are some rules that must be followed while overloading an operator.
    • The operator function cannot be private; it must be static as well as public.
    • The keyword operator must be prefixed with the operator you want to overload.
    • The operands of the overloaded operator should be passed in the overloaded operator function parameter.
    • The result of the expression will be returned via the return type of the function.
    • Off all the operands or parameters that are passed to function, one parameter must be the one in which operator function has been defined.
    Without wasting any further theory, let’s jump straight to a code sample, which will help you grasp the concept in a more effective manner. Have a look at Example1.

    Example1

    Code:
    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    public class ClassA
    {
        int num;
        
        public  ClassA( int num)
        {
            this.num = num;
        }
    
        public int getvalue()
        {
            return num;
        }
    
        public static ClassA operator + (ClassA a, ClassA b)
        {
            return new ClassA(a.num + b.num);
        }
    }
    
    namespace CSharpTutorial
    {
        class Program
        {
            static void Main(string[] args)
            {
                ClassA obj1, obj2, obj3;
    
                obj1 = new ClassA(10);
                obj2 = new ClassA(20);
                obj3 = obj1 + obj2;
    
                Console.WriteLine("The sum of object1 and object2 is: " + obj3.getvalue());  
                Console.ReadLine();
            }
        }
    }
    
    Carefully read the code in Example1. We have declared a class which we have named ClassA. Inside this ClassA, we have declared a member num of type integer. Next we have defined single parameter constructor which is used to initialize the value of num. We have then inserted a method in ClassA named getvalue() which actually returns the value of num.

    Next lines are important in ClassA. We have inserted an operator function which actually takes two objects of ClassA as parameter and then perform the addition of their num variable. The result of the addition has been passed into another anonymous object as parameter and then it is returned back to the calling function. While declaring this operator function we have followed all the rules which we described earlier. We have made the function public static. Also, the operands have been passed as the parameters. We said of all the parameters that are passed to the operators, at least one of them should be that type in which the operator function has been defined. In our operator function both of the parameters are of type ClassA which is also the class in which operator function has been defined.
    Code:
    public static ClassA operator + (ClassA a, ClassA b)
    {
        return new ClassA(a.num + b.num);
    }
    
    Now, come to the main method inside the Program class. In main method we have declared three objects of ClassA and we have named them obj1, obj2 and obj3. We initialized the objects obj1 and obj2 with 10 and 20 respectively. Now, the num variable of obj1 will hold value 10 and num variable of obj2 will hold value 20. Next line is the gist of this example.

    obj3 = obj1 + obj2;

    When compiler reached this point of code, it will first check that weather the types on the left and right of the operator are primitive types or custom types. If the types are primitive such as integer or float, it will simply add them by calling some built in arithmetic routine. However if the compiler finds that the types on the left and right of operator are custom types, it will check that if at least one of the types surrounding the operator have corresponding operator function declared in the body or not. When it finds the operator function it will pass the surrounding types as parameter to that operator function and then execute the operator function.

    We have declared that the return type of the operator would be ClassA type object containing the variable num equal to the sum of the num variables of the two ClassA objects passed to the operator as parameters or in other words operands. We have then called the getvalue method of the obj3 to show that it actually contains the sum of num variables of obj1 and obj2. The output Example1 is as follows.

    Output1

    [​IMG]

    Overloading operator for custom and primitive operand



    In Example1, we overloaded our operator to add two object of a custom type ClassA. What if we want to add a custom type with a primitive type? For instance what would we do if we want to add an object of ClassA with an integer? The solution is identical what we did when we add two custom types with exception that now we will replace one of the objects that have been passes as parameter with an integer. In Example2, we have modified Example1 to explain this concept. Pay attention to that.

    Example2

    Code:
    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    public class ClassA
    {
        int num;
        
        public  ClassA( int num)
        {
            this.num = num;
        }
    
        public int getvalue()
        {
            return num;
        }
    
        public static ClassA operator + (ClassA a, int n)
        {
            return new ClassA(a.num + n);
        }
    }
    
    namespace CSharpTutorial
    {
        class Program
        {
            static void Main(string[] args)
            {
                ClassA obj1, obj2, obj3;
    
                obj1 = new ClassA(10);
                obj3 = obj1 + 30;
                Console.WriteLine("The sum of object1 and object2 is: " + obj3.getvalue());
    
                obj3 += 30;
                Console.WriteLine("The sum of object1 and object2 is: " + obj3.getvalue());  
                Console.ReadLine();
            }
        }
    }
    
    You will see only a little difference between Example and Example2 that too is in the operator function. You can see that operator function now takes two arguments of which one is the custom type ClassA and the other one is the integer type variable. Inside the operator function we have added the num variable of ClassA with the integer that has been passed and second parameter. We have then created and anonymous object and passed it the sum and returned it back to the calling function.

    Inside the main function we added obj1 and the some integer and stored the resultant value in obj2 as we did in the Example1, we then called the getvalue function and displayed the value of num variable of object three which now contains the sum of obj1 and some integer which Is 30 in this case. The result will be 40 which has been displayed in the output.

    Next come to this line

    obj3 += 30;

    We know that for primitive types the above line equals obj3 = obj3 + 30; we know that num variable of obj3 now contains value 40. We are adding 30 to it. Now the result of this expression would be 70 which have been displayed in the second line of the output.

    Output2

    [​IMG]

    Using this technique, you can overload operators to perform arithmetic operations on all types of primitive as well as custom data types.

    Conversion between custom and primitive types through overloaded operators



    Operator overloading is not limited to arithmetic or logical operators, using overloaded implicit and explicit operators we can convert one data type to another. For Example, we can overload the aforementioned operators for converting integer type to a custom type ClassA which we have studied in Example1 and Example2, and vice versa. We will see with the help of an Example that how we can implement custom type conversion logic. Have a look at Example3.

    Example3

    Code:
    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    public class ClassA
    {
        int num;
        
        public  ClassA( int num)
        {
            this.num = num;
        }
    
        public int getvalue()
        {
            return num;
        }
    
        public static explicit operator ClassA(int a)
        {
            return new ClassA(a);
        }
    
        public static implicit operator int(ClassA obj)
        {
            return obj.getvalue();
        }
    }
    
    namespace CSharpTutorial
    {
        class Program
        {
            static void Main(string[] args)
            {
                // Explicit conversion from primitive type to custom type
                ClassA obj1 = (ClassA)40;
                Console.WriteLine("Explicit conversion from int to ClassA type: "+obj1.getvalue());
    
                // Implicit Conversion from custom to primitive data type
                int num = obj1;
                Console.WriteLine("Implicit conversion from ClassA to integer type: " + num);
                Console.ReadLine();
            }
        }
    }
    
    Look at the code in the above example. Again we have the same class ClassA. Now it contains two new overloaded operator methods. First look at the following method.
    Code:
    public static explicit operator ClassA(int a)
    {
        return new ClassA(a);
    }
    
    This method shows that when an integer type variable Is being converted explicitly to ClassA type variable, this method should be called. We can see that the parameter it takes is integer type and the type to which we want to convert is ClassA. The explicit keyword in the operator function shows that this method would be called when explicit conversion is being done. For example:

    ClassA obj1 = (ClassA)40;

    In the above line we are explicitly casting integer into an object of ClassA, when the above line of code executes, the method we discussed above will be called. Inside the method, a new object of type ClassA will be created which will be passed the value of integer variable that has been passed as parameter to operator function and the object will be returned back to calling function. This was the explicit conversion.

    Now come towards our second method.
    Code:
    public static implicit operator int(ClassA obj)
    {
        return obj.getvalue();
    }
    
    This overloaded operator method takes object of ClassA as a parameter and then converts it into integer. Note, that we have prefixed implicit operator before the keword operator which means that this conversion will be done implicitly. So this method will be called when we write following line in main function.

    int num = obj1;

    The output of the Example3 is as follows:

    Output3

    [​IMG]

    From the above two methods we can infer following general rules while perform conversions using overloaded operators.
    • The type which we want to convert from should be passed in the parameter of the overloaded operator. For example if you want to convert from integer to custom type. The integer should be in the parameter of the operator function.
    • The type into which we want to convert should be placed right before the parameter brackets in operator function declaration
    • If you want to convert between types implicitly, prefix implicit keyword before the operator keyword in the function definition. Same goes for the explicit conversion.
    Following these rules, you can convert virtually all types of primitive and custom variables into each other.

    Operator overloading is a very vast and complex subject, which requires continuous practice and focus to be comprehended thoroughly. I would advise you to go through the above example more than once and try to solve complex overloading examples. For example, I would advise you to try conversion between object of two different types. That is an interesting problem and will widen your horizon and help you understand the concept more effectively. In case you face any problem, leave a reply and I will be back to help solve it for you!
     
    Last edited by a moderator: Jan 21, 2017
    shabbir likes this.

Share This Page

  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice