Adam C
Adam C

Reputation: 103

Can Boolean operators ever produce a non-Boolean result?

Please note, this question is not about the correctness of this style/convention, only about the use of Boolean operators. Just wanted to mention the style to give context.

Microsoft's C# Coding Conventions states that implicit typing is allowed "for local variables when the type of the variable is obvious from the right side of the assignment."

In the following code:

bool x = X();
bool y = Y();

var z = x && y;

Does the Boolean operator in the declaration of z make its type "obvious"? In other words, is there any situation in C# where && can be used with an x and y that are not Boolean, and produce a result that is not Boolean?

Upvotes: 1

Views: 560

Answers (4)

adjan
adjan

Reputation: 13684

You have two separate questions.

is there any situation in C# where && can be used with an x and y that are not Boolean, and produce a result that is not Boolean?

This is shown by the other answers.

Does the Boolean operator in the declaration of z make its type "obvious"?

Yes, if x and y are bools. Since the && operator applied on boolean operands always returns a bool, which is defined in the specification. C# doesn't really allow variable return types for the same overload, except for the case of using the dynamic keyword. But then var is just inferred as dynamic as well.

Upvotes: 0

Jonathon Chase
Jonathon Chase

Reputation: 9704

Are && and || guaranteed to return a boolean? No. Will they almost always result in a boolean? Most definitely.

By way of a counter example for && returning a non-boolean, consider the following:

public class Foo
{
    public int Val { get; }
    public Foo(int val) { Val = val; }
    
    public static bool operator true(Foo val) {
        return val.Val > 0;
    }
    public static bool operator false(Foo val) {
        return val.Val <= 0;
    }
    
    public static Foo operator &(Foo left, Foo right) {
        return new Foo(left.Val & right.Val);
    }
    public static Foo operator |(Foo left, Foo right) {
        return new Foo(left.Val | right.Val);
    }
}

Now we have a class that has indirectly overloaded the && and || operators, and they return type Foo.

The specification has this to say about user defined && and || operators:

When the operands of && or || are of types that declare an applicable user-defined operator & or operator |, both of the following must be true, where T is the type in which the selected operator is declared:

• The return type and the type of each parameter of the selected operator must be T. In other words, the operator must compute the logical AND or the logical OR of two operands of type T, and must return a result of type T.

• T must contain declarations of operator true and operator false.

Now, we evaluate the following:

var foo = new Foo(5) && new Foo(4);

foo is of Type Foo, with a Val of 4, as 5 & 4 is 4.

All of that said, I would not expect to see this kind of behavior outside of very specific circumstances.

Additionally, as the specification points out, the result of && or || must be the type of the parameters. In a bool && bool or bool || bool scenario, this should always be bool. So long as you're doing your logical operations on booleans (and not strange random non-boolean types) you should expect the result to be a bool.

Upvotes: 6

user2228413
user2228413

Reputation:

I could maybe misunderstood your question but this maybe could help to you or someone else. There is "is" operator. You can check a veriable is a type of something. For example; var z = x is bool && y is bool;

Upvotes: 0

Ron Beyer
Ron Beyer

Reputation: 11273

Yes, it is possible for that to return something that is not a boolean as long as it can be evaluated as a boolean.

This requires you to overload the true and false operators, take this strange type:

public class MyStrangeType
{
    public static readonly MyStrangeType Strange1 = new MyStrangeType(0);
    public static readonly MyStrangeType Strange2 = new MyStrangeType(1);

    private int myValue;

    public int Value { get { return myValue; } }

    private MyStrangeType(int value)
    {
        myValue = value;    
    }

    public static bool operator true(MyStrangeType x) { return x.myValue == 1; } 
    public static bool operator false(MyStrangeType x) { return x.myValue != 1; }

    public static MyStrangeType operator &(MyStrangeType x, MyStrangeType y)
    {
        return new MyStrangeType(3);    
    }
}

Now when you do something like this:

var result = MyStrangeType.Strange1 && MyStrangeType.Strange2;

result is not a boolean but a MyStrangeType.

Try it out!

public class Program
{
    public static void Main()
    {
        var result = MyStrangeType.Strange1 && MyStrangeType.Strange2;

        Console.WriteLine(result.GetType().FullName);
    }
}

Outputs:

MyStrangeType

Upvotes: 5

Related Questions