Indirectly Overloading the &amp&amp, ||, and ?: Operators




Indirectly Overloading the &&, ||, and ?: Operators

Problem

You need to control the handling of the &&, ||, and ?: operators within your data type; unfortunately, these operators cannot be directly overloaded.

Solution

Overload these operators indirectly by overloading the &, |, true, and false operators, as shown in Figure.

Overloading &, |, true, and false

public class ObjState
{
    public ObjState(int state)
    {
       this.state = state;
    }
    public int state = 0;
    public static ObjState operator &(ObjState obj1, ObjState obj2)
    {
       if (obj1.state >= 0 && obj2.state >= 0)
          return (new ObjState(1));
       else
          return (new ObjState(-1));
    }
    public static ObjState operator |(ObjState obj1, ObjState obj2)
    {
       if (obj1.state < 0 && obj2.state < 0)
          return (new ObjState(-1));
       else
          return (new ObjState(1));
    }
    public static bool operator true(ObjState obj)
    {
       if (obj.state >= 0)
          return (true);
       else
          return (false);
    }
    public static bool operator false(ObjState obj)
    {
       if (obj.state < 0)
          return (true);
       else
          return (false);
    }
    public override string ToString( ) 
    { 
       return (state.ToString( )); 
    }
}

This technique gives you complete control over the operations of the &&, ||, and ?: operators.

Alternatively, you can simply add an implicit conversion to bool:

	public class ObjState
	{
	   public ObjState(int state)
	   {
	      this.state = state;
	   }
	   public int state = 0;
	   public static implicit operator bool(ObjState obj)
	   {
	      if (obj.state == 0)
	      {
	         throw new InvalidOperationException( );
	      }
	      return (obj.state > 0);
	   }
	}

This technique implements strict Boolean logic; the first technique (overriding the &&, ||, and ?: operators) gives you more freedom to stray from implementing strict Boolean logic.

Discussion

While you cannot overload the &&, ||, and ?: operators directly, you can overload them indirectly by overloading the &, |, true, and false operators. The &&, ||, and ?: operators then use the overloaded &, |, true, and false operators for their calculations.

The && operator indirectly uses the false and & operators to perform a short-circuiting AND operation. Initially, the false operator is invoked to determine whether the first object is equal to false. If so, the righthand side of the expression is not evaluated and false is returned. If the false operator returns a true, the & operator is invoked next to perform the ANDing operation on the two objects. This initial test using the false operator enables the operator to short-circuit the operation.

The || operator works the same as the && operator, except that the initial test is done using the true operator rather than the false operator.

The ?: operator requires the overloading of the TRue operator to be indirectly overloaded. Note that this, in turn, requires the overloading of the false operator for symmetry. The ?: operator takes a conditional expression as input and evaluates either its TRue or false expression. This operator can be defined as follows:

	conditional-expression ? true-expression : false-expression

The ?: operator invokes the true operator to determine which expression of this operator should be evaluated. Note that if an implicit conversion to bool exists, it will be used in preference to the true operator.

When implementing these operators, you should first check to determine whether any parameters in the overloaded operator methods were set to null. The code for the overloaded & operator has been modified to do this:

	public static ObjState operator &(ObjState obj1, ObjState obj2)
	{
	   if (obj1 == null || obj2 == null)
	   {
	      throw (new ArgumentNullException("Neither object may be null.")); 
	   }
	   if (obj1.state >= 0 && obj2.state >= 0)
	      return (new ObjState(1));
	   else
	      return (new ObjState(-1));
	   }

See Also

See the "Operator Overloading Usage Guidelines," "Overloadable Operators," and "Operator Overloading Tutorial" topics in the MSDN documentation.