当前位置:  开发笔记 > 编程语言 > 正文

为什么可空的bool不允许if(可为空)但允许if(nullable == true)?

如何解决《为什么可空的bool不允许if(可为空)但允许if(nullable==true)?》经验,为你挑选了2个好方法。

此代码编译:

private static void Main(string[] args)
{
    bool? fred = true;

    if (fred == true)
        Console.WriteLine("fred is true");
    else if (fred == false)
         Console.WriteLine("fred is false");
    else Console.WriteLine("fred is null");
}

此代码无法编译.

private static void Main(string[] args)
{
    bool? fred = true;

    if (fred)
        Console.WriteLine("fred is true");
    else if (!fred)
         Console.WriteLine("fred is false");
    else Console.WriteLine("fred is null");
}

我想如果(booleanExpression == true)应该是冗余.在这种情况下为什么不呢?



1> Jon Skeet..:

有没有从隐式转换Nullablebool.这里从隐式转换boolNullable,这就是发生(在语言方面),以每个在第一个版本的布尔常量的东西.所述bool operator==(Nullable, Nullable然后操作者施加.(这与其他提升的运营商并不完全相同 - 结果只是bool,而不是Nullable.)

换句话说,表达式'fred == false'是类型bool,而表达式'fred'是类型,Nullable因此您不能将它用作"if"表达式.

编辑:为了回答这些评论,从来没有一个隐含的转换Nullable,T并且有充分的理由 - 隐式转换不应该抛出异常,除非你想要null隐式转换为default(T)没有其他许多可以做的事情.

此外,如果隐式转换轮两种方式,如"可空非空+"的表达是非常混乱的(对于支持+,喜欢的类型int).+(T?,T?)和+(T,T)都可用,具体取决于转换的操作数 - 但结果可能非常不同!

我身后的决定,只有从一个显式转换100%NullableT.


100%同意禁止Nullable - > T的隐式转换.隐式转换不应该抛出.它维护了简单的规则,暗示=安全,显性=危险.

2> Charles Bret..:

因为fred不是布尔值.它是一个结构体,它有一个名为IsNull或HasValue的布尔属性,或者其他......名为fred的对象是包含布尔值和值的复合复合对象,而不是基本布尔本身......

下面,例如,如何实现Nullable Int.通用Nullable几乎可以肯定地实现(但通常).您可以在此处看到如何实现隐式和显式转换.

public struct DBInt
   {
       // The Null member represents an unknown DBInt value.
       public static readonly DBInt Null = new DBInt();
       // When the defined field is true, this DBInt represents a known value
       // which is stored in the value field. When the defined field is false,
       // this DBInt represents an unknown value, and the value field is 0.
       int value;
       bool defined;
       // Private instance constructor. Creates a DBInt with a known value.
       DBInt(int value) 
       {
              this.value = value;
              this.defined = true;
       }
       // The IsNull property is true if this DBInt represents an unknown value.
       public bool IsNull { get { return !defined; } }
       // The Value property is the known value of this DBInt, or 0 if this
       // DBInt represents an unknown value.
       public int Value { get { return value; } }
       // Implicit conversion from int to DBInt.
       public static implicit operator DBInt(int x) 
       { return new DBInt(x); }

       // Explicit conversion from DBInt to int. Throws an exception if the
       // given DBInt represents an unknown value.
       public static explicit operator int(DBInt x) 
       {
              if (!x.defined) throw new InvalidOperationException();
              return x.value;
       }
       public static DBInt operator +(DBInt x) 
       { return x; }
       public static DBInt operator -(DBInt x) 
       { return x.defined? -x.value: Null; }
       public static DBInt operator +(DBInt x, DBInt y) 
       {
              return x.defined && y.defined? 
                      x.value + y.value: Null;
       }
       public static DBInt operator -(DBInt x, DBInt y) 
       {
              return x.defined && y.defined?  
                      x.value - y.value: Null;
       }
       public static DBInt operator *(DBInt x, DBInt y) 
       {
              return x.defined && y.defined?  
                      x.value * y.value: Null;
       }
       public static DBInt operator /(DBInt x, DBInt y) 
       {
              return x.defined && y.defined?  
                     x.value / y.value: Null;
       }
       public static DBInt operator %(DBInt x, DBInt y) 
       {
              return x.defined && y.defined?  
                      x.value % y.value: Null;
       }
       public static DBBool operator ==(DBInt x, DBInt y) 
       {
              return x.defined && y.defined?  
                     x.value == y.value: DBBool.Null;
       }
       public static DBBool operator !=(DBInt x, DBInt y) 
       {
              return x.defined && y.defined?  
                     x.value != y.value: DBBool.Null;
       }
       public static DBBool operator >(DBInt x, DBInt y) 
       {
              return x.defined && y.defined?  
                     x.value > y.value: DBBool.Null;
       }
       public static DBBool operator <(DBInt x, DBInt y) 
       {
              return x.defined && y.defined?  
                     x.value < y.value: DBBool.Null;
       }
       public static DBBool operator >=(DBInt x, DBInt y) 
       {
              return x.defined && y.defined?  
                      x.value >= y.value: DBBool.Null;
       }
       public static DBBool operator <=(DBInt x, DBInt y) 
       {
              return x.defined && y.defined?  
                     x.value <= y.value: DBBool.Null;
       }
       public override bool Equals(object o) 
       {
              try { return (bool) (this == (DBInt) o); } 
              catch  { return false; }
       }
       public override int GetHashCode() 
       { return (defined)? value: 0; }   
       public override string ToString() 
       { return (defined)? .ToString(): "DBInt.Null"; }   
   }

推荐阅读
360691894_8a5c48
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有