Overloading == to return a non-boolean

Were you aware that you could overload == to return types other than boolean? I certainly wasn’t until I started reading through the lifted operators part of the C# 2 specification. It’s quite bizarre – here it is in action:

using System;

class Test
{
    public static string operator== (Test t1, Test t2)
    {
        return "Fish?";
    }
    
    public static string operator!= (Test t1, Test t2)
    {
        return "Not a fish?";
    }

    static void Main()
    {
        Test a = new Test();
        Test b = new Test();
        Console.WriteLine (a==b);
    }
}

That ends up printing “Fish?” to the console. Strange but true. When I asked about this on the newsgroup, one poster said that he did use this functionality for an ORM type of system – his == operator on two expressions would return another expression which represented the test for equality between the other two expressions. I can’t say I much like this idea, although I could see where he was coming from. (The C# spec does specifically discourage this sort of thing, which is at least a start).


So, dear readers, have any of you done this, and if so, why?

8 thoughts on “Overloading == to return a non-boolean”

  1. Jup, a lot of ORM “abuse” this feature to ease composition of sql statements. Since other options sucks this is quite a good compromise IMO and eases life of a developer a lot. Since it has a very specific range in ORMs (it usually works only on specific class derived classes) it doesn’t create any confusion.

  2. I don’t know if I was that person, but indeed I overload this operator on the entity field objects so you can construct compile-time checked expressions for filters in C# and VB.NET. As there’s no LINQ in .net 2.0 and .net 1.x, and there’s no way to create your own operators like in C++, this is a proper way to do it.

    I agree that it shouldn’t be abused, but in this particular context, the ‘==’ is of no use anyway, as the ‘==’ isn’t used to compare a field object, so there’s no real confusion.

    It’s a trade-off really. I didn’t want to overload these operators actually, though as I can’t create new ones, I had to. :)

  3. I just googled “define: ORM”, so now I’m wondering why so many people are programming Other Regulated Material.

  4. You could use it to return tri-state booleans like in sql (true,false,null). Maybe you also could implement fuzzy logic when == returns a float between 0 and 1.

  5. I ran across your blog while looking for stuff on Eclipse and enjoyed it enough I kept reading. Anyway, I have used this in C++ to build up expression trees. For instance, I want to build up a tree for the expression 5 * (x + y). Originally, the code looked like:

    new MultNode(new ConstNode(5), new PlusNode(new VarNode(“x”), new VarNode(“y”))

    The first step is to realize that you can put the allocations in a function, and do something like this:

    MultNode Mult(Node left, Node right) {
    return new MultNode(left, right);
    }

    Mult(Const(5), Plus(Var(“x”), Var(“y”)))

    But then you can realize that the Mult and Plus functions can be replaced by operator overloads, which let you change that to:

    MultNode operator +(Node left, Node right) {
    return new MultNode(left, right);
    }

    VarNode xv(“x”);
    VarNode yv(“y”);
    5 * (x + y)

    Then if you want to build up an expression tree for more general expressions — say, with comparisons — then you also want to overload operators < , <=, >, >=, ==, and != in the same way.

    This is perhaps abusing the operator overloading ability a little, but there is absolutely no question it improved code readability.

Comments are closed.