You need to control
the handling of the &&
,
||
, and ?
: operators within
your data type; unfortunately, these operators cannot be directly
overloaded.
Overload these operators indirectly by overloading the
&
, |
,
true
, and false
operators:
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.
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 operation stops and whatever is
on the lefthand side of the &&
operator is
returned. If the false
operator returns a
true
, the &
operator is
invoked next to perform the AND
ing 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 only requires the overloading of
the true
operator to be indirectly overloaded.
Note that overloading the true
operator 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 would 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)); }