643

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

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

string willi = string.Empty;

または

string willi = String.Empty;

または

string willi = "";

または何?


  • javaについても同様の議論を見てください。stackoverflow.com/questions/213985/… - harpo
  • String.IsNullOrEmpty(string myString)を使用した方がいいでしょうか。 - ZombieSheep
  • 私は[string.IsNullOrWhiteSpace(stringvalue)]を使用します。初期化するには、単に[var text ="" ;;]と入力します。 - Jalal El-Shaer
  • もっと重要なのはあなたの変数の陽気な名前です。 - Arj
  • 私が興味を持っていることは、なぜEmptyプロパティさえもあるのです。それは素晴らしいことですがすべてではありませんが、必要不可欠ではありません。 - MasterMastic

29 답변


739

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

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

しかし、どちらを読みやすくするかは別の問題です。それは主観的なもので、人によって異なるので、チームのほとんどの人が好きなものを見つけて、一貫性を保つためにそれを使用することをお勧めします。個人的に私は見つけます""読みやすくなりました。

その議論""そして" "お互いに間違えやすいのですが、私を洗っているわけではありません。プロポーショナルフォントを使用していない限りどれか違いを見分けるのはとても簡単です。


  • あなたが""を見ることを期待しているとき、あなたの目はあなたをだますことができます。あなたは簡単に"を間違えることができます。 " "の場合他の誰かが書いたものを編集する方が簡単なのはこのためです。あなたの頭脳はテキストについての先入観を持っていないので、異常を選ぶのはより簡単です。 - tvanfosson
  • @ tvanfosson:それで、あなた(または同僚)は実際にこれとしてバグとして噛まれていますか?実際に問題が発生していない限り、このような申し立てには疑いがあります。 ""を使用しています何年もの間、これまで誤解することなく… - Jon Skeet
  • 個人的には、常にStringを使用しています。空の場合は、大文字と小文字の区別を使用します。文字列に対して静的メソッドを使いたいときはいつでも、それは私が変数と型を区別することを可能にする単なる個人的な好みです。しかし、これは、javaからcommons.langでStringUtils.EMPTYを使用したことによるキャリーオーバーです。興味のある点の1つは、私はほとんど盲目であり、これは間違いなく私にとって読みやすさに役立ちます。 - Brett Ryan
  • あなたは私にTimes New Romanで開発を始めるためのインスピレーションを与えました。 - Justin Rusbatch
  • いくつかのためのあいまいな理由string.Empty定数ではありません。つまり、コンパイル時定数が必要とされる多くの場合において、string.Empty合法でさえありません。これもcase ""ブロックインswitchステートメント、のデフォルト値オプションのパラメータのパラメータ、パラメータ、プロパティ属性、そして他の多くの状況(読者に任されている)。だからそれを考えるとstring.Emptyいくつかの一般的な状況では許可されていません、それを使用することをお勧めします"" - どこでもコンベンション。 - Jeppe Stig Nielsen

361

パフォーマンスとコード生成の観点から違いはありません。パフォーマンステストでは、1つが他のものよりも速く、どちらかがミリ秒だけで行ったり来たりしました。

舞台裏のコードを見ても、実際には違いはありません。唯一の違いはILです。string.Emptyオペコードを使用するldsfldそして""オペコードを使用します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 


  • @PrateekSaluja:ILを確認するには、Visual Studioに付属のildasm.exeを使用できます。分解を見るには、'逆アセンブリ'を使用します。ブレークポイントに到達したときにデバッグメニューのウィンドウ(リリースコードでも機能します)。 - Thomas Bratt
  • 私はこの製品をお勧めしようとしていることを憎む..しかし..リフレクターはあなたがソースを分解するときあなたの言語を選ぶことを可能にし、ILはオプションである! ILDASMはただ時代遅れです... MSツールチームは良いツールを磨いたりリリースしたりするようには見えません! - felickz

71

最高のコードはまったくコードなし

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

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


  • しかし、C#では、string.IsNullOrWhitespace(s)と言うことができます。 - felickz
  • コードはできるだけ小さくする必要があることに同意しますが、一般的に、文字数が少ないほどコードが優れているとは言えません。たとえば、変数の命名に関しては、妥当な量の文字は、一般に、iとjを使用するよりも優れた名前になります。 - Markus Meyer
  • @ Markusそれは依存性が高いです:インデックスを表すループ変数の場合、i です長い変数名よりも優れています。さらに一般的で短い変数名同じ情報を伝える同じ明瞭さにおいて、常に好ましい。あなたに必要な情報を表現するのはそれだけです必要ある程度の長さで、これを否定するわけではありません(誰もそうではありません)。 - Konrad Rudolph
  • @コンラッド:ループが小さく、他のインデックスが含まれていない場合に限り、iは良い変数名です。しかし、私はそれに同意する。同じ情報をもっと簡潔に伝えることができます。文字列のように、それが好ましいでしょう。場合。 string.Emptyは明確さを追加しません。 - Markus Meyer
  • 私には:string.Emptyは、この文字列は常に空であるべきであり、常に空であるべきだと言います。これを書いている時点では、この文字列は空になる可能性がありますが、あなたはそれを自由に変更できます。 - aeroson

