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