此代码编译:
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)应该是冗余.在这种情况下为什么不呢?
有没有从隐式转换Nullable
到bool
.这里是从隐式转换bool
到Nullable
,这就是发生(在语言方面),以每个在第一个版本的布尔常量的东西.所述bool operator==(Nullable
然后操作者施加.(这与其他提升的运营商并不完全相同 - 结果只是bool
,而不是Nullable
.)
换句话说,表达式'fred == false'是类型bool
,而表达式'fred'是类型,Nullable
因此您不能将它用作"if"表达式.
编辑:为了回答这些评论,从来没有一个隐含的转换Nullable
,T
并且有充分的理由 - 隐式转换不应该抛出异常,除非你想要null
隐式转换为default(T)
没有其他许多可以做的事情.
此外,如果是隐式转换轮两种方式,如"可空非空+"的表达是非常混乱的(对于支持+,喜欢的类型int
).+(T?,T?)和+(T,T)都可用,具体取决于转换的操作数 - 但结果可能非常不同!
我身后的决定,只有从一个显式转换100%Nullable
以T
.
因为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"; } }