C#では、string.EmptyまたはString.Emptyまたは“”を使用して文字列を初期化する必要がありますか?


705

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

どうすればよいですか?正しい方法は何ですか?なぜですか?

string willi = string.Empty;

または

string willi = String.Empty;

または

string willi = "";

または何?


7
:また、この類似したJavaのための議論を参照してくださいstackoverflow.com/questions/213985/...
ハーポ

39
確かに、String.IsNullOrEmpty(string myString)を使用した方がいいですか?
ZombieSheep 09

3
[string.IsNullOrWhiteSpace(stringvalue)]を使用しています... .Net 4.0で動作します。初期化するために、私は単純に使用します。[VARテキスト=「」;]シンプルで、読みやすく、:)を入力する少なくとも時間がかかる
ジャラルエルShaer

61
さらに重要なのは、変数の陽気な名前です。
Arj

5
私が興味を持ったのは、Emptyプロパティさえある理由です。それはすべてが素晴らしいですが、必要で完全なものではありません。
MasterMastic

回答:


808

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

他の回答では、を使用するたびに新しい文字列が作成されることが示唆されています""。これは真実ではありません-文字列のインターンにより、アセンブリごとに1回またはAppDomainごとに1回(またはおそらくプロセス全体で1回)作成されます-その前に確認できません)。この違いはごくわずかです-非常に、非常に重要ではありません。

ただし、どちらを読みやすくするかは別の問題です。これは主観的であり、人によって異なります。したがって、チームのほとんどの人がどのような人かを調べ、一貫性を保つためにそれをすべて行うことをお勧めします。個人的には""読みやすいと思います。

