C#で、私は空の文字列で文字列値を初期化したいです。
どうすればいいですか。 正しい方法は何ですか、そしてそれはなぜですか?
string willi = string.Empty;
または
string willi = String.Empty;
または
string willi = "";
または何?
あなたとあなたのチームが最も読みやすいと思うものは何でも使用してください。
他の回答では、使用するたびに新しい文字列が作成されることを示唆しています""
。これは真実ではありません - 文字列のインターリンティングのため、アセンブリごとに1回、またはAppDomainごとに1回(またはプロセス全体に対して1回)作成されます。この違いはごくわずかです。大々的に重要ではありません。
しかし、どちらを読みやすくするかは別の問題です。それは主観的なもので、人によって異なるので、チームのほとんどの人が好きなものを見つけて、一貫性を保つためにそれを使用することをお勧めします。個人的に私は見つけます""
読みやすくなりました。
その議論""
そして" "
お互いに間違えやすいのですが、私を洗っているわけではありません。プロポーショナルフォントを使用していない限りどれか違いを見分けるのはとても簡単です。
string.Empty
定数ではありません。つまり、コンパイル時定数が必要とされる多くの場合において、string.Empty
合法でさえありません。これもcase ""
ブロックインswitch
ステートメント、のデフォルト値オプションのパラメータのパラメータ、パラメータ、プロパティ属性、そして他の多くの状況(読者に任されている)。だからそれを考えるとstring.Empty
いくつかの一般的な状況では許可されていません、それを使用することをお勧めします""
- どこでもコンベンション。 - Jeppe Stig Nielsen
パフォーマンスとコード生成の観点から違いはありません。パフォーマンステストでは、1つが他のものよりも速く、どちらかがミリ秒だけで行ったり来たりしました。
舞台裏のコードを見ても、実際には違いはありません。唯一の違いは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
。これら二つは6倍長い追加の利点はありませんが、まったく同じ情報が表現されているため、明らかに追加の明瞭さはありません。
i
です長い変数名よりも優れています。さらに一般的で短い変数名同じ情報を伝える同じ明瞭さにおいて、常に好ましい。あなたに必要な情報を表現するのはそれだけです必要ある程度の長さで、これを否定するわけではありません(誰もそうではありません)。 - Konrad Rudolph
一つの違いは、あなたが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 Nielsenstring.Empty
達成できないようにする一貫性コードベースでは、同じことを表現するために2つの異なるエンティティを使用する必要があります。また、できないことのリストに追加するには、使用できません。string.Empty
と属性。 - Pragmateek
私は好きですstring
にString
。選ぶstring.Empty
オーバー""
それを選ぶこととそれにこだわることの問題です。使用する利点string.Empty
それはあなたが何を意味するのか非常に明白であり、あなたは誤って次のような印刷不可能な文字を上書きしてはいけません。"\x003"
あなたの中に""
。
""
コピー/貼り付けが無効の場合は危険です。空の文字列をコピー/貼り付けすることは決してないからです。他の文字列については、もちろん注意が必要です。 - Timo
私は参加するつもりはありませんでしたが、間違った情報がここに投げ出されるのを見ています。
私は、個人的には好むstring.Empty
。それは個人的な好みであり、私はどんなチームでもケースバイケースで意志に専念します。
他の人が言ったように、まったく違いはありません。string.Empty
そしてString.Empty
。
さらに、これはほとんど知られていない事実ですが、 ""の使用は完全に受け入れられます。 ""のすべてのインスタンスは、他の環境ではオブジェクトを作成します。ただし、.NETはその文字列をインターンするので、将来のインスタンスは同じ不変文字列をインターンプールから取得し、パフォーマンスへの影響はほとんどありません。ソース:ブラッドエイブラムス。
私は個人的にはもっと複雑なことに正当な理由がない限り ""を好みます。
String.Empty
そしてstring.Empty
同等です。String
BCLクラス名です。string
そのC#のエイリアス(またはショートカットの場合はショートカット)です。と同じInt32
そしてint
。見るドキュメントより多くの例については。
の限り""
心配している、私は本当にわからない。
個人的に、私はいつも使っていますstring.Empty
。
まさにそこにいるすべての開発者は ""が何を意味するのか知っているでしょう。私は個人的に初めてString.Emptyに遭遇しました。ありますまったく同じこと。
string.Empty
?あなたは何を知っていましたか""
あなたがそれを見たのは初めてですか? - David R Tribble
このトピックは古くて長く続くので、この動作が他の場所で言及されている場合は申し訳ありません。 (そしてこれをカバーする答えを私に指摘してください)
あなたが使用した場合、私はコンパイラの動作に違いが見つかりました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
基本的には、私が正しければ、警告メッセージを気にせずにデバッグのためにプログラマが関数の戻り値を変数に設定できるようにしたいので、コストのかかる割り当てと文字列の場合にのみ警告を制限します。空は定数ではなくフィールドです。
var unused = "literal";
コンパイラによって完全に最適化(削除)できます。副作用はありません。一方、var unused = MyClass.Member;
完全に削除することはできません。それは読書だからですMember
副作用がある可能性があります。もしMember
の静的プロパティです。get
アクセサ、それはゲッターへの呼び出しが保持されなければならないことは明らかです。でもMember
静的フィールドであるため、静的コンストラクターが実行する可能性がある副作用がある可能性があります。なるほど悪いコーディングスタイルそのようにしてください。しかし、あなたは読むためにダミーが必要ですMember
。 - Jeppe Stig Nielsen
私はコンソールアプリケーションで次の関数を使ってこの非常に簡単なテストを実行しました:
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コンソールアプリケーションで実行しました。そのため、内部的には違いはなく、プログラマーとして使用したい方の都合がいいのです。文字列クラスのこの振る舞いはとして知られています文字列のインターナリングネットインチエリックリペットは非常に素晴らしいブログを持っていますここにこの概念を説明します。
上記のいずれか
教訓にするべき、もっと多くの、より良いことがあります。どんな樹皮が一番木に合っているかのように、鈍い苔の色合いを帯びた曖昧な茶色だと思います。
他の理由は別として、String.Emptyを強くお勧めします。それは、それが何であるかを確実に知っていることと、誤って内容を削除していないことを確認するためです。 しかし主に国際化のためのものです。 引用符で囲まれた文字列が表示される場合は、それが新しいコードであるかどうかを常に疑問に思う必要があり、それを文字列テーブルに入れる必要があります。そのため、コードが変更されたり見直されたりするたびに、「引用符の中の何か」を探す必要があります。はい、空の文字列を除外することができます。 。
VisualStudioのStringでは、stringとは異なる色分けがされているとは誰も述べていません。読みやすさにとって重要です。また、通常、小文字はvarsとtypeに使用され、大したことはしませんが、String.Emptyは定数であり、varやtypeではありません。
違いはありません。最後のものはもっとも入力が早いです:)
string
はの同義語ですSystem.String
タイプ、それらは同一です。
値も同じです。string.Empty == String.Empty == ""
コードでは文字定数 ""を使わずにstring.Empty
またはString.Empty
- プログラマが何を意味しているのかが見やすくなります。
の間にstring
そしてString
私は小文字が好きですstring
私は何年もの間Delphiで働いていたし、Delphiスタイルが小文字であるという理由だけでもっとstring
。
だから、私があなたの上司だったら、あなたは書いているでしょうstring.Empty
問題ではありません - それらはまったく同じものです。 しかし、主なことはあなたが一貫している必要があります
PS私はいつもこのような「正しいこと」に苦労しています。
私は3番目を使いますが、他の2つのうち最初のものはあまり変わっていないようです。 stringはStringのエイリアスですが、代入全体でそれらを見ると気分が悪くなります。
最初の2つのどちらでも私には受け入れられるでしょう。引用符の間にスペースを入れることでバグを導入するのは比較的簡単なので、最後の1つは避けます。この特定のバグは観察によって見つけるのが難しいでしょう。タイプミスがないと仮定すると、すべて意味的に同等です。
[編集]
また、あなたはいつもどちらかを使いたいかもしれません。string
またはString
一貫性のために、しかしそれは私だけです。
.NETがどのように文字列を処理するかは、完全にコードスタイルの設定です。しかし、ここに私の意見があります:)
静的メソッド、プロパティ、およびフィールドにアクセスするときは、常にBCLタイプ名を使用します。String.Empty
またはInt32.TryParse(...)
またはDouble.Epsilon
新しいインスタンスを宣言するときは、常にC#キーワードを使用します。int i = 0;
またはstring foo = "bar";
コードをスキャンしてそれらを再利用可能な名前付き定数にすることができるので、宣言されていない文字列リテラルを使用することはめったにありません。とにかく、コンパイラは定数をリテラルに置き換えます。これは、魔法の文字列や数字を避け、名前を使ってそれらにもう少し意味を持たせるためのより多くの方法です。さらに値を変更する方が簡単です。
私は個人的に2回目の(マイナーな)問題を起こしているのを目撃しました。かつてはチームベースのプログラミングに不慣れな後輩の開発者のミスによるもので、もう1つは単純なタイプミスでしたが、実際にはstring.Emptyを使用することで両方の問題を回避できたはずです。
はい、これは非常に判断力のある呼び出しですが、言語があなたに物事をやるための複数の方法を与えるとき、私は最もコンパイラ監督と最も強いコンパイル時強制を持つものに寄りかかる傾向があります。あれはではない「」特定の意図を表現することがすべてです。
string.EMptyまたはStrng.Emptyと入力すると、コンパイラはあなたが間違ったことを知らせます。すぐに。単純にコンパイルされません。あなたが引用している開発者として特定コンパイラ(または他の開発者)がいかなる方法でも誤解することがないように意図しています、そしてあなたがそれを間違って行ったとき、あなたはバグを作成することはできません。
""を意味するときに ""と入力した場合、またはその逆の場合、コンパイラはあなたが指示したことを喜んで行います。他の開発者があなたの特定の意図を拾うことができないかもしれません。バグが発生しました。
string.Emptyのずっと前に、EMPTY_STRING定数を定義した標準ライブラリを使用しました。 string.Emptyが許可されていないcaseステートメントでは、まだこの定数を使用しています。
可能であれば、コンパイラを使用して作業してください。そして、たとえどんなに小さくても、ヒューマンエラーの可能性を排除してください。 IMO、これは他の人が引用したように「読みやすさ」に勝る。
特異性とコンパイル時の強制それが夕食です。
私は好むだろうstring.Empty
オーバーString.Empty
含まなくても使用できるのでusing System;
あなたのファイルに。
ピッキングは""
オーバーstring.Empty
、それは個人的な好みであり、あなたのチームによって決定されるべきです。
string.Empty
インポートせずに定数using System
namespace - C#のキーワードは、出力の* .dllまたは* .exeファイルにMSILとして書き込まれる前に、名前空間を含む完全修飾名に変換されるだけです。そう効果的にstring.Empty
ように書かれるSystem.String.Empty
MSILでコンパイラによって。そしてあなたがすでに知っているかもしれないようにあなたが完全に修飾された型名を言及するならばあなたはあなたのコードファイルの一番上に名前空間をインポートすることへのスキップを与えることができます。 - RBT
長期的に見て、コンパイラはそれらをすべて同じにする必要があります。コードが読みやすくなるように標準を選択し、それを守ってください。
私はちょうどいくつかのコードを見ていました、そしてこの質問は私が前に何度か読んだことのある私の心に浮かびました。これは確かに読みやすさの問題です。
次のC#コードを見てください。
(customer == null) ? "" : customer.Name
vs
(customer == null) ? string.empty : customer.Name
私は個人的には後者があいまいさが少なく読みやすいと感じています。
他の人が指摘したように、実際の違いはごくわずかです。
私は ""を使っています。なぜならそれは私のコードではっきりと黄色に着色されているからです...何らかの理由でString.Emptyは私のVisual Studio Codeテーマでは全て白です。そして私はそれが私にとって最も重要だと思います。
2つ目は「適切」だと思いますが、率直に言ってそれが問題になるとは思わない。コンパイラは、それらのどれでも正確に同じバイトコードにコンパイルするのに十分賢いはずです。私は自分自身を使います。
に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
...私のケアレベルは低いです;-)
空の文字列は、空のセットのようなもので、誰もが呼び出すために使用する名前です。""
。また、正式な言語では、長さがゼロのアルファベットから作成された文字列は、空の文字列と呼ばれます。 setとstringの両方に、特別な記号があります。空の文字列:εと空の集合:◄あなたがこの長さゼロの文字列について話をしたいのなら、あなたはそれを空の文字列と呼ぶでしょう。今あなたがそれを空の文字列と命名した場合はなぜ使用しないでくださいstring.Empty
コードでは、その意図が明確であることを示しています。不利な点は、それが定数ではなく、したがって属性のようにどこでも利用できるわけではないということです。 (技術的な理由から定数ではありません。参照資料を参照してください。)
違いは非常に小さいですが、ほとんど違いはありませんが、違いはまだ存在します。
1) ""はオブジェクトを作成しますが、String.Emptyは作成しません。しかし、このオブジェクトは一度作成され、コード内に別の ""がある場合は後で文字列プールから参照されます。
2)文字列と文字列は同じですが、ドット表記は演算子ではなくクラスを示し、大文字で始まるクラスはに準拠するため、String.Empty(String.Format、String.Copyなど)を使用することをお勧めします。 C#コーディング標準