Overloading Short-circuit Operators

Introduction

Here we will discuss how to overload short-circuit operators in C#. This articles assumes knowledge of operator overloading in C#.

The short-circuit operators are && and ||. They work nearly the same as ampersand (&) and simple pipeline (|) but there are some differences how the short-circuit operators work and the ampersand single pipeline.

bool a=false;
bool b = true;
If(a & b)
//some code
If(a && b)
//some code

For a layman, both expressions will work the same and will generate the same output but for experienced programmers there is a difference between how the short-circuit (&&) and ampersand (&) work.

How a short-circuit works

In C# a short-circuit operator can used in a bool expression only . it will return true and depending on the condition in the control statement.

If the short-circuit finda an operand that can reflect the result of the expression then it will stop checking the remaining operands and execute the condition true or false that is being reflected by the operand.

In the code above in the if statement && will find that a is false and in the AND operator all the operands must be true in order to execute if the statement. In this case a is false so it will not check b and will transfer control to the else statement. The && and || operators do not work with integers or any other type except bool.

Working of ampersand or single pipeline operator

The main difference between a short-circuit and a single pipeline/ampersand operator is the & and | operators can work with integers too. It compares the two operands bitwise and ANDs them. The result can be stores in another integer variable as in the following:

int a =4&5// this will compare 4 and 5 bitwise and AND them in binary form
int b=4|5// this compare 4and 5 bitwise and OR them in binary form

Another difference is that the & and| operator check all the conditions, even if the result of the control statement is being reflected by the current operand.

bool a=false;
bool b = true;
If(a & b) // result of b will also be check event a reflect that the statement is false
//some code
If(b|a)// b reflect result of statement but it will still check a
//some code

Overloading short-circuit operator

C# did not allow overloading the short-circuit operator directly just like +,-,/,|,& and so on.

But there are certain rules if we fulfil them when can use a short-circuit operator for a user-defined data type or in a simple that can overload them. In fact we do not overload them but if the conditions are fulfilled then they are overloaded by the compiler logically.

Rules for overloading the short-circuit operator.

  1. | and & must be overloaded for the given class.
  2. | and & must return an object of the class for which they are overloaded.
  3. | and & must have a reference to an object of the class for which they are overloaded.
  4. True and false statements must be overloaded.

    If the above 4 rules are fulfilled by our program; we can use the short-circuit operator for a user-defined data type in overloaded form without actually overloading them.
  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Linq;  
  4. using System.Text;  
  5.   
  6. namespace operatorOverLoading  
  7. {  
  8.   
  9.     class demension  
  10.     {  
  11.         private int height;  
  12.         private int width;  
  13.         //two argument constructor for class  
  14.         public demension()  
  15.         {  
  16.             height = 0;  
  17.             width = 0;  
  18.         }  
  19.   
  20.         public demension(int h, int w)  
  21.         {  
  22.             height = h;  
  23.             width = w;  
  24.   
  25.         }  
  26.   
  27.         public void show()  
  28.         {  
  29.             Console.WriteLine("height  :" + height);  
  30.             Console.WriteLine("width  :" + width);  
  31.         }  
  32.   
  33.         public static demension operator |(demension d1, demension d2)  
  34.         {  
  35.             if (((d1.width != 0) || (d1.height != 0)) | ((d2.width != 0) || (d2.height != 0)))  
  36.                 return new demension(1, 1);  
  37.             else  
  38.                 return new demension(0, 0);  
  39.   
  40.         }  
  41.          
  42.         public static demension operator &(demension d1, demension d2)  
  43.         {  
  44.             if (((d1.width != 0) && (d1.height != 0)) & ((d2.width != 0) && (d2.height != 0)))  
  45.          
  46.                 return new demension(1, 1);  
  47.               
  48.             else  
  49.                 return new demension(0, 0);  
  50.               
  51.         }  
  52.           
  53.          
  54.          
  55.         public static bool operator true(demension op)  
  56.         {  
  57.             if ((op.width != 0) || (op.height != 0))  
  58.                 return true// at least one coordinate is non-zero   
  59.             else  
  60.                 return false;  
  61.         }  
  62.          
  63.         public static bool operator false(demension op)  
  64.         {  
  65.             if ((op.width == 0) && (op.height == 0))  
  66.                 return true// all coordinates are zero   
  67.             else  
  68.                 return false;  
  69.         }  
  70.          
  71.          
  72.     }  
  73.     class Program  
  74.     {  
  75.         static void Main(string[] args)  
  76.         {  
  77.             demension a = new demension(5, 6);  
  78.             demension b = new demension(10, 10);  
  79.             demension c = new demension(0, 0);  
  80.             if (b && a) Console.WriteLine("a && c is true.");  
  81.             else Console.WriteLine("a && c is false.");  
  82.   
  83.             if (a || b) Console.WriteLine("a || b is true.");  
  84.             else Console.WriteLine("a || b is false.");  
  85.   
  86.             if (a || c) Console.WriteLine("a || c is true.");  
  87.             else Console.WriteLine("a || c is false.");  
  88.               
  89.             Console.ReadKey();  
  90.         }  
  91.     }  

How the code will work

If (b&&a)

At first control will transfer to the false operator to check whether or not it is false for the operand a. If the false statement returns true then the short-circuit operator will not check b and control will transfer to the else statement.

Overloading short-circuit operator

If the false statement returns false then the & operator will be called for the b operand and checks if the statement inside the & operator is true. If so then two argument constructors will be called with (1,1) and this newly created object is returned to the b operand and the true statement is checked; if satisfied then it will return true and if not then it will return false.

The if statement inside the & operator is false. if so then two argument constructors will be called with (0,0) and this newly created object is returned to the b operand and the true statement is checked. If satisfied then it will return true if not it will return false.

Then depending on that the if or else will be executed in the main.