C#では、文字列値を空の文字列で初期化したいと思います。
どうすればよいですか?正しい方法は何ですか?なぜですか?
string willi = string.Empty;
または
string willi = String.Empty;
または
string willi = "";
または何?
C#では、文字列値を空の文字列で初期化したいと思います。
どうすればよいですか?正しい方法は何ですか?なぜですか?
string willi = string.Empty;
または
string willi = String.Empty;
または
string willi = "";
または何?
回答:
あなたとあなたのチームが最も読みやすいと思うものを使用してください。
他の回答では、を使用するたびに新しい文字列が作成されることが示唆されています""
。これは真実ではありません-文字列のインターンにより、アセンブリごとに1回またはAppDomainごとに1回(またはおそらくプロセス全体で1回)作成されます-その前に確認できません)。この違いはごくわずかです-非常に、非常に重要ではありません。
ただし、どちらを読みやすくするかは別の問題です。これは主観的であり、人によって異なります。したがって、チームのほとんどの人がどのような人かを調べ、一貫性を保つためにそれをすべて行うことをお勧めします。個人的には""
読みやすいと思います。
""
と" "
簡単に間違えられるという議論は、私にはあまり当てはまりません。あなたはプロポーショナルフォントを使っている(と私が一緒に働いていない場合を除きいかなる行う開発者)、それは違いを見分けるために非常に簡単です。
string.Empty
で定数ではありません。つまり、コンパイル時の定数が必要とされる多くのケースでは、string.Empty
合法ではありません。これにはcase ""
、switch
ステートメント内のブロック、オプションのパラメーターのデフォルト値、属性を適用する際のパラメーターとプロパティ、および他の多くの状況が含まれます(読者に任せてください)。そのstring.Empty
ため、一部の一般的な状況では許可されないため、""
-everywhere規則を使用することをお勧めします。
パフォーマンスとコード生成の観点から実際には違いはありません。パフォーマンステストでは、ミリ秒単位で高速と高速の切り替えが行われました。
舞台裏のコードを見ると、実際には違いもわかりません。唯一の違いは、IL、であるstring.Empty
オペコードを使用ldsfld
して""
オペコードを使用していますldstr
が、それは理由だけでstring.Empty
静的であり、そして両方の命令が同じことを行います。作成されたアセンブリを見ると、まったく同じです。
private void Test1()
{
string test1 = string.Empty;
string test11 = test1;
}
private void Test2()
{
string test2 = "";
string test22 = test2;
}
.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
コーディングの基本的な性質は、プログラマーとしての私たちの仕事は、私たちが行うすべての決定はトレードオフであることを認識することです。[…] 簡潔さから始めます。テストによって、必要に応じて他の寸法を増やします。
その結果、以下のコードでは、より良いコードです:優先""
にstring.Empty
かString.Empty
。これら2つは6倍長く、追加の利点はありません。まったく同じ情報を表現しているため、明確さはありません。
i
ある長い変数名よりも優れ。より一般的には、同じ情報を同じ明快さで伝える短い変数名が常に望ましいです。必要な情報を表現するには、特定の文字数が必要です。これは否定できません(だれもです)。
1つの違いは、switch-case
構文を使用する場合case string.Empty:
、それは定数ではないため、記述できないことです。あなたはCompilation error : A constant value is expected
詳細については、このリンクを参照してください: string-empty-versus-empty-quotes
switch
文は1つの非常に良い例です。また、などのオプションのパラメーターを作成した場合void MyMethod(string optional = "") { ... }
も、を使用することはできませんstring.Empty
。そしてもちろん、const
フィールドやローカル変数を定義したい場合は、const string myString = "";
もう一度""
しか選択肢がありません。string.Empty
定数フィールドだけの場合、違いはありません。しかし、そうではないため、場合によってはを使用する必要があります""
。それでは、なぜ""
いつも使用しないのですか?
string.Empty
すると、コードベースで一貫性を実現できなくなるため、これは本当に強力な引数です。同じことを表現するには、2つの異なるエンティティを使用する必要があります。そして、できないことのリストに追加するにはstring.Empty
、属性で使用することはできません。
私は好むstring
へString
。選ぶというstring.Empty
こと""
は、どれを選ぶか、それにこだわるということです。を使用する利点string.Empty
は、それが何を意味するかが非常に明白であり、のよう"\x003"
に印刷できない文字を誤ってコピーしないことです""
。
""
あなたは/空の文字列をコピー&ペーストしませんので、コピーが/貼り付け時に危険ですが、私は主張し、無効です。もちろん、他の弦については、常に気をつけるべきことです。
チャイムを鳴らすつもりはありませんでしたが、間違った情報がここに投げ込まれているのが見えます。
私は個人的に好みstring.Empty
ます。それは個人的な好みであり、私はケースバイケースで私が一緒に働くどんなチームの意志にも曲げます。
いくつかの他の述べたように、間に全く差がないstring.Empty
とはString.Empty
。
さらに、これはあまり知られていない事実であり、「」の使用は完全に許容されます。「」のすべてのインスタンスは、他の環境ではオブジェクトを作成します。ただし、.NETはその文字列をインターンするため、将来のインスタンスは同じ不変文字列をインターンプールからプルし、パフォーマンスへの影響は無視できます。出典:Brad Abrams。
そこにいるほぼすべての開発者は、「」の意味を知っています。私は個人的に初めてString.Emptyに出会い、本当に同じものかどうかを調べるためにgoogleを検索するのに少し時間を費やす必要がありました。
string.Empty
か?""
あなたがそれを初めて見たのは何でしたか知っていますか?
このトピックはかなり古くて長いので、この動作が他の場所で言及されている場合は失礼します。(そしてこれをカバーする答えを私に指摘してください)
あなたが使用する場合、私はコンパイラの動作に違いを見つけました 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
基本的に、私がそれを正しく理解した場合、プログラマーは、警告メッセージで煩わされることなく、デバッグの目的で関数の戻り値を変数に設定できるようにしたいので、コストの高い割り当てと文字列の場合にのみ警告を制限しました。空は定数ではなくフィールドです。
var unused = "literal";
は、コンパイラーによって完全に最適化(削除)できることに注意してください。副作用はありません。一方、var unused = MyClass.Member;
完全に削除することはできません。それは読書Member
が副作用をもたらす可能性があるためです。Member
がget
アクセサー付きの静的プロパティである場合、ゲッターへの呼び出しを保持する必要があることは明らかです。ただしMember
、静的フィールドであっても、静的コンストラクターが実行される可能性があるという副作用がある場合があります。確かに、そのようにするのは悪いコーディングスタイルでしょう。しかし、あなたは読むためにダミーが必要Member
です。
コンソールアプリケーションで次の方法を使用して、この非常に簡単なテストを実行しました。
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つの変数、すなわちことを示唆しているstr1
、str2
とstr3
別の構文を使用して初期化されているものの、メモリ内のオブジェクト(長さがゼロの)正確に同じ文字列を指しています。このテストは.NET 4.5コンソールアプリケーションで実行しました。したがって、内部的には違いはなく、結局のところ、プログラマとして使いたいものの利便性にまで達しています。文字列クラスのこの動作は、.NETでは文字列インターニングとして知られています。エリックリペットは非常にいいブログ持ってここにこの概念を説明します。
String.Emptyを強くお勧めします。他の理由は別として、それが何であるかを理解し、誤ってコンテンツを削除していないことを確認するためですが、主に国際化のためです。文字列が引用符で囲まれている場合は、それが新しいコードであるかどうかを常に疑問視しなければならず、文字列テーブルに配置する必要があります。したがって、コードが変更または確認されるたびに、「引用符で囲まれたもの」を探す必要があり、はい、空の文字列を除外できますが、ローカライズされないことがわかっている場合を除き、文字列を引用符で囲まないことをお勧めします。 。
VisualStudioでは、文字列は文字列とは異なる色でコード化されていると誰も述べていません。これは読みやすさにとって重要です。また、小文字は通常、変数と型に使用されますが、大したことではありませんが、String.Emptyは定数であり、変数または型ではありません。
string
と同義です System.String
タイプの、同一です。
値も同じです: string.Empty == String.Empty == ""
私はむしろ、コード内で「」文字定数を使用していないだろうstring.Empty
かString.Empty
-簡単にプログラマが何を意味するか見るために。
間string
及びString
下部ケースのようなI string
私は年間たくさんのDelphiでの作業に使用し、Delphiのスタイルが小文字である以上という理由だけでstring
。
だから、私があなたの上司なら、あなたは書いているでしょう string.Empty
私は有利に働くstring.Empty
以上String.Empty
、あなたがAを含めなくても、それを使用することができますので、using System;
ファイルにます。
ピッキング""
についてはstring.Empty
、個人的な好みであり、チームが決定する必要があります。
string.Empty
をインポートせずに定数を使用する方法について不思議に思う人のためusing System
に-C#のキーワードは、出力* .dllまたは*でMSILとして書き込まれる前に、名前空間も含む完全修飾名に変換されます。 exeファイル。したがって、コンパイラによってMSILのstring.Empty
ようSystem.String.Empty
に効率的に記述されます。すでにご存じかもしれませんが、完全修飾型名について言及すると、コードファイルの先頭にある名前空間のインポートをスキップできます。
違いはありません。最後のものはタイプするのに最も速いです:)
それは問題ではありません-それらはまったく同じものです。ただし、主なことは、が一貫必要
ps私はいつもこのような「正しいこと」に苦労しています。
これは完全にコードスタイルの設定であり、.NETが文字列を処理する方法を実行します。しかし、ここに私の意見があります:)
静的メソッド、プロパティ、フィールドにアクセスするときは常にBCLタイプ名を使用します:String.Empty
またはInt32.TryParse(...)
またはDouble.Epsilon
新しいインスタンスを宣言するときは常にC#キーワードを使用します。int i = 0;
またはstring foo = "bar";
コードをスキャンして再利用可能な名前付き定数に結合できるようにしたいので、未宣言の文字列リテラルを使用することはほとんどありません。とにかく、コンパイラーは定数をリテラルで置き換えます。これは、魔法の文字列/数値を回避し、名前でもう少し意味を与えるための方法です。さらに、値を変更する方が簡単です。
最初の2つはどちらでもかまいません。引用符の間にスペースを入れることでバグを導入するのは比較的簡単なので、最後の1つは避けます。この特定のバグは、観察では見つけるのが難しいでしょう。タイプミスがないと仮定すると、すべて意味的に同等です。
[編集]
また、常に、string
またはString
一貫性を保つために使用することもできますが、それは私だけです。
私は個人的に「」が2回(マイナー)の問題を引き起こすことを目撃しました。1つはチームベースのプログラミングに不慣れなジュニア開発者のミスによるもので、もう1つは単純なタイプミスでしたが、実際にはstring.Emptyを使用することで両方の問題を回避できました。
はい、これは非常に判断の呼びかけですが、言語が物事を実行するための複数の方法を提供する場合、私は最もコンパイラの監視と最も強力なコンパイル時の強制を持つものに傾く傾向があります。「」ではありません。それはすべて、特定の意図を表現することです。
string.EMptyまたはStrng.Emptyと入力すると、コンパイラーは、それが間違っていることを知らせます。すぐに。単にコンパイルされません。開発者は、コンパイラー(または別の開発者)が誤って解釈できないという特定の意図を挙げています。間違った場合、バグを作成することはできません。
「」の意味で「」と入力した場合、またはその逆の場合、コンパイラーはユーザーが指示したとおりに喜んで実行します。別の開発者が特定の意図を収集できる場合とできない場合があります。バグが作成されました。
string.Emptyよりもずっと前に、EMPTY_STRING定数を定義する標準ライブラリを使用していました。string.Emptyが許可されていないcaseステートメントでは、引き続きこの定数を使用します。
可能な場合はいつでも、コンパイラーを適切に動作させ、どんなに小さくても人為的エラーの可能性を排除してください。IMO、他の人が引用したように、これは「読みやすさ」よりも優先されます。
特異性とコンパイル時間の強制。夕食にどうするか。
コンパイラーは、長期的にはそれらをすべて同じにする必要があります。コードが読みやすくなるように標準を選択し、それに固執します。
違いは非常に小さいですが、違いはまだ存在しています。
1) ""はオブジェクトを作成しますが、String.Emptyは作成しません。ただし、このオブジェクトは一度作成され、コードに別の ""がある場合、後で文字列プールから参照されます。
2)文字列と文字列は同じですが、ドット表記は演算子ではなくクラスを示し、大文字で始まるクラスはC#コーディング標準。
オンhttp://blogs.msdn.com/b/brada/archive/2003/04/22/49997.aspx:
Davidが示唆するように、との間
String.Empty
に""
はかなりの違いがありますが、違いがあります。""
実際にオブジェクトを作成すると、文字列インターンプールから取り出される可能性がありますが、それでも...String.Empty
オブジェクトは作成されません...したがって、最終的にメモリ効率を本当に求めている場合は、をお勧めしString.Empty
ます。ただし、差はそう...あなたが好きになるでしょうあなたのコードでそれを見ることはないtrivalある心に留めておく必要があります
についてはSystem.String.Empty
やstring.Empty
やString.Empty
自分のケアのレベルが低い... ;-)
空の文字列は、空のセットのようなもので、誰もがを呼び出すために使用する名前です""
。また、正式な言語では、長さがゼロのアルファベットから作成された文字列は、空の文字列と呼ばれます。セットと文字列の両方に特別な記号があります。空の文字列:εおよび空のセット:∅。この長さがゼロの文字列について話したい場合は、空の文字列と呼ぶので、誰もがあなたが何を参照しているかを正確に理解できます。空の文字列に名前を付けた場合はstring.Empty
、コードで使用しないでください。意図が明示的であることを示しています。欠点は、定数ではないため、属性のようにどこでも利用できないことです。(技術的な理由により、定数ではありません。参照ソースを参照してください。)