因为 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"; }
}