0

My code for operator overloading in C# for True and false is given below:

class LimitedInt
{
    public static bool operator true(LimitedInt x)
    {
        if (x.theValue > 10)
            return true;
        else
            return false;
    }
    public static bool operator false(LimitedInt x)
    {
        if (x.theValue < 10)
            return false;
        else
            return true;
    }
    public int theValue;
}

Now I am calling the True and the False methods like:

LimitedInt li1 = new LimitedInt();
li1.theValue = 10;
if (li1)
    Console.WriteLine("True Called");
else if (!li1)
    Console.WriteLine ("False Called");

For the last Line of the code "else if(!a)" i get the error:

Operator '!' cannot be applied to operand of type 'LimitedInt'

My question is how to call the False method then ?

Update: I am able to call the False overload as suggested by people here. First I have to add the overload of &:

public static LimitedInt operator &(LimitedInt t, LimitedInt s) { return t;}

Then to call false overload do this:

if (li1 && li1)
{
}

Hope this helps others too.

yogihosting
  • 5,494
  • 8
  • 47
  • 80

3 Answers3

4

First of all, this is a very poor use case for operator true and operator false. There are very few legitimate usages for defining these operators, and this is not one of them.

You would be better off defining an "is valid" method or property that returns a bool.

You would be even better off still by ensuring that your limited int is in a valid state when constructed.

Finally, a limited int is a good candidate for a struct, since it is logically an immutable value.

To answer the actual question that you asked:

My question is how to call the False method then?

As you note, the ! operator does not invoke operator false. It invokes operator !, and there isn't one. The only operation in C# which invokes operator false is &&:

x && y

is logically the same as

operator_false(x) ? x : (x & y)

Except that side effects of evaluating x only happen once, obviously.

Similarly

x || y

is

operator_true(x) ? x : (x | y)

As noted in a comment, the | and & operators must be defined on your type for this to work.

Eric Lippert
  • 647,829
  • 179
  • 1,238
  • 2,067
  • Don't you also need to overload operator `|` (in addition to `true` and `false`) to get `||` to work (and likewise with `&` and `&&`)? – Kyle Jun 28 '17 at 20:12
  • @Kyle: That's correct; thanks for noting that. – Eric Lippert Jun 28 '17 at 20:13
  • Now i have one question how to apply x || y in my code to call false overload, can you give me a specific code for it? – yogihosting Jun 28 '17 at 20:17
  • 1
    @yogihosting: Define the `&` and `|` operators, and then `&&` or `||` together two of your type. But *you should not do this in the first place*. This is a poor use of these operators; can you explain why you want to use them? – Eric Lippert Jun 28 '17 at 20:18
3

The operator ! does not call the true/false operators (if, and binary operators as && and || do. More precisely, | employs true and & employs false due to the underlying "short circuit" principle). And the fact that the operator is overloaded, does not mean that the type of your LimitedInt would suddenly change to bool.

In the sample you gave, you could avoid the unary !, add an overload for the & operator to the class and write:

if (li1)
    Console.WriteLine("True Called");
else if((li1 && li1) == false)
    Console.WriteLine ("False Called");

In else if, the first li1 forces evaluation of LimitedInt's false operator, then skips evaluation of the second operand and yields false, which we need to invert to get to the console output. You see how ugly this gets, so it is only for demonstration purposes and not something I would want to bother reviewers and other developers with.

There are already three very good answers here which together may explain it even better:

How does operator overloading of true and false work?
Why overload true and false instead of defining bool operator?
https://stackoverflow.com/a/598971/1132334

Cee McSharpface
  • 8,493
  • 3
  • 36
  • 77
  • I checked by puttiing your code - else if(false || li1). Now i get error - Operator '||' cannot be applied to operands of type 'bool' and 'LimitedInt' – yogihosting Jun 28 '17 at 20:20
  • 1
    @yogihosting: That's correct. **If you want to treat instances of your type as bools then implementing operator true and false is completely the wrong thing to do**. You seem hell bent on pursuing a very wrong solution to your problem, and are not explaining to us why you think it is the right thing to do. – Eric Lippert Jun 28 '17 at 20:21
  • right... operator & needs to be overloaded as well for this to work. sorry for this, I edited the information into the answer. I presume that you are experimenting and want to see the result that you expect, but I'd add to what @Eric states that this will be a maintenance nightmare for your fellow developers in case you are about to apply this to a real world project. – Cee McSharpface Jun 28 '17 at 20:23
  • @EricLippert thank you – yogihosting Jun 28 '17 at 21:01
  • @dlatikay thank you. I am able to call the False overload by your help. I did 2 things. 1) added the & overload 2) then to call false i did if(li1 && li1). – yogihosting Jun 28 '17 at 21:03
1

I suggest using implicit operator in the case:

 class LimitedInt {
   public int theValue;

   // Let's combine both true and false cases into bool and
   // make it implict to allow .Net implictly cast LimitedInt to bool before !:  
   public static implicit operator bool(LimitedInt value) {
     //DONE: validate public methods' arguments
     if (null == value)
       return false; //TODO: put the right value here (true or false)

     return value.theValue > 10;
   }
 }

In order to apply ! we allow .Net implictly cast LimitedInt to bool:

 LimitedInt li1 = new LimitedInt();

 if (!l1i) {
   ...
 }
Dmitry Bychenko
  • 180,369
  • 20
  • 160
  • 215