3

I have following code:

public class Foo
{
    public static bool operator<(Foo l, Foo f)
    {
        Console.WriteLine("Foo!");
        return false;
    }
    //public static bool operator>(Foo l, Foo f)
    //{
    //    return f < l;
    //}
}

Compiler tells about error with message:

The operator 'Program.Foo.operator <(Program.Foo, Program.Foo)' requires a matching operator '>' to also be defined

It seems very weird for me. Why should I overload operator> ?

Vadim Martynov
  • 8,602
  • 5
  • 31
  • 43
Alex Aparin
  • 4,393
  • 5
  • 25
  • 51
  • 6
    Why is that weird? If you define when obj1 is less than obj2 you should also define when obj1 is greater than obj2 – Tim Schmelter Jan 23 '17 at 12:46
  • 6
    I'd say *not* overloading both would be 'weird'. It would certainly surprise me to find that `a < b` wasn't the same as `b > a`. – Charles Mager Jan 23 '17 at 12:47
  • Take a look at this question: [Why must we define both == and != in C#?](http://stackoverflow.com/questions/6916884/why-must-we-define-both-and-in-c) –  Jan 23 '17 at 12:47
  • @TimSchmelter, But I can never use opertor >. I don't understand such requirement. It seems like solution from c++ is very logical – Alex Aparin Jan 23 '17 at 12:48
  • Then overload it and make it do nothing or make it do the default behavior. –  Jan 23 '17 at 12:49
  • @arbitrarystringofletters, It is extra noise in code – Alex Aparin Jan 23 '17 at 12:50
  • 1
    @LmTinyToon No, it is a bug fixed on beforehand. – Patrick Hofman Jan 23 '17 at 12:51
  • If I don't use operator >, why should I redefine it in such manner. It is not logical – Alex Aparin Jan 23 '17 at 12:54
  • 3
    If you have a less-than operator, you also have a greater-than operator. If your `<` operator doesn't mean "less-than", you probably shouldn't have it. Use a method instead. An operator should have a clear meaning. – Dennis_E Jan 23 '17 at 12:55
  • 1
    _"But I can never use opertor >"_ - perhaps _you_ don't _now_ but will that always be the case? What about other people working on the code? They might use it? What are you going to do, go around and rip the **>** key off everyones' keyboard to prevent them from using it in your code? –  Jan 23 '17 at 12:55
  • @LmTinyToon Your current implimentation of `<` is not logical. Prehaps instead of overloading operators you should actually just right a method for whatever type of unique comparison you want. – juharr Jan 23 '17 at 12:56
  • @juharr, It is just sample. The core idea of example is why should I should overload also `operator >`. – Alex Aparin Jan 23 '17 at 12:57
  • @Dennis_E, If I have `operator <` I have `operator <`. In my opinion idea from c++ is more correct in such sense – Alex Aparin Jan 23 '17 at 12:59
  • 1
    @LmTinyToon Can you show us what the actual code is so we can understand why you'd only want `<`? – juharr Jan 23 '17 at 12:59
  • 1
    @LmTinyToon I suspect you misunderstand C++. While you can define only one operator, it doesn't mean it's a smart idea. `<` doesn't say anything about equality so it's not enough to compare values. Using `<` for **anything** other than comparison is a severe design bug – Panagiotis Kanavos Jan 23 '17 at 13:35
  • @LmTinyToon also note that **some** STL **containers** implement `==` as `!(x < y) && !(y < x)`. That's a container implementation feature though, not a C++ feature. Some don't. Some orderings aren't linear though so you need all operators. [Check the last commenct to this C++ answer](http://stackoverflow.com/a/10575783/134204) – Panagiotis Kanavos Jan 23 '17 at 13:43
  • @LmTinyToon don't confuse convenience with correctness. From a correctness standpoint, it's better to be explicit. It may not be as convenient, but it's definitely safer – Panagiotis Kanavos Jan 23 '17 at 13:45
  • @PanagiotisKanavos, Yes, I agree. I saw assertions of such kind. – Alex Aparin Jan 23 '17 at 13:47
  • @LmTinyToon Adding to [Panagiotis Kanavos's](http://stackoverflow.com/users/134204/panagiotis-kanavos) fine comment about _"c++...smart idea"_, c/c++ allows you to do many things that are just straight up unpoliced and dangerous. It was concerns like this that drove the c# design and to prevent you from doing naughty things in your code and to _kittens_ –  Jan 25 '17 at 05:19
  • I have a situation where equality is not allowed, so opposite of `<` in this case is `>` and not `>=`. Operator pair in this case is really simple. Define operator `<` as it should work, and then its pair like that: `public bool operator > (ClassName a, ClassName b) { return !(a < b); }`. It could be done similarly if `<=`, and `>=` would need to be defined, too. Just calling the opposite with negated return can be used. – nobody Feb 15 '20 at 07:21

4 Answers4

4

Because that operator comes in pairs (like == and !=). It expects you to implement both to make sure you don't accidentally forget about it. If you say that < behaves differently, > should too, hence you are forced to overload it too.

As MSDN says:

User-defined types can overload the < operator. If a type overloads the "less than" operator <, it must also overload the "greater than" operator >.

Patrick Hofman
  • 153,850
  • 22
  • 249
  • 325
  • Looks like the MSDN page has now been updated and no longer says that, but to me that quote by itself sounds like it's talking more generally about other binary operators - for example overloading the binary '+' operator would also implicitly overload the '+=' operator (whereas when the comparison operators come in pairs, it's not implicit, but rather mandatory to be explicit). Seems like this note doesn't apply to comparison operators (as they don't have equivalent assignment operators), which could be why it's no longer included on the page. – NotEnoughData Apr 15 '19 at 06:31
  • 1
    @NotEnoughData Updated with the most recent documentation, which still upholds my answer. – Patrick Hofman Apr 15 '19 at 07:11
2

I can speculate that the reason is because of mathematical properties of inequality operators. https://en.wikipedia.org/wiki/Inequality_(mathematics)

> is inverse of <

It would not be surprising if compiler assumes those properties and is allowed to swap one for another. And even if compiler is not allowed to do that - resulting code would be unmanageable.

E.g. take refactoring tools as an example - inverting operators is a fairly common functionality in those.

bushed
  • 1,050
  • 1
  • 15
  • 27
  • 1
    >= is inverse of < if I am not mistaken. Your point holds though. – CSharpie Jan 23 '17 at 14:43
  • It seems that the inverse of < operator is still > (see wiki): aa However, opposite of (a > b) is (a <= b). That, however, does not work for nullables... – bushed Jan 23 '17 at 15:53
1

From Overloadable Operators:

The comparison operators, if overloaded, must be overloaded in pairs; that is, if == is overloaded, != must also be overloaded.

The reverse is also true, and similar for < and >, and for <= and >=.

Community
  • 1
  • 1
Am_I_Helpful
  • 18,735
  • 7
  • 49
  • 73
1

This is rule for comparison operators overloading. You can overload these operators only in pairs:

  • == and !=
  • < and >
  • <= and >=

The comparison operators, if overloaded, must be overloaded in pairs; that is, if == is overloaded, != must also be overloaded. The reverse is also true, and similar for < and >, and for <= and >=.

MSDN Source - Overloadable Operators (C# Programming Guide)

Roman
  • 11,966
  • 10
  • 38
  • 47