47

一つの違いは、あなたがswitch-case構文、あなたは書くことができないcase string.Empty:それは定数ではないからです。あなたはCompilation error : A constant value is expected

詳細についてはこのリンクを見てください。文字列 - 空対空引用符


  • switch文はとても良い例です。また、オプションのパラメータを作ると、void MyMethod(string optional = "") { ... }、使用することもできませんstring.Empty。そしてもちろん、あなたが定義したい場合はconstフィールドまたはローカル変数const string myString = "";また""唯一の選択肢です。もしもstring.Empty定数フィールドだった場合、違いはありません。しかしそうではないので、場合によっては使用する必要があります""。それではなぜ使用しないでください""ずっと? - Jeppe Stig Nielsen
  • これは本当に強力な議論です。string.Empty達成できないようにする一貫性コードベースでは、同じことを表現するために2つの異なるエンティティを使用する必要があります。また、できないことのリストに追加するには、使用できません。string.Empty属性。 - Pragmateek
  • とても良い点!リンクが切れています。内容のコピーは次のとおりです。web.archive.org/web/20131230161806/http://kossovsky.net/… - ygoe

41

私は好きですstringString。選ぶstring.Emptyオーバー""それを選ぶこととそれにこだわることの問題です。使用する利点string.Emptyそれはあなたが何を意味するのか非常に明白であり、あなたは誤って次のような印刷不可能な文字を上書きしてはいけません。"\x003"あなたの中に""


  • 誤って印刷できない文字をコードにコピーした場合、この質問よりも大きな問題が発生することがわかります)。 - Jon Skeet
  • ASCII \ 003がB2Bメッセージのフィールド区切り文字になっていました:) - Jimmy
  • (\ xエスケープを回避することもお勧めします。ただし、「\ x9Bad Compiler」と「\ x9Good Compiler」の違いを見つけるのは困難です。根本的に別の結果!) - Jon Skeet
  • 個人的には、Stringに対して静的メソッドを呼び出すときはいつでも、stringよりもStringを好みます。しかし、私はほとんど盲目であり、これは私がだれにも強制しない個人的な好みです。 - Brett Ryan
  • @ Jimmyもちろん、私たちは空の文字列について話していました。その議論""コピー/貼り付けが無効の場合は危険です。空の文字列をコピー/貼り付けすることは決してないからです。他の文字列については、もちろん注意が必要です。 - Timo

19

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

私は、個人的には好むstring.Empty。それは個人的な好みであり、私はどんなチームでもケースバイケースで意志に専念します。

他の人が言ったように、まったく違いはありません。string.EmptyそしてString.Empty

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


  • 「技術的に」という理由がわかりません。 "のすべてのインスタンスオブジェクトを作成します。文字列が埋め込まれる可能性があるだけではなく、C#の仕様に含まれています。 - Jon Skeet

14

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


12

String.Emptyそしてstring.Empty同等です。StringBCLクラス名です。stringそのC#のエイリアス(またはショートカットの場合はショートカット)です。と同じInt32そしてint。見るドキュメントより多くの例については。

の限り""心配している、私は本当にわからない。

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


10

まさにそこにいるすべての開発者は ""が何を意味するのか知っているでしょう。私は個人的に初めてString.Emptyに遭遇しました。ありますまったく同じこと。


  • これは公開された読み取り専用の文字列フィールドで、その値は""です。なぜそれが変わるのでしょうか。 - Matthew Whited
  • あなたは@ジェイソンの主張を見逃しています。あなたがそれがあなたが最初に見たものであることをどうやって知っていますかstring.Empty?あなたは何を知っていましたか""あなたがそれを見たのは初めてですか? - David R Tribble

8

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

あなたが使用した場合、私はコンパイラの動作に違いが見つかりました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-non-constant-value

基本的には、私が正しければ、警告メッセージを気にせずにデバッグのためにプログラマが関数の戻り値を変数に設定できるようにしたいので、コストのかかる割り当てと文字列の場合にのみ警告を制限します。空は定数ではなくフィールドです。


  • 私があなたが言及する最初の人であると私は信じます。私は数ヶ月前にこのQ&Aを読み終えましたが、この違いを覚えていないでしょう。 - Palec
  • 面白い。宣言に注意してくださいvar unused = "literal";コンパイラによって完全に最適化(削除)できます。副作用はありません。一方、var unused = MyClass.Member;完全に削除することはできません。それは読書だからですMember副作用がある可能性があります。もしMemberの静的プロパティです。getアクセサ、それはゲッターへの呼び出しが保持されなければならないことは明らかです。でもMember静的フィールドであるため、静的コンストラクターが実行する可能性がある副作用がある可能性があります。なるほど悪いコーディングスタイルそのようにしてください。しかし、あなたは読むためにダミーが必要ですMember。 - Jeppe Stig Nielsen

7

私はコンソールアプリケーションで次の関数を使ってこの非常に簡単なテストを実行しました:

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コンソールアプリケーションで実行しました。そのため、内部的には違いはなく、プログラマーとして使用したい方の都合がいいのです。文字列クラスのこの振る舞いはとして知られています文字列のインターナリングネットインチエリックリペットは非常に素晴らしいブログを持っていますここにこの概念を説明します。


6

上記のいずれか

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


5

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


5

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


4

違いはありません。最後のものはもっとも入力が早いです:)


4

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

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

コードでは文字定数 ""を使わずにstring.EmptyまたはString.Empty - プログラマが何を意味しているのかが見やすくなります。

の間にstringそしてString私は小文字が好きですstring私は何年もの間Delphiで働いていたし、Delphiスタイルが小文字であるという理由だけでもっとstring

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


3

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

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


  • 現代の世界では、「一貫性のある」 StackOverflowの目標の1つである、世界中のすべてのチームで一貫性があることを意味します。提案がある場合は、String.Emptyを使用してみましょう。 - Pavel Radzivilovsky
  • Empty定数を持たない言語もありますし、私が考えることのできるすべての言語で""を許可することもできます。長さゼロの文字列だから私は""に投票します。他の言語との一貫性のために。 :) - TomXP411

2

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


2

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

[編集]

また、あなたはいつもどちらかを使いたいかもしれません。stringまたはString一貫性のために、しかしそれは私だけです。


  • 私はこの発言に同意しますが、怠惰になっても危険な生活をしています。いずれにせよ、変数宣言の外側で文字列を代入する前に、それを使用するコードを書く機会がないと思います。実際、リスクがあるにもかかわらず、文字列を初期化しなければならないのは厄介です。 - EnocNRoll - Ananda Gopal

2

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

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

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

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


2

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

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

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

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

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

可能であれば、コンパイラを使用して作業してください。そして、たとえどんなに小さくても、ヒューマンエラーの可能性を排除してください。 IMO、これは他の人が引用したように「読みやすさ」に勝る。

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


2

私は好むだろうstring.EmptyオーバーString.Empty含まなくても使用できるのでusing System;あなたのファイルに。

ピッキングは""オーバーstring.Empty、それは個人的な好みであり、あなたのチームによって決定されるべきです。


  • 私はチームの唯一のメンバーですが、どうすればいいですか。サイコロを投げる? - Gqqnbig
  • それがどのように使用することが可能であるかについて疑問に思うかもしれない人のためにstring.Emptyインポートせずに定数using Systemnamespace - C#のキーワードは、出力の* .dllまたは* .exeファイルにMSILとして書き込まれる前に、名前空間を含む完全修飾名に変換されるだけです。そう効果的にstring.Emptyように書かれるSystem.String.EmptyMSILでコンパイラによって。そしてあなたがすでに知っているかもしれないようにあなたが完全に修飾された型名を言及するならばあなたはあなたのコードファイルの一番上に名前空間をインポートすることへのスキップを与えることができます。 - RBT

1

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


1

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

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

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

vs

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

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

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


1

私は ""を使っています。なぜならそれは私のコードではっきりと黄色に着色されているからです...何らかの理由でString.Emptyは私のVisual Studio Codeテーマでは全て白です。そして私はそれが私にとって最も重要だと思います。


0

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


0

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...私のケアレベルは低いです;-)


  • そのMSDNブログ記事は2003年のものでした....最近の.NETバージョンでもこれは当てはまると思いますか。 - Carsten Schütte
  • @ CarstenSchüそのような機能はあまり変更するつもりはないと私には思えます…そしてもしそうであれば、それについてインターネット上でいくつかの話題がありました。 - sergiol
  • @sergiolフィールドがリテラルよりも効率的な場合、これは明らかにパフォーマンス上のバグです。それで、それが今までに修正されることを願っています。 - Konrad Rudolph

0

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


-1

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

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

2)文字列と文字列は同じですが、ドット表記は演算子ではなくクラスを示し、大文字で始まるクラスはに準拠するため、String.Empty(String.Format、String.Copyなど)を使用することをお勧めします。 C#コーディング標準


  • string.Emptyです""、ソースを確認してください - dss539

リンクされた質問


関連する質問

最近の質問