web-dev-qa-db-ja.com

C#で、私は文字列を初期化するためにstring.EmptyまたはString.Emptyまたはは ""を使用すべきですか?

C#で、私は空の文字列で文字列値を初期化したいです。

どうすればいいですか。正しい方法は何ですか、そしてそれはなぜですか?

string willi = string.Empty;

または

string willi = String.Empty;

または

string willi = "";

または何?

671

あなたとあなたのチームが最も読みやすいと思うものは何でも使ってください。

他の回答では、""を使用するたびに新しい文字列が作成されることを示唆しています。これは事実ではありません - 文字列のインターリンティングのため、アセンブリごとに1回、またはAppDomainごとに1回(またはプロセス全体に対して1回)作成されます。この違いはごくわずかです - 大規模に、大規模に重要ではありません。

しかし、どちらを読みやすくするかは別の問題です。それは主観的で、人によって異なるでしょう - それで私はあなたがあなたのチームの大部分の人が好きであるものを見つけることをお勧めします、そしてすべては一貫性のためにそれに従う。個人的には""が読みやすいと思います。

""" "はお互いに間違えやすいという議論は、実際に私を洗い流すものではありません。プロポーショナルフォントを使用しているのでなければ(そしてany開発者と一緒に働いたことがない)、違いを見分けるのはとても簡単です。

769
Jon Skeet

パフォーマンスやコード生成の観点から見ても、実際に違いはありません。パフォーマンステストでは、1つが速いものともう1つが速いものとの間をミリ秒単位で行ったり来たりしました。

舞台裏のコードを見ても、実際には違いはありません。唯一の違いはILにあります。これはstring.Emptyがopcode ldsfldを使用し、""がopcode ldstrを使用するということですが、それはstring.Emptyが静的であり、両方の命令が同じことを行うためです。あなたが生産された議会を見れば、それは全く同じです。

C#コード

private void Test1()
{
    string test1 = string.Empty;    
    string test11 = test1;
}

private void Test2()
{
    string test2 = "";    
    string test22 = test2;
}

ILコード

.method private hidebysig instance void 
          Test1() cil managed
{
  // Code size       10 (0xa)
  .maxstack  1
  .locals init ([0] string test1,
                [1] string test11)
  IL_0000:  nop
  IL_0001:  ldsfld     string [mscorlib]System.String::Empty
  IL_0006:  stloc.0
  IL_0007:  ldloc.0
  IL_0008:  stloc.1
  IL_0009:  ret
} // end of method Form1::Test1
.method private hidebysig instance void 
        Test2() cil managed
{
  // Code size       10 (0xa)
  .maxstack  1
  .locals init ([0] string test2,
                [1] string test22)
  IL_0000:  nop
  IL_0001:  ldstr      ""
  IL_0006:  stloc.0
  IL_0007:  ldloc.0
  IL_0008:  stloc.1
  IL_0009:  ret
} // end of method Form1::Test2

アセンブリコード

        string test1 = string.Empty;
0000003a  mov         eax,dword ptr ds:[022A102Ch] 
0000003f  mov         dword ptr [ebp-40h],eax 

        string test11 = test1;
00000042  mov         eax,dword ptr [ebp-40h] 
00000045  mov         dword ptr [ebp-44h],eax 
        string test2 = "";
0000003a  mov         eax,dword ptr ds:[022A202Ch] 
00000040  mov         dword ptr [ebp-40h],eax 

        string test22 = test2;
00000043  mov         eax,dword ptr [ebp-40h] 
00000046  mov         dword ptr [ebp-44h],eax 
369
aBetterGamer

最良のコードは、まったくコードがないことです

コーディングの基本的な性質は、プログラマーとしての私たちの仕事は、私たちが行うすべての決定がトレードオフであることを認識することです。 […]簡潔に始めましょう。テストで要求されるように他の寸法を増やします。

その結果、より少ないコードがより良いコードです:""string.EmptyまたはString.Emptyに優先します。これら2つは、6倍長くなり、追加の利点はありません - 確かに追加された明快さはありません。それらはまったく同じ情報を表しているからです。

75
Konrad Rudolph

1つの違いは、switch-case構文を使用すると、定数ではないためcase string.Empty:を記述できないことです。 Compilation error : A constant value is expectedがもらえます

詳細については、このリンクを参照してください。 string-empty-vs.-empty-quotes

52
Mentoliptus

私はstringよりStringを好みます。 string.Emptyより""を選ぶのは、それを選んでそれにこだわることです。 string.Emptyを使うことの利点は、あなたが何を意味しているのか非常に明白であり、あなたが誤ってあなたの"\x003"の中の""のような印刷不可能な文字をコピーしてしまうことがないことです。

42
Jimmy

私は参加するつもりはありませんでしたが、間違った情報がここに投げ出されるのを見ています。

私は個人的にはstring.Emptyを好みます。それは個人的な好みであり、私は私がケース・バイ・ケースで取り組むチームの意志に専念します。

他の人が言ったように、string.EmptyString.Emptyの間に全く違いはありません。

さらに、これはほとんど知られていない事実ですが、 ""の使用は完全に受け入れられます。 ""のすべてのインスタンスは、他の環境ではオブジェクトを作成します。ただし、.NETはその文字列をインターンするので、将来のインスタンスは同じ不変文字列をインターンプールから取得し、パフォーマンスへの影響はほとんどありません。出典: ブラッドエイブラムス

22
John Rudy

私は個人的にはもっと複雑なことに正当な理由がない限り ""を好みます。

15
MidnightGun

String.Emptystring.Emptyは同等です。 StringはBCLクラス名です。 stringは、そのC#のエイリアス(またはショートカットの場合はショートカット)です。 Int32およびintと同じです。他の例については ドキュメント をご覧ください。

""に関する限り、私は本当によくわかりません。

個人的には、私はいつもstring.Emptyを使います。

13
Silviu Niculita

だいたいの開発者は ""が何を意味するのか知っているでしょう。私は個人的に初めてString.Emptyに遭遇し、グーグルで検索して本当にそれがまったく同じであるかどうかを調べるために時間を費やす必要がありました。

10
Jason Baker

このトピックは非常に古く長いため、この動作が他の場所で言及されている場合は申し訳ありません。 (そしてこれをカバーする答えを私に指摘してください)

string.Emptyまたは二重引用符を使用した場合、コンパイラの動作に違いがあることがわかりました。あなたがstring.Emptyまたは二重引用符で初期化された文字列変数を使わないなら、違いはそれ自身を示します。

string.Emptyで初期化した場合はコンパイラの警告

CS0219 - The variable 'x' is assigned but its value is never used

二重引用符で初期化した場合には予​​期したメッセージが表示されますが、は決して発行されません。

この動作は、次のリンクのConnectの記事で説明されています。 https://connect.Microsoft.com/VisualStudio/feedback/details/799810/c-warning-cs0219-not-reported-when-assign-不定値

基本的には、私が正しければ、警告メッセージを気にすることなく、プログラマがデバッグのために関数の戻り値を変数に設定できるようにしたいと考えています。空は定数ではなくフィールドです。

9
Steve

私は、コンソールアプリケーションで次の方法でこの非常に簡単なテストを実行しました。

private static void CompareStringConstants()
{
    string str1 = "";
    string str2 = string.Empty;
    string str3 = String.Empty;
    Console.WriteLine(object.ReferenceEquals(str1, str2)); //prints True
    Console.WriteLine(object.ReferenceEquals(str2, str3)); //prints True
}

これは、異なる構文を使用して初期化されていても、3つの変数str1str2、およびstr3がすべて、メモリー内のまったく同じストリング(長さゼロの)オブジェクトを指していることを示しています。このテストは.NET 4.5コンソールアプリケーションで実行しました。そのため、内部的には違いはなく、すべてプログラマとして使用したいという利便性になります。このような文字列クラスの動作は、.NETでは文字列のインターナリングとして知られています。 Eric Lippertには、この概念を説明したとても素敵なブログ がここ にあります。

8
RBT

上記のいずれか.

教訓にするべき、もっとたくさんの、もっと良いことがあります。どんな樹皮が一番木に合っているかのように、鈍い苔の色合いを帯びた曖昧な茶色だと思います。

7
Quibblesome

他の理由は別として、String.Emptyを強くお勧めします。それは、それが何であるかを確実に理解し、誤ってコンテンツを削除したのではなく、主に国際化のためです。引用符で囲まれた文字列が表示される場合は、それが新しいコードであるかどうかを常に疑問に思う必要があり、文字列テーブルに入れる必要があります。そのため、コードが変更されたり見直されたりするたびに、「引用符の中の何か」を探す必要があります。はい、空の文字列を除外できます。 。

7
Wayne Murphy

stringSystem.Stringタイプの同義語です。それらは同一です。

値も同じです:string.Empty == String.Empty == ""

私はコードで文字定数 ""を使うのではなく、string.EmptyString.Emptyを使います - プログラマーが何を意味するのか見やすくします。

stringStringの間私は長年にわたってDelphiで作業していたため、またstringは小文字のstringであるからです。

だから、私があなたの上司だったら、あなたはstring.Emptyを書いているでしょう

6
zendar

VisualStudioのStringでは、stringとは異なる色分けがされているとは誰も述べていません。これは読みやすさにとって重要です。また、通常、小文字はvarsとtypeに使用され、大したことはしませんが、String.Emptyは定数でvarとtypeではありません。

6
Dimitry

違いはありません。最後のものはもっとも速いタイプですが:)

5
CasperTDK

string.Emptyをファイルに含める必要なしに使用できるので、String.Emptyよりusing System;をお勧めします。

""よりstring.Emptyを選ぶことに関しては、それは個人的な好みであり、あなたのチームによって決定されるべきです。

4
Andrew

それは問題ではありません - それらはまったく同じものです。しかし、主なことはあなたは一貫していなければならないということです

pS私はいつもこのような「正しいこと」に苦労しています。

4
Calanus

.NETがどのように文字列を処理するかは、完全にコードスタイルの設定です。しかし、ここに私の意見があります:)

静的メソッド、プロパティ、およびフィールドにアクセスするときは、常にBCLタイプの名前を使用します。String.EmptyまたはInt32.TryParse(...)またはDouble.Epsilon

新しいインスタンスを宣言するときは、常にC#キーワードを使用します。int i = 0;またはstring foo = "bar";

コードをスキャンして再利用可能な名前付き定数にすることができるので、宣言されていない文字列リテラルを使用することはめったにありません。とにかくコンパイラは定数をリテラルに置き換えるので、これは魔法の文字列/数字を避け、名前を使ってそれらにもう少し意味を与えるためのより多くの方法です。さらに値を変更する方が簡単です。

4
mckamey

私は3番目を使いますが、他の2つのうち最初のものはあまり変わっていないようです。 stringはStringのエイリアスですが、割り当て全体でそれらを見ると気分が悪くなります。

3
plinth

最初の2つのどちらでも私には受け入れられるでしょう。引用符の間にスペースを入れることでバグを導入するのは比較的簡単なので、最後の1つは避けます。この特定のバグは観察によって見つけるのが難しいでしょう。タイプミスがないと仮定すると、すべて意味的に同等です。

[編集]

また、一貫性を保つために常にstringまたはStringを使用することをお勧めしますが、それは私にすぎません。

3
tvanfosson

私は個人的に2回目の(マイナーな)問題を起こしているのを目撃しました。かつてはチームベースのプログラミングに不慣れな後輩の開発者のミスによるもので、もう1つは単純なタイプミスでしたが、事実はstring.Emptyを使用することです。

はい、これは非常に判断力のある呼び出しですが、言語があなたに物事を実行するための複数の方法を提供するとき、私は最もコンパイラ監督と最も強いコンパイル時強制を持つものに傾く傾向があります。つまり、ではなく ""です。特定の意図を表現することがすべてです。

String.EMptyまたはStrng.Emptyと入力すると、コンパイラはあなたが間違ったことを知らせます。すぐに。単純にコンパイルされません。開発者として、あなたは特定のコンパイラ(または他の開発者)が決して誤解することができないという意図を引用しています。 tバグを作ります。

""を意味するときに ""と入力した場合、またはその逆の場合、コンパイラは指示したとおりに動作します。他の開発者があなたの特定の意図を拾うことができないかもしれません。バグが発生しました。

String.Emptyのずっと前に、EMPTY_STRING定数を定義した標準ライブラリを使用しました。 string.Emptyが許可されていないcaseステートメントでは、まだこの定数を使用しています。

可能であれば、コンパイラを使用して自分のために機能させ、人的エラーの可能性を最小限に抑えます。 IMO、これは他の人が引用したように「読みやすさ」に勝る。

特異性とコンパイル時の強制それが夕食です。

3
RhinoTX

長期的に見て、コンパイラはそれらをすべて同じにする必要があります。コードが読みやすくなるように標準を選択し、それを守ってください。

2

私はいくつかのコードを見ていただけで、この質問は私が前に読んだことのある私の頭に浮かびました。これは確かに読みやすさの問題です。

次のC#コードを見てください。

(customer == null) ? "" : customer.Name

vs

(customer == null) ? string.empty : customer.Name

私は個人的には後者があいまいさが少なく読みやすいと感じています。

他の人が指摘したように、実際の違いはごくわずかです。

2
Remotec

私は ""を使っています。なぜならそれは私のコードではっきりと黄色に色づけされているからです。そして私はそれが私にとって最も重要だと思います。

2
5argon

空の文字列は、空の集合のようなもので、誰もが""を呼び出すために使用する名前です。また、正式な言語では、長さ0のアルファベットから作成された文字列は空文字列と呼ばれます。 setとstringの両方に、特別な記号があります。空の文字列:ε、空の集合:◄あなたがこの長さゼロの文字列について話をしたいのなら、あなたはそれを空文字列と呼ぶでしょう。空の文字列に名前を付けた場合、コードでstring.Emptyを使用しないのは、その意図が明白であることを示しています。不利な点は、それが定数ではなく、したがって属性のようにどこでも利用できるわけではないということです。 (いくつかの技術的な理由からこれは定数ではありません。参照資料を参照してください。)

1
Wouter

2つ目は「適切」だと思いますが、率直に言ってそれが問題になるとは思わない。コンパイラは、それらのどれでも正確に同じバイトコードにコンパイルするのに十分賢いはずです。私は自分自身を使います。

1
Magus

http://blogs.msdn.com/b/brada/archive/2003/04/22/49997.aspx について:

Davidが示唆しているように、String.Empty""の違いはごくわずかですが、違いがあります。 ""は実際にはオブジェクトを作成しますが、それはおそらく文字列のインターンプールから引き出されますが、それでもString.Emptyはオブジェクトを作成しません...したがって、究極的にメモリ効率を探しているなら、String.Emptyをお勧めします。ただし、違いは非常に小さいため、コードでは絶対に見ないでください。
System.String.Emptyまたはstring.EmptyまたはString.Empty...私のケアレベルは低いです;-)

1
sergiol

違いは非常に小さいですが、ほとんど違いはありませんが、違いはまだ存在します。

1) ""はオブジェクトを作成しますが、String.Emptyは作成しません。しかし、このオブジェクトは一度作成され、コード内に別の ""がある場合は後で文字列プールから参照されます。

2)文字列と文字列は同じですが、ドット表記は演算子ではなくクラスを示し、大文字で始まるクラスはC#コーディング標準.

0
user34577