Microsoft.NET

……………………………………………….Expertise in .NET Technologies

Logical Operator Overloading in C# (OOP’s) – Part 17

Posted by Ravi Varma Thumati on July 13, 2009

C# Logical Operator Overloading

There are four logical operators that can be directly overloaded for a class. These are the NOT operator (!), the AND operator (&), the OR operator (|) and the exclusive OR or XOR operator (^). The short-circuit operators (&& and ||) cannot be overloaded directly. However, if the class meets certain conditions the short-circuit operators are enabled automatically.

This article uses the Vector class developed over previous articles. The Vector class represents a two-dimensional vector and already overloads arithmetic operators and the true and false operators.

Overloading the Binary Boolean Logical Operators

The Boolean binary logical operators are generally used in conditional processing operations and thus return a Boolean value, either true or false. To create an overloaded version of these operators, the syntax is the same as for other binary overloads, except that the return value is generally of the bool type.

public static bool operator logical-operator (

op-type operand,

op-type2 operand2

)

At least one of the operands must be of the same type as the containing class. This means that by providing the correct signature, you can permit logical operations between two classes of differing types.

Creating the Boolean AND Operator (&)

The three binary Boolean operators can be added to the Vector class using the syntax described above. When determining the results of each, a Vector will be deemed to equate to true if either of the co-ordinates is non-zero. If both the X and Y properties are zero, the Vector will be considered ‘false’.

Add the following operator overload to the Vector class to implement the AND function:

public static bool operator &(Vector v1, Vector v2)

{

bool v1flag = !((v1.X == 0) && (v1.Y == 0));

bool v2flag = !((v2.X == 0) && (v2.Y == 0));

return v1flag & v2flag;

}

The code evaluates each vector’s co-ordinates to create a Boolean representation in the ‘flag’ variables. An AND operation is then performed on the two flags and the result returned. You can test the code by changing the Main method of the program as follows and executing the console application.

static void Main(string[] args)

{

Vector v1 = new Vector(0, 0);

Vector v2 = new Vector(10, 0);

Console.WriteLine(v1 & v1);                 // Outputs “False”

Console.WriteLine(v1 & v2);                 // Outputs “False”

Console.WriteLine(v2 & v1);                 // Outputs “False”

Console.WriteLine(v2 & v2);                 // Outputs “True”

}

Creating the Boolean OR (|) and XOR (^) Operators

Using similar code, we can add the Boolean OR and XOR operators to the Vector class. Add the following two operator overloads to the class to implement the two logical functions.

public static bool operator |(Vector v1, Vector v2)

{

bool v1flag = !((v1.X == 0) && (v1.Y == 0));

bool v2flag = !((v2.X == 0) && (v2.Y == 0));

return v1flag | v2flag;

}

public static bool operator ^(Vector v1, Vector v2)

{

bool v1flag = !((v1.X == 0) && (v1.Y == 0));

bool v2flag = !((v2.X == 0) && (v2.Y == 0));

return v1flag ^ v2flag;

}

Again, these operators can be tested using a modified Main method:

static void Main(string[] args)

{

Vector v1 = new Vector(0, 0);

Vector v2 = new Vector(10, 0);

Console.WriteLine(v1 | v1);                 // Outputs “False”

Console.WriteLine(v1 | v2);                 // Outputs “True”

Console.WriteLine(v2 | v1);                 // Outputs “True”

Console.WriteLine(v2 | v2);                 // Outputs “True”

Console.WriteLine(v1 ^ v1);                 // Outputs “False”

Console.WriteLine(v1 ^ v2);                 // Outputs “True”

Console.WriteLine(v2 ^ v1);                 // Outputs “True”

Console.WriteLine(v2 ^ v2);                 // Outputs “False”

}

Overloading the Unary Boolean Logical Operator

Only one unary Boolean logical operator exists. This is the NOT operator (!) that switches a Boolean value between true and false. When overloaded using the unary syntax below, the value returned should be the opposite of the Boolean representation of the object. As with other unary operators, the type of the operand provided must be the same as the class that the declaration appears within.

public static bool operator !(op-type operand)

Creating the Boolean NOT Operator (!)

The NOT operator for the Vector class will examine the contents of the X and Y properties. As described above, if both co-ordinates are zero, the Boolean value for the object is false. However, as this is the NOT operator, we will perform the check and return true only when both values are zero. Add the following code to the class to provide the NOT operator:

public static bool operator !(Vector v)

{

return ((v.X == 0) && (v.Y == 0));

}

To test that the operator is working correctly, modify the Main method as follows:

static void Main(string[] args)

{

Vector v1 = new Vector(0, 0);

Vector v2 = new Vector(10, 0);

Console.WriteLine(!v1);                     // Outputs “True”

Console.WriteLine(!v2);                     // Outputs “False”

}

Enabling the Short-Circuit Operators

The short-circuit operators provide an additional variant of the AND and OR operators. In each case, the left-hand operand in the operation is examined in isolation first. When evaluating an AND where the first operand evaluates to false, the result of the operation will be false regardless of the value of the second operand. Similarly, when evaluating an OR operation where the first operand evaluates to true, the result will always be true. In these special cases, the right-hand operand is not evaluated at all, potentially improving performance.

The short-circuit operators cannot be overloaded directly. However, if two conditions are met in the class then the short-circuit operators are automatically made available. The two conditions are as follows:

  • The class must overload the normal logical operators (& and |) with the operation returning a value of the same type as the containing class. Each parameter of the operator must also be of the type of the containing class.
  • The true and false operators must be overloaded.

When the operator is invoked, the true or false operators are used to determine the status of the first operand. If this guarantees an outcome from the operation, the result is returned immediately. When the state of the first operand does not force an outcome, the AND or OR operator is used for the two values to determine the result.

Adding the Short-Circuit Operator Pre-Requisites to the Vector Class

The Vector class already includes overloaded true and false operators. To enable the short-circuit operators, we just need to add the correct signature for the AND and OR operators. As these must return a Vector result that can be evaluated as either true or false according to the results, this will return (0,0) if the operation equates to false and (1,1) for true.

Modify the code for the existing & and | operator overloads as follows:

public static Vector operator &(Vector v1, Vector v2)

{

bool v1flag = !((v1.X == 0) && (v1.Y == 0));

bool v2flag = !((v2.X == 0) && (v2.Y == 0));

if (v1flag & v2flag)

return new Vector(1, 1);

else

return new Vector(0, 0);

}

public static Vector operator |(Vector v1, Vector v2)

{

bool v1flag = !((v1.X == 0) && (v1.Y == 0));

bool v2flag = !((v2.X == 0) && (v2.Y == 0));

if (v1flag | v2flag)

return new Vector(1, 1);

else

return new Vector(0, 0);

}

You can test that the short-circuit operators are correct by modifying the Main method of the program. However, as the operators do not return a Boolean value, an if statement is required in order to test the results of the operations. This is demonstrated in the following code.

static void Main(string[] args)

{

Vector v1 = new Vector(0, 0);

Vector v2 = new Vector(10, 0);

if (v1 && v2)

Console.WriteLine(“v1 && v2 = true”);

else

Console.WriteLine(“v1 && v2 = false”);  // Outputs “v1 && v2 = false”

if (v1 || v2)

Console.WriteLine(“v1 || v2 = true”);   // Outputs “v1 || v2 = true”

else

Console.WriteLine(“v1 || v2 = false”);

}

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

 
%d bloggers like this: