プロパティstring foo = string.Empty
がBCLに含まれていたのはなぜですか?空の文字列(string foo = ""
)を使用するよりも冗長で明確ではないようです
typeof(string).GetField("Empty").SetValue(null, " ");
;)
public static string Empty { get { return string.Intern(""); } }
でしょうか?
プロパティstring foo = string.Empty
がBCLに含まれていたのはなぜですか?空の文字列(string foo = ""
)を使用するよりも冗長で明確ではないようです
typeof(string).GetField("Empty").SetValue(null, " ");
;)
public static string Empty { get { return string.Intern(""); } }
でしょうか?
回答:
私はここでしか仮定できません:
string.Empty
明示性のために定義されています-文字列を初期化するとき、""
(テスト中にプレースホルダーの代わりに、null
または言う" "
だけで)実際に初期化子として明示的に意図されたコンテキストから明確でない場合があります。使用string.Empty
は、この種の難問に対する明確な答えです。
Cへの先祖返りでもあります。Cの空の文字列は空の文字列ではありません。これは、最初の文字がnull(したがって空)である文字配列であり、C#とは異なります。ここでの私のポイントは、異なる言語では、異なる方法で空の文字列を表すということです(そして、それらは異なる意味を持つかもしれません)- string.Empty
そのような曖昧さを排除します。
複数のオブジェクトについて他の人が言うこととは対照的に、コンパイル時に文字列リテラルがインターンされるため、これは問題ではありません。これにはstring.Empty
- の値が含まれます""
。これらのいずれかがコードで繰り返されるたびに、オブジェクトはインターンプールから取得されます。これはアプリドメインごとに当てはまります。
""
とが得られる{'\0'}
ので、空の文字列リテラルとそれを定義する他の迂回方法の間に違いはありません。
私がこれらを学んだ情報源を100%確信しているわけではありませんが、それを使用するためのいくつかのポイントは次のとおりです。
.NETアセンブリの各文字列は一意であるため、
string foo = "";
string bar = "";
文字列は不変であるため、出力アセンブリに2つの文字列が生成されます。両方の参照があるとstring.Empty
、アセンブリのサイズが小さくなります。
string.Empty
意図に出くわすと、それが空の文字列であることになっていることは明らかです。しかしfoo = ""
、プログラマーがテスト中に文字列の内容を削除し、それを追加し直すのを忘れた場合、それはそのようになっているはずですか?""
/ string.Empty
は抑留され、1つのオブジェクトのみが作成されます。
のオブジェクトは作成されませんstring.Empty
。を使用""
すると、ほとんどの場合、文字列インターンプールから取得されるオブジェクトが作成されます。
過去に、人々はテストを実行String.Empty
し、わずかに速く出てきましたが、それは微最適化です。
String.Emptyは次のとおりです。
//The Empty constant holds the empty string value.
//We need to call the String constructor so that the compiler doesn't mark
//this as a literal.
//Marking this as a literal would mean that it doesn't show up as a field
//which we can access from native.
public static readonly String Empty = "";
メモリ消費の最適化と文字列比較の最適化の問題です。アプリケーションで空の文字列を使用するたびに、0文字を含む文字列オブジェクトを割り当てています。文字列の比較に関しては、文字(文字列)ではなく参照(ポインタ)を比較することで実行できます。空の文字列でも高速です。
アプリケーションで同じ文字列を何度も使用している場合、文字列でString.Intern()を呼び出すことで同じ種類のメカニズムを使用できます。ただし、各文字列を1回だけ使用する場合は、使用するメモリが増えるだけです。
そのため、String.Emptyは、ほとんどの.Netアプリケーションで実行する価値のある特別な場合の最適化にすぎません。そのため、BCLに統合されました。
このテーマの詳細については、Eric Lippertのブログ投稿を読むことを強くお勧めします。
彼のブログ投稿で参照されているこのドキュメントもご覧ください。