web-dev-qa-db-ja.com

オプションのパラメーターのデフォルト値としてString.Emptyを使用することはできません

私はEffective C# Bill Wagnerを読んでいます。 Item 14-Minimize Duplicate Initialization Logicでは、コンストラクターで新しいオプションのパラメーター機能を使用する次の例を示しています。

public MyClass(int initialCount = 0, string name = "")

彼は""の代わりにstring.Emptyを使用したことに注意してください。
コメント:

[上記の例では] 2番目のコンストラクターは、より一般的なstring.Emptyではなく、nameパラメーターのデフォルト値に ""を指定したことに注意してください。 string.Emptyはコンパイル時の定数ではないためです。これは、文字列クラスで定義された静的プロパティです。これはコンパイル定数ではないため、パラメーターのデフォルト値に使用することはできません。

すべての状況でstring.Empty staticを使用できない場合、それはその目的に反しませんか?空の文字列を参照するシステムに依存しない手段があることを確認するために使用すると思いました。私の理解は間違っていますか?ありがとう。

更新
フォローアップコメント。 MSDNによると:

各オプションパラメータには、その定義の一部としてデフォルト値があります。そのパラメーターに引数が送信されない場合、デフォルト値が使用されます。 デフォルト値は定数でなければなりません。

その場合、System.Environment.NewLineを使用することも、デフォルト値として新しくインスタンス化されたオブジェクトを使用することもできません。 VS2010はまだ使用していませんが、これは残念です!

86
Mikeyg36

C#2.0コンパイラの時点では、String.Emptyへのポイントはほとんどありません。実際、多くの場合、コンパイラは""へのいくつかの参照をインライン化できますが、同じことはできません。 String.Emptyで。

C#1.1では、すべてが空の文字列を含む多数の独立したオブジェクトを作成することを避けることが有用でしたが、それらの時代は終わりました。 ""は正常に機能します。

59
Andy Mortimer

空の文字列に対して独自の定数を定義することを止めるものは何もありません。本当に定数をオプションのパラメーター値として使用する場合は、次のようにします。

const string String_Empty = "";

public static void PrintString(string s = String_Empty)
{
    Console.WriteLine(s);
}

[余談ですが、String.Empty over ""一般的に、他の回答では言及されていませんが、肉眼では事実上見えないさまざまなUnicode文字(幅ゼロのジョイナーなど)があります。したがって、""は必ずしも空の文字列ではありませんが、String.Empty使用しているものを正確に知っています。私はこれがバグの一般的な原因ではないことを認識していますが、可能です。

52

元の質問から:

空の文字列を参照するシステムに依存しない手段があることを確認するために使用すると思いました。

空の文字列はシステムによってどのように異なるのでしょうか?常に文字のない文字列です!私は本当にstring.Empty == ""がfalseを返した実装を見つけたら怖いでしょう:)これはnotEnvironment.NewLineのようなものと同じです。

Counter Terroristの報奨金投稿から:

次のC#リリースでは、String.Emptyをデフォルトのパラメーターとして使用できるようにします。 :D

確かにそれは起こりません。

私も個人的には非常に異なるデフォルト設定メカニズムが好きでしたが、オプションパラメータが機能する方法は、開始以来.NETにありました-それは常にメタデータに定数を埋め込むことを意味します対応する引数が指定されていない場合はサイト。

string.Emptyでは、実際意味がありません-""を使用すると、必要な処理を実行できます。 that文字列リテラルを使用するのは苦痛ですか? (私はどこでもリテラルを使用します-string.Emptyを使用することはありません-しかし、それは別の引数です。)

それがこの質問について私を驚かせたものです。苦情はdoes n'tが実際に実際の問題を引き起こす何かを中心に展開します。デフォルトが実際に変化する可能性があるため、実行時にデフォルトを計算したい場合には、より重要です。たとえば、DateTimeパラメータを使用してメソッドを呼び出し、デフォルトで「現在の時刻」にしたい場合を想像できます。現時点で、私が知っている漠然としたエレガントな回避策は次のとおりです。

public void RecordTime(string message, DateTime? dateTime = null)
{
    var realDateTime = dateTime ?? DateTime.UtcNow;
}

...しかし、それは必ずしも適切ではありません。

結論として:

  • これがC#の一部になることは非常に疑わしい
  • string.Emptyの場合、とにかく無意味です
  • 本当にdo n'tが常に同じ値を持つ他の値については、本当にcanが痛い
24
Jon Skeet

私はstring.Emptyを使用することはありません、私はそれのポイントを見ることができません。プログラミングが初めての人にとっては簡単になるかもしれませんが、その場合でも役に立つとは思いません。

7
Hans Olsson

String.Emptyの背後にある考え方は、読みやすさを高めることだと思います。異なるプラットフォームでの表現方法に違いがある改行のようなものではありません。それは恥ずかしいので、デフォルトのパラメータでは使用できません。ただし、WindowsとLinuxのMonoのようなものとの間で移植する場合、問題は発生しません。

4
Tom Cabanski

参考までに、属性コンストラクタに渡される値には同じ制約が課せられているように見えます-それらは定数でなければなりません。 string.emptyは次のように定義されているため:

public static readonly string Empty

実際の定数ではなく、使用できません。

3
Shawn Eavis

私はstring.Emptyを純粋に読みやすくするために使用しています。

他の誰かが後でコードを読んだり変更したりする必要がある場合、彼らは私が空の文字列をチェックまたは設定するつもりだったことを知っています。 ""だけを使用すると、必要な文字列をそこに入れるのを忘れたために、バグや混乱を引き起こすことがあります。

例:

if(someString == string.Empty)
{

}

if(someString == "")
{

}

最初のifステートメントは、非常に意図的で読みやすいように思えます。これは単なる好みであるため、""の代わりにstring.Emptyを使用しなければならないことで、列車が大破することは実際にはありません。

1
lukejkw