c# - Implicit (bool) and == operator override - handle if statements correctly -
i have custom class implement both ==
, implicit
boolean operator.
is correct way handle possible, if ==/!= statements , expected result? this:
public class foo { public bool result { get; set; } public static bool operator ==(bool @bool, foo foo) { return equals(foo, @bool); } public static bool operator !=(bool @bool, foo foo) { return notequals(foo, @bool); } public static bool operator ==(foo foo, bool @bool) { return equals(foo, @bool); } public static bool operator !=(foo foo, bool @bool) { return notequals(foo, @bool); } public static bool operator ==(foo foo, foo foob) { return equals(foo, foob); } public static bool operator !=(foo foo, foo foob) { return notequals(foo, foob); } public static implicit operator bool(foo foo) { try { return foo.result; } catch { return false; } } private static bool equals(foo foo, foo foob) { if (object.equals(foo, null)) { if (object.equals(foob, null)) return true; return false; } if (object.equals(foob, null)) return false; return foo.result == foob.result; } private static bool notequals(foo foo, foo foob) { if (object.equals(foo, null)) { if (object.equals(foob, null)) return false; return true; } if (object.equals(foob, null)) return true; return foob.result != foo.result; } private static bool equals(foo foo, bool @bool) { if (object.equals(foo, null)) return true; return @bool == foo.result; } private static bool notequals(foo foo, bool @bool) { if (object.equals(foo, null)) return false; return @bool != foo.result; } }
i wondering fact seems need implement overloads either
if (new foo() != true)
and
if (true != new foo())
i think you've written code :-)
the following sufficient:
public class foo { public bool result { get; set; } public static implicit operator bool(foo foo) { return !object.referenceequals(foo, null) && foo.result; } }
the compiler know how implicitly convert variables of type foo
bool
. (and null
converted false
).
so, when write:
new foo() == false
the compiler use implicit type converter bool
value foo
, use standard equality operator bool
.
if @ il compiler generates expression find:
newobj instance void foobool.foo::.ctor() // new foo() call bool foobool.foo::op_implicit(class foobool.foo) // implicit operator (foo => bool) ldc.i4.0 // false ceq // equality operator (bool)
here's test:
static void main(string[] args) { asserttrue(new foo() == false); asserttrue(false == new foo()); assertfalse(new foo() != false); assertfalse(false != new foo()); asserttrue(new foo { result = true } == true); asserttrue(true == new foo { result = true }); assertfalse(new foo { result = true } != true); assertfalse(true != new foo { result = true }); } static void asserttrue(bool value) { console.writeline(value ? "ok" : "not ok"); } static void assertfalse(bool value) { console.writeline(value ? "not ok" : "ok"); }
it prints ok
each test. simplified code should fulfill needs if understood them correctly.
update
to allow equality operator work instances of foo
(which may null):
public static bool operator ==(foo a, foo b) { if (object.referenceequals(a, b)) { return true; } else if (object.referenceequals(a, null)) { return !b.result; } else if (object.referenceequals(b, null)) { return !a.result; } else { return a.result == b.result; } }
you should implement inequality operator:
public static bool operator !=(foo a, foo b) { return !(a == b); }
and override gethashcode
+ equals
public override int gethashcode() { return this.result ? 1 : 0; } public override bool equals(object obj) { if (object.referenceequals(obj, null)) { return !this.result; } type t = obj.gettype(); if (t == typeof(foo)) { return this.result == ((foo)obj).result; } else if (t == typeof(bool)) { return this.result == (bool)obj; } else { return false; } }
Comments
Post a Comment