为什么 '\0'.ToString()==string.Empty 的结果是 FALSE?

5
我只是无法理解:如果'\0'是一个空字符,而字符串是一种字符数组,那么为什么会发生这种情况呢?
char value = '\0';
bool isEmpty = value.ToString() == string.Empty; // This returns FALSE because 
                                                 // '\0'.ToString() returns "\0" 
                                                 // where I expect it to be 
                                                 // string.empty

3
它不是空的,因为它包含一个空字符。这里不适用“以空字符结尾的字符串”的语义。 - Alex K.
我非常确定字符不能为空。 - Neil N
你的标题是关于字符串,而正文则与字符有关...它们是不同的。 - H H
5个回答

16

没有所谓的“空字符”,所以你在第一句话中的假设是不正确的。一个只有一个字符(U+0000)的字符串不同于空字符串-首先,第一个字符串的长度为1,而不是0。

对一个char调用ToString()将始终返回一个长度为1的字符串,其中仅包含该字符。在我看来,这是唯一有意义的事情。我不知道你为什么会期望其他任何东西。

虽然U+0000经常用作终止字符,但它并不等同于字符“不存在”。字符串“Foo\0Bar”与“FooBar”不同,不能被视为相同。

简而言之:.NET没有问题,出现问题的是你的期望 :)


3

由于"\0".Length == 1...

的原因...


2

我个人认为这应该被称为 null 字符而不是空字符。无论如何,它都是一个字符,一个包含字符的字符串并不是空的。


1
在C语言中,这将是一个空字符串。而在C#中,这段代码会创建一个包含一个字符的字符串,即NULL字符。因此,该字符串的长度为1,且不等于空字符串。

1
请注意,C语言中的空字符串只是一种约定俗成。我们都会聚在一起并同意将指向零字符的指针解释为长度为零的字符串。我们不必全部同意这个约定,也有一些不使用这个约定的C程序。例如,OLE自动化程序使用的BSTR数据结构就不遵循这个约定。 - Eric Lippert

0

.NET不使用以null结尾的字符串。它使用托管的String类,具有完全不同的语义。C和C ++使用null终止符,因为它们对“字符串”变量的概念实际上只是字符数组开头的指针,并且null终止符是一种方便的方式来扫描字符串的结尾。在.NET中,由于String是一个完整的托管类,因此此机制是不必要的。


2
请注意,作为实现细节,所有.NET字符串实际上都以零字符结尾存储在它们的内存块中。这样,在交互操作场景中,运行时引擎开发人员可以轻松地将字符串指针传递给C风格的字符串操作方法,而不必担心要复制到一个以null结尾的缓冲区中。 - Eric Lippert
这是一个很好的观点。从托管语言的角度来看,我只谈到必要的内容。你提到的场景确实提出了进一步的互操作性问题-例如,如果有人将null字符嵌入C#字符串中,然后将其传递给API函数,那么API字符串将在第一个null字符处结束,可能会导致意外的结果。我相信你已经意识到了这一点;我只是为了完整起见将其包含在内 :) - Dave C

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接