null
在条件限制中未评估为false
的原因是什么?
我首先考虑分配以避免使用=
而不是==
的错误,但编译器很容易禁止这样做。
if (someClass = someValue) // cannot convert someClass to bool. Ok, nice
if (someClass) // Cannot convert someClass to bool. Why?
if (someClass != null) // More readable?
我认为假设null
表示false
是合理的。还有其他语言也使用它,因为它没有我的错误。
编辑:我当然是指参考类型。
Daniel Earwicker对分配错误的好评......这个编译没有警告,因为它评估为bool
:
bool bool1 = false, bool2 = true;
if (bool1 = bool2)
{
// oops... false == true, and bool1 became true...
}
答案 0 :(得分:23)
这是C#语言中的特定设计功能:if
statements accept only a bool
。
IIRC这是为了安全:具体来说,你的第一个if (someClass = someValue)
无法编译。
编辑:一个好处是它使if (42 == i)
约定(“yoda比较”)变得不必要。
答案 1 :(得分:22)
“我认为假设null意味着错误”
是合理的不在C#中。 false是一个布尔结构,一个值类型。值类型不能具有空值。如果你想做你所做的事情,你必须创建特定类型的自定义转换器为布尔值:
public class MyClass
{
public static implicit operator bool(MyClass instance)
{
return instance != null;
}
}
通过上述内容,我可以做到:
if (instance) {
}
等
答案 2 :(得分:13)
“我认为假设null意味着错误”
是合理的我不同意。恕我直言,错误意味着“不”。 Null意为“我不知道”;即完全不确定。
答案 3 :(得分:5)
在数据类型的实例中会想到一件事,比如int? Int不能为空,所以它们总是评估为真吗?你可以假设int = 0是假的,但是开始变得非常复杂,因为0是一个有效值(其中0可以评估为true,因为编程器设置它)而不仅仅是默认值。
有很多边缘情况,其中null不是一个选项,或者有时它是一个选项,有时则不是。
他们提出这样的事情来保护程序员不犯错误。它与你在案例陈述中无法做到的原因相同。
答案 4 :(得分:5)
只需使用if(Convert.ToBoolean(someClass))
http://msdn.microsoft.com/en-us/library/wh2c31dd.aspx
参数
value类型:System.Object实现的对象 IConvertible接口,或null。 返回值
类型:System.Boolean true或false, 这反映了返回的价值 调用IConvertible.ToBoolean 基础类型的方法 值。如果value为null,则为方法 返回false
答案 5 :(得分:4)
据我所知,这是一个你在动态语言中看到的功能,C#不是这种功能(根据语言规范if
只接受bool
或表达式计算为{{1 }})。
我认为在每个案例中bool
为null
是不合理的。在某些情况下这是有道理的,但在其他情况下却没有。例如,假设您有一个可以有三个值的标志: set , unset 和 un-initialized 。在这种情况下, set 将为false
,未设置将为true
,而未初始化将为{{ 1}}。如您所见,在这种情况下,false
的含义不是null
。
答案 6 :(得分:3)
因为null和false是不同的东西。
一个完美的例子是布尔? FOO
如果foo的值为true,则其值为true 如果foo的值为false,则其值为false 如果foo没有赋值,则其值为null。
这是三个逻辑上独立的条件。
另一种想法
“我欠你多少钱?”
“ Nothing ”和“我没有那些信息”是两个截然不同的答案。
答案 7 :(得分:3)
null没有的原因是什么 在条件中评估为假?
我首先想到的是作业 避免使用
=
代替的错误==
这不是原因。我们知道这一点,因为如果要比较的两个变量恰好是bool
类型,那么代码将编译得非常愉快:
bool a = ...
bool b = ...
if (a = b)
Console.WriteLine("Weird, I expected them to be different");
如果b
为真,则打印消息(a
现在为真,使后续调试体验与消息一致,从而使您更加困惑......)
null
无法转换为bool
的原因只是C#避免了隐式转换,除非设计者要求用户定义类型。 C ++历史书充满了由隐式转换引起的痛苦故事。
答案 8 :(得分:3)
在结构上,大多数无法想到任何技术理由的人应该等于虚假"弄错了。
代码由CPU运行。
大多数(如果不是全部)CPU具有位,位组和位组的解释。也就是说,可以是Preferences > Java>Build Path > Classpath Variables.
,0
,1
,byte
,word
,dword
等等。< / p>
请注意,在x86平台上,字节是八位字节(8位),字通常是16位,但这不是必需的。较旧的CPU有4位字,甚至今天也是如此。低端嵌入式控制器通常使用每个字7或12位。
那就是说,有些事情是&#34;等于&#34;,&#34;零&#34;,&#34;更大&#34;,&#34;更少&#34;,&#34;更大或等于&#34;,或&#34;少于或等于&#34;在机器代码中。没有qword
,null
或false
。
作为惯例,true
为true
,1
为false
,0
指针为null
,{{1 },0x00
或0x0000
,具体取决于地址总线宽度。
C#是例外之一,因为它是间接类型,其中两个可能的值0x00000000
和0x0000000000000000
不是立即值,而是索引一个结构(在C中考虑0
,或在x86汇编中考虑1
。
这是设计的。
重要的是要注意,此类设计决策是精心制作决策,而传统,直接方式是假设enum
,{ {1}}和PTR
相等。
答案 9 :(得分:2)
C#没有像C ++那样转换参数。如果希望if
语句接受该值,则需要在布尔值中显式转换该值。
答案 10 :(得分:1)
与PHP,Perl等语言相比,它只是c#的类型系统。
条件只接受Boolean
个值,null不具有Boolean
类型,因此它在那里不起作用。
至于你在另一个评论中提到的C / C ++中的NULL例子,必须要说C和C ++都没有布尔类型(事后C ++通常有一个针对bool的类型转换,解析为int,但这是另一回事并且它们也没有空引用,只有NULL(=&gt; 0) - 指针。
当然,编译器设计人员可以将任何可空类型的自动转换实现为布尔值,但这会导致其他问题,即:
假设foo
不 null
:
if (foo)
{
// do stuff
}
哪种状态是真的?
总是如果它不是空的?
但是,如果您希望您的类型可以转换为布尔值(即来自您的三态或量子逻辑类),该怎么办?
这意味着你会有两种不同的转换,包括隐式转换和显式转换,这两种转换都会有不同的行为。
我甚至不敢想象如果你做的话会发生什么
if (!!foo) // common pattern in C to normalize a value used as boolean,
// in this case might be abused to create a boolean from an object
{
}
我认为强制(foo == null)
是好的,因为它也增加了代码的清晰度,更容易理解你真正检查的内容。