7

私は次のコードを持っています

 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);

最初のメッセージボックスには何も表示されませんここに画像の説明を入力してください

2番目のメッセージボックスには何かが表示されますここに画像の説明を入力してください

カウンター値が0の場合、両方のメッセージボックスに同じ結果が表示されますが、カウンターが0より大きい場合、問題が発生します。

問題は初期化にあると思いnew string(ptr, counter)ます

。しかし、なぜこれが発生するのかという内部メカニズムを知りたいのです。

4

2 に答える 2

12

ptrは内部的にnullです。したがって、連結すると、ヌル文字まで出力されます。したがって、実行時に、にMessageBox.Show(s + "Something");評価されMessageBox.Show("\0Something");ますが、他の1つはに評価されMessageBox.Show("Something\0");ます。

そのためSomething、最初のものには印刷されません。ヌル文字を過ぎています。ウィキペディアでヌル終了文字列(ASCIIZ)の詳細を読んでください。

内部的には、.NETの文字列はstruct、長さintegerとchar[]配列を含むだけです。ただし、に渡すとMessageBox.Show、Win32 API関数MessageBoxに渡されます。この関数はCベースであるため、nullで終了する文字列を使用します。

ほとんどの場合、少なくともoptimizeRelease)モードの最新のコンパイラでは、コンパイラは、文字列にnull文字が追加されたことを認識し、その後のすべてを削除します。この場合、\0文字列に割り当てるだけです。

于 2012-05-27T03:09:01.810 に答える
3

new char()空の文字(2つのゼロバイトを含む)を返すので、も同様ptrです'\0'

を使用するs = new System.String(ptr, 0);と、コンストラクターは'\0'文字を0回連結し、空の文字列("")になります。空の文字列を別の文字列に追加しても効果がないため、s+"Something"はに等しくなり"Something"+sます"Something"

別の方法では、を使用s = new System.String(ptr, 1);すると、単一の文字を含む文字列が作成されます'\0'。次に、この文字列を前に追加すると、後に追加すると。になり"Something"ます。"\0Something""Something\0"

C#では、文字列はNULLで終了する文字列として操作されない"\0Something"ため、作成すると実際に使用できます(Length10の文字列を使用することで確認できます)が、Windowsuser32ライブラリのMessageBox.ShowWin32関数に変換されます。MessageBoxまた、その関数にはnullで終了する文字列が必要です(Unicode文字列の場合はゼロバイトまたは2つのゼロバイトに遭遇すると停止します)。

于 2012-05-27T03:45:13.817 に答える