我有以下代码
char ptr=new char();
int counter = 1;
string s = new System.String(ptr, counter);
// does not show something
MessageBox.Show(s+"Something");
//shows something
MessageBox.Show("Something" + s);
第一个Messagebox不显示
第二个消息框显示
如果计数器值为0,则两个消息框都显示相同的结果,但如果计数器大于0则会出现问题。
我认为问题出在new string(ptr, counter)
启动
。但我想知道为什么会发生这种情况的内在机制。
答案 0 :(得分:12)
ptr内部是null。因此,当您连接时,它将打印到空字符。因此,在运行时,MessageBox.Show(s + "Something");
评估为MessageBox.Show("\0Something");
,而您的另一个评估为MessageBox.Show("Something\0");
。
这就是为什么Something
没有印在第一个上的原因。它超过了空字符。在Wikipedia上阅读有关Null-Terminated Strings(ASCIIZ)的更多内容。
在.NET内部,.NET中的字符串只是一个struct
,包含一个int
个eger长度和一个char[]
数组。但是,在将其传递给MessageBox.Show
时,会将其传递给Win32 API函数MessageBox
,该函数基于C,使用以null结尾的字符串。
最有可能的是,至少对于optimize
(Release
)模式下的现代编译器,编译器会看到你在字符串中添加了一个空字符,然后删除它后面的所有内容。在这种情况下,它只为字符串分配\0
。
答案 1 :(得分:3)
new char()
返回一个空字符(包含两个零字节),因此ptr
为'\0'
。
当您使用s = new System.String(ptr, 0);
时,构造函数会将'\0'
字符零次连接起来,从而产生一个空字符串(""
)。将空字符串添加到另一个字符串无效,因此s+"Something"
等于"Something"+s
"Something"
。
另一方面,使用s = new System.String(ptr, 1);
创建一个包含单个'\0'
字符的字符串。然后在"Something"
之前添加此字符串会导致"\0Something"
之后添加"Something\0"
。
在C#字符串不被操作为NULL-Terminated Strings,所以当你创建"\0Something"
时,你真的拥有它(你可以确保通过Length
字符串是10),但是MessageBox.Show
被转换为windows user32库的Win32 MessageBox
函数。并且该函数需要以空字符结尾的字符串(当遇到零字节或零字符串的零字节时它会停止。)