""" "簡単に間違えられるという議論は、私にはあまり当てはまりません。あなたはプロポーショナルフォントを使っている(と私が一緒に働いていない場合を除きいかなる行う開発者)、それは違いを見分けるために非常に簡単です。


75
「」が表示されることを期待しているとき、目があなたをだますことができます。これが、他の誰かが書いたものを編集する方が簡単な理由です。あなたの脳はテキストについて先入観を持っていないので、異常を簡単に見つけることができます。
tvanfosson 2008年

125
@tvanfosson:それで、あなた(または同僚)は実際にこれにバグとして噛まれましたか?実際に問題を引き起こしていないのに、私はこの種の主張に疑いを持っています。私は何年もの間「」を間違って使用することなく使用しています...
Jon Skeet

34
個人的には、常にString.Emptyを使用してきました。文字列に静的メソッドを使用する場合は常に大文字の「S」を使用します。これは、変数と型を区別できるようにするための個人的な設定です。しかし、これはjavaのcommons.langでStringUtils.EMPTYを使用することによる単なる持ち越しです。興味深い点の1つは、私はほとんど盲目であり、これは間違いなく私にとって読みやすさを助けます。
ブレット・ライアン

79
Times New Romanで開発を始めるためのインスピレーションを与えてくれました。
Justin Rusbatch、2010

73
いくつかのあいまいな理由string.Emptyで定数ではありません。つまり、コンパイル時の定数が必要とされる多くのケースでは、string.Empty合法ではありません。これにはcase ""switchステートメント内のブロック、オプションのパラメーターのデフォルト値、属性を適用する際のパラメーターとプロパティ、および他の多くの状況が含まれます(読者に任せてください)。そのstring.Emptyため、一部の一般的な状況では許可されないため、""-everywhere規則を使用することをお勧めします。
Jeppe Stig Nielsen 2013

375

パフォーマンスとコード生成の観点から実際には違いはありません。パフォーマンステストでは、ミリ秒単位で高速と高速の切り替えが行われました。

舞台裏のコードを見ると、実際には違いもわかりません。唯一の違いは、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 

13
@PrateekSaluja:ILを確認するには、Visual Studioに付属のildasm.exeを使用できます。ダイアセンブリを表示するには、ブレークポイントに到達したときにデバッグメニューの[逆アセンブリ]ウィンドウを使用します(リリースコードでも機能します)。
Thomas Bratt

1
私がこの製品をお勧めしようとしているのは嫌いです。しかし、..リフレクターを使用すると、ソースを分解するときに言語を選択できます。ILはオプションです。ILDASMは時代遅れの感じです... MSツールチームは良いツールを磨いたりリリースしたりしていないようです!
felickz

80

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

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

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


1
C#では、string.IsNullOrWhitespace(s):p
felickzの

31
コードは可能な限り小さくする必要があることに同意しますが、一般的に、文字数が少ないほど常にコードが優れているとは主張しません。たとえば、変数の命名について言えば、妥当な量の文字を使用すると、通常、iとjを使用するよりも適切な名前になります。
Markus Meyer

3
すなわち、高度に依存@Markus:インデックスを表すループ変数のため、i ある長い変数名よりも優れ。より一般的には、同じ情報を同じ明快さで伝える短い変数名が常に望ましいです。必要な情報を表現するには、特定の文字数が必要です。これは否定できません(だれもです)。
Konrad Rudolph

2
@Konrad:ループが小さく、他のインデックスが含まれていない場合にのみ、iは適切な変数名です。しかし、私はそうなら同意します。string.Empty / ""の場合のように、同じ情報をより簡潔に伝えることができます。string.Emptyは明確さを追加しません。
Markus Meyer

私にとって:string.Emptyは、この文字列は常に空である必要があると言っていますが、 ""は、この文字列を書き込むときに空である可能性があると言っていますが、自由に変更できます。
エアロソン2017

54

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

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


22
switch文は1つの非常に良い例です。また、などのオプションのパラメーターを作成した場合void MyMethod(string optional = "") { ... }も、を使用することはできませんstring.Empty。そしてもちろん、constフィールドやローカル変数を定義したい場合は、const string myString = "";もう一度""しか選択肢がありません。string.Empty定数フィールドだけの場合、違いはありません。しかし、そうではないため、場合によってはを使用する必要があります""。それでは、なぜ""いつも使用しないのですか?
Jeppe Stig Nielsen

5
を使用string.Emptyすると、コードベースで一貫性を実現できなくなるため、これは本当に強力な引数です。同じことを表現するには、2つの異なるエンティティを使用する必要があります。そして、できないことのリストに追加するにはstring.Empty属性で使用することはできません。
Pragmateek 2013年

2
とても良い点!リンクが壊れています。ここでは、コンテンツのコピーです:web.archive.org/web/20131230161806/http://kossovsky.net/...
ygoe

42

私は好むstringString。選ぶというstring.Emptyこと""は、どれを選ぶか、それにこだわるということです。を使用する利点string.Emptyは、それが何を意味するかが非常に明白であり、のよう"\x003"に印刷できない文字を誤ってコピーしないことです""


101
印刷できない文字を誤ってコードにコピーしていると、この質問よりも大きな問題が発生すると私は主張します;)
Jon Skeet

9
ASCII \ 003はたまたま使用したB2Bメッセージのフィールド区切り文字です:)
ジミー

7
(また、\ xエスケープを回避することをお勧めします。ところで、根本的に異なる結果をもたらす"\ x9Bad Compiler"と "\ x9Good Compiler"の違いを見つけるのは難しすぎます!)
Jon Skeet

個人的には、Stringで静的メソッドを呼び出すときは常に、StringよりもStringを優先します。私はほとんど盲目ですが、これは私がだれにも強制しない個人的な好みです。
ブレット・ライアン

2
@ジミー確かに、私たちは空の文字列について話していました。引数""あなたは/空の文字列をコピー&ペーストしませんので、コピーが/貼り付け時に危険ですが、私は主張し、無効です。もちろん、他の弦については、常に気をつけるべきことです。
Timo

22

チャイムを鳴らすつもりはありませんでしたが、間違った情報がここに投げ込まれているのが見えます。

私は個人的に好みstring.Emptyます。それは個人的な好みであり、私はケースバイケースで私が一緒に働くどんなチームの意志にも曲げます。

いくつかの他の述べたように、間に全く差がないstring.EmptyとはString.Empty

さらに、これはあまり知られていない事実であり、「」の使用は完全に許容されます。「」のすべてのインスタンスは、他の環境ではオブジェクトを作成します。ただし、.NETはその文字列をインターンするため、将来のインスタンスは同じ不変文字列をインターンプールからプルし、パフォーマンスへの影響は無視できます。出典:Brad Abrams


20
「技術的に」「」のすべてのインスタンスがオブジェクトを作成する理由がわかりません。文字列がインターンされるのは偶然ではなく、C#仕様にあります。
Jon Skeet、

15

個人的には、もっと複雑なものに正当な理由がない限り、「」を好みます。


13

String.Emptystring.Empty同等です。StringBCLクラス名です。stringはそのC#エイリアス(またはショートカット(必要な場合))です。Int32およびと同じintです。ドキュメントを見るその他の例を。

の限り ""は、私は本当にわかりません。

個人的には、常にを使用していますstring.Empty


10

そこにいるほぼすべての開発者は、「」の意味を知っています。私は個人的に初めてString.Emptyに出会い、本当に同じものかどうかを調べるためにgoogleを検索するのに少し時間を費やす必要がありました。


3
これはパブリックな読み取り専用文字列フィールドであり、その値は ""です...なぜそれが変わるのですか?
マシューホワイト

5
@Jasonが作成したポイントを逃します。初めて目にしたのはどのようにしてわかりますstring.Emptyか?""あなたがそれを初めて見たのは何でしたか知っていますか?
David R Tribble

10

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

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

string.Emptyコンパイラの警告で初期化する場合

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

二重引用符を使用した初期化の場合、期待されるメッセージが表示される間は、決して出力されません。

この動作は、次のリンクの接続に関する記事で説明されています。https//connect.microsoft.com/VisualStudio/feedback/details/799810/c-warning-cs0219-not-reported-when-assign-non-constant-value

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


1
あなたが最初に言及する人だと思います。数か月前にこのQ&Aを読みましたが、言及されていた場合、この違いを覚えていません。
Palec

2
面白い。宣言var unused = "literal";は、コンパイラーによって完全に最適化(削除)できることに注意してください。副作用はありません。一方、var unused = MyClass.Member;完全に削除することはできません。それは読書Memberが副作用をもたらす可能性があるためです。Membergetアクセサー付きの静的プロパティである場合、ゲッターへの呼び出しを保持する必要があることは明らかです。ただしMember、静的フィールドであっても、静的コンストラクターが実行される可能性があるという副作用がある場合があります。確かに、そのようにするのは悪いコーディングスタイルでしょう。しかし、あなたは読むためにダミーが必要Memberです。
Jeppe Stig Nielsen

9

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

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つの変数、すなわちことを示唆しているstr1str2str3別の構文を使用して初期化されているものの、メモリ内のオブジェクト(長さがゼロの)正確に同じ文字列を指しています。このテストは.NET 4.5コンソールアプリケーションで実行しました。したがって、内部的には違いはなく、結局のところ、プログラマとして使いたいものの利便性にまで達しています。文字列クラスのこの動作は、.NETでは文字列インターニングとして知られています。エリックリペットは非常にいいブログ持ってここにこの概念を説明します。


8

上記のいずれか。

多くの、より多くのより良いものを強調する必要があります。どの樹皮が木に一番合うのかなど、ダルモスの色がかった漠然とした茶色だと思います。


7

String.Emptyを強くお勧めします。他の理由は別として、それが何であるかを理解し、誤ってコンテンツを削除していないことを確認するためですが、主に国際化のためです。文字列が引用符で囲まれている場合は、それが新しいコードであるかどうかを常に疑問視しなければならず、文字列テーブルに配置する必要があります。したがって、コードが変更または確認されるたびに、「引用符で囲まれたもの」を探す必要があり、はい、空の文字列を除外できますが、ローカライズされないことがわかっている場合を除き、文字列を引用符で囲まないことをお勧めします。 。


7

VisualStudioでは、文字列は文字列とは異なる色でコード化されていると誰も述べていません。これは読みやすさにとって重要です。また、小文字は通常、変数と型に使用されますが、大したことではありませんが、String.Emptyは定数であり、変数または型ではありません。


String.Emptyをは一定ではない:参照stackoverflow.com/questions/507923/...設計によって、それが実際にStringクラスのインスタンスです。:ビットは、隠されたものの、着色が前に述べたstackoverflow.com/questions/263191/...
マイケル

6

string と同義です System.Stringタイプの、同一です。

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

私はむしろ、コード内で「」文字定数を使用していないだろうstring.EmptyString.Empty-簡単にプログラマが何を意味するか見るために。

string及びString下部ケースのようなI string私は年間たくさんのDelphiでの作業に使用し、Delphiのスタイルが小文字である以上という理由だけでstring

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


6

私は有利に働くstring.Empty以上String.Empty、あなたがAを含めなくても、それを使用することができますので、using System;ファイルにます。

ピッキング""についてはstring.Empty、個人的な好みであり、チームが決定する必要があります。


2
私はチームの唯一のメンバーです。どうすれば決定できますか?サイコロを投げますか?
Gqqnbig

1
名前空間string.Emptyをインポートせずに定数を使用する方法について不思議に思う人のためusing Systemに-C#のキーワードは、出力* .dllまたは*でMSILとして書き込まれる前に、名前空間も含む完全修飾名に変換されます。 exeファイル。したがって、コンパイラによってMSILのstring.EmptyようSystem.String.Emptyに効率的に記述されます。すでにご存じかもしれませんが、完全修飾型名について言及すると、コードファイルの先頭にある名前空間のインポートをスキップできます。
RBT 2017

5

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


4

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

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


1
現代の世界では、「一貫性がある」とは、世界中のすべてのチームにわたって一貫していることを意味し、StackOverflowの目標の1つです。私が提案するかもしれない場合は、String.Emptyを使用しましょう。
Pavel Radzivilovsky、2009

1
一部の言語には、Empty定数がありません。また、考えられるすべての言語で、長さゼロの文字列を許可します。したがって、他の言語との一貫性を保つために「」に投票します。:)
TomXP411 2014

4

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

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

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

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


3

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


3

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

[編集]

また、常に、stringまたはString一貫性を保つために使用することもできますが、それは私だけです。


私はこの発言に同意しますが、怠惰なときでも危険なまま生きています。いずれにしても、変数宣言の外で文字列を割り当てる前に、文字列を使用するコードを書く機会はないと思います。実際、リスクにもかかわらず、文字列を初期化しなければならないのは私にとって不愉快です。
EnocNRoll-AnandaGopal Pardue 2009年

3

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

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

string.EMptyまたはStrng.Emptyと入力すると、コンパイラーは、それが間違っていることを知らせます。すぐに。単にコンパイルされません。開発者は、コンパイラー(または別の開発者)が誤って解釈できないという特定の意図を挙げています。間違った場合、バグを作成することはできません。

「」の意味で「」と入力した場合、またはその逆の場合、コンパイラーはユーザーが指示したとおりに喜んで実行します。別の開発者が特定の意図を収集できる場合とできない場合があります。バグが作成されました。

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

可能な場合はいつでも、コンパイラーを適切に動作させ、どんなに小さくても人為的エラーの可能性を排除してください。IMO、他の人が引用したように、これは「読みやすさ」よりも優先されます。

特異性とコンパイル時間の強制。夕食にどうするか。


3

""を使用しているのは、コード内で明確に黄色に着色されるためです...何らかの理由で、Visual Studio CodeテーマではString.Emptyがすべて白です。そして私はそれが私にとって最も重要だと信じています。



2

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

次のC#コードを検討してください...

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

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

個人的には、後者は曖昧さが少なく読みやすいと思います。

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


1

2つ目は「適切」だと思いますが、正直なところ、重要ではないと思います。コンパイラーは、それらをまったく同じバイトコードにコンパイルするのに十分スマートでなければなりません。自分で「」を使用しています。


1

違いは非常に小さいですが、違いはまだ存在しています。

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

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


1
string.Empty "" です。ソースを確認してください
dss539 '12

1

オンhttp://blogs.msdn.com/b/brada/archive/2003/04/22/49997.aspx

Davidが示唆するように、との間String.Empty""はかなりの違いがありますが、違いがあります。""実際にオブジェクトを作成すると、文字列インターンプールから取り出される可能性がありますが、それでも... String.Emptyオブジェクトは作成されません...したがって、最終的にメモリ効率を本当に求めている場合は、をお勧めしString.Emptyます。ただし、差はそう...あなたが好きになるでしょうあなたのコードでそれを見ることはないtrivalある心に留めておく必要があります
についてはSystem.String.Emptystring.EmptyString.Empty自分のケアのレベルが低い... ;-)


1
そのMSDNブログの投稿は2003年でした...これが最近の.NETバージョンにも当てはまりますか?
CarstenSchütte2013

@CarstenSchütte:そのような機能はそれほど変更することを意図していないように私には思えます...そして、もしそうなら、それについてインターネット上でいくつかの話題がありました。
sergiol 2013

3
@sergiolフィールドがリテラルより効率的である場合、これは明らかにパフォーマンスのバグです。したがって、それが今までに修正されることを期待しています。
Konrad Rudolph

1

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


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.