布尔运算符可以产生非布尔结果吗?

时间:2019-05-09 20:49:28

标签: c#

请注意,这个问题不是关于这种样式/约定的正确性,而只是关于布尔运算符的使用。只是想提一下提供上下文的样式。

Microsoft的C# Coding Conventions指出,“当变量的类型在赋值的右侧很明显时,允许对局部变量进行隐式键入。”

在以下代码中:

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

var z = x && y;

z声明中的布尔运算符是否使它的类型“明显”?换句话说,在C#中是否可以将&&xy一起使用而不是布尔值并产生非布尔值的结果?

4 个答案:

答案 0 :(得分:6)

是否保证&&||返回布尔值?不。它们几乎总是会产生布尔值吗?绝对可以。

通过针对&&返回非布尔值的计数器示例,请考虑以下几点:

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);
    }
}

现在,我们有了一个可以间接重载&&||运算符的类,它们返回的类型为Foo

规范对用户定义的&&||运算符说:

  

当&&或||的操作数时是声明适用的用户定义的运算符&或operator |的类型,以下两个必须为true,其中T是声明所选运算符的类型:

     

•返回类型和所选运算符的每个参数的类型必须为T。换句话说,运算符必须计算类型T的两个操作数的逻辑与或逻辑或,并且必须返回类型的结果T。

     

•T必须包含运算符true和false的声明。

现在,我们评估以下内容:

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

foo的类型为FooVal为4,因为5&4为4。

所有这些都表示,我不希望在非常特殊的情况下不会看到这种行为。

此外,如规范所指出的,&&||的结果必须是参数的类型。在bool && boolbool || bool场景中,该值应始终为bool。只要您对布尔值(而不是奇怪的随机非布尔类型)进行逻辑运算,就应该期望结果为bool

答案 1 :(得分:5)

是的,有可能返回不是布尔值的内容,只要它可以被评估为布尔值即可。

这需要您重载truefalse运算符,并采用以下奇怪的类型:

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);    
    }
}

现在,当您执行以下操作时:

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

result不是布尔值,而是MyStrangeType

Try it out!

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

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

输出:

  

MyStrangeType

答案 2 :(得分:0)

我可能会误解您的问题,但这可能对您或其他人有帮助。 有“是”运算符。您可以检查一个名副其实的东西。 例如; var z = x是bool && y是bool;

答案 3 :(得分:0)

您有两个独立的问题。

  

在C#中是否存在&&可以与x和y一起使用的情况   不是布尔值,并且产生的结果不是布尔值?

其他答案显示了这一点。

  

z声明中的布尔运算符是否使其类型“明显”?

是的,如果xy是傻子。由于应用于布尔操作数的&&运算符始终返回规范中定义的bool。除了使用dynamic关键字的情况外,C#实际上不允许相同的重载使用变量返回类型。但是随后var也被推断为dynamic