質問
どのような値という名前だと思いますし、デフォルトのパラメータは、C#.NET 4.0で追加されますか?
何が(それはすでに過負荷状態にして上書きして達成されていない)これらのための良好な使用でしょうか?
解決
これは、コンストラクタを簡単にすることができ、特に、(スレッドのために重要である)不変タイプのため - <のhref =「http://marcgravell.blogspot.com/2008/11/immutability-and-optional-parameters.html」 relが= "nofollowをnoreferrer">完全な議論のこちらをご覧ください。それが のおそらくあるべきな素敵な、しかし、オーバーロードの多くを持つよりも立派ではありません。あなたは明らかに、不変オブジェクトとオブジェクト初期化子を使用することはできませんいつものように:
new Foo {Id = 25, Name = "Fred"}
は使用できません。私はのために解決されます:
new Foo (Id: 25, Name: "Fred")
これは、オーバーロードを簡素化の一般的な考え方に拡張することができますが、の最もの例では、私は法的な組み合わせを宣伝オーバーロードを好むだろう。あなただけの(通常は)初期状態を定義しているので、コンストラクタは、IMO、少し異なっています。
物事のCOM側はまた、多くの人々にとって重要であるが、私は単純に多くのCOM相互運用機能を使用していない - そう、これはのの私にとって重要
としてではありません。 <時間>編集の再コメント。なぜ彼らは使用を属性と同じ構文を使用しませんでしたか?シンプル - それは(属性を持つ問題ではありません)他のメンバー/変数をあいまいにすることができます。例を取るます:
[XmlElement("foo", Namespace = "bar")]
(ctorの、「foo」という)が1つの正規のパラメータ、および1つのという名前の割り当てを使用します。だから我々は、通常の名前付き引数のためにこれを使用すると仮定します:
SomeMethod("foo", SecondArg = "bar");
(またコンストラクタことができた。私は、簡単にするための方法を使用した)
さて...私たちは、変数またはSecondArg
と呼ばれる性質を持っている場合は?これはSecondArg
する名前付き引数としてSomeMethod
を使用して、のSecondArg
する「バー」を割り当て、通常の引数のよう「bar」を渡し間であいまいになる。
を説明するために、これは、C#3.0で合法です
static void SomeMethod(string x, string y) { }
static void Main()
{
string SecondArg;
SomeMethod("foo", SecondArg = "bar");
}
もちろん、SecondArgは、プロパティ、フィールド、varialble、などかもしれない...
の代替構文はこのあいまいさを持っていません。
編集 - 280Z28することにより、このセクション:ここにこれを追加するため申し訳ありませんが、それは本当にユニークな答えはありません、それはコメントのために長すぎるとコードが含まれています。あなたは、あいまいさを示唆したが、あなたの例では、決定ケースをハイライト表示されませんでした。私はあなたが与えた例が混乱する可能性が何かを指摘すると思うが、オブジェクト初期化子の周りに必要な
{}
は、基本構文の曖昧さを防ぐことができます。次のコードのための私の説明は複数行のブロックコメントとして埋め込まれている。
[AttributeUsage(AttributeTargets.Class)]
public sealed class SomeAttribute : Attribute
{
public SomeAttribute() { }
public SomeAttribute(int SomeVariable)
{
this.SomeVariable = SomeVariable;
}
public int SomeVariable
{
get;
set;
}
}
/* Here's the true ambiguity: When you add an attribute, and only in this case
* there would be no way without a new syntax to use named arguments with attributes.
* This is a particular problem because attributes are a prime candidate for
* constructor simplification for immutable data types.
*/
// This calls the constructor with 1 arg
[Some(SomeVariable: 3)]
// This calls the constructor with 0 args, followed by setting a property
[Some(SomeVariable = 3)]
public class SomeClass
{
}
<時間> 他のヒント
これはかわすにOfficeアプリケーションで動作するようにまともなAPIを提供する問題を助けます! :)
オフィスのAPIのいくつかの部分は大丈夫ですが、はっきりオプション/名前付きパラメータを持つ言語から使用するために設計されたエッジケースがあります。 C#は持っているだから、なぜそれらを持っています。
オプションのパラメータはまた、クラスが受け入れられた引数の単なるバリエーションれている方法の数十を提供し、問題を回避します。
Exceptionクラスを考えてみましょう。代わりに、オプションの引数を持つ1つのコンストラクタの、それはメッセージを持っている "の組み合わせごとに4つのコンストラクタを持っている、と「内部例外」を有しています。それは大丈夫だが、今あなたがのInnerExceptionを取るコンストラクタにnull値を提供する場合に何が起こるかを検討しますか?それはsortofなしのInnerExceptionパラメータを持つコンストラクタのように、正確なしのInnerExceptionパラメータを持つとコンストラクタのように動作しない、またはそれがnull参照の例外をスローしますか?
2つのオプションのパラメータを持つ単一のコンストラクタは、ヌルのInnerExceptionを渡すと、それを全く含んでいないと同等であったこと、それはより明白いただろう。デフォルト引数に最適な場所。
また、今、すべての派生例外クラスも無意味面倒である4つのコンストラクタを含める必要があることを忘れないでください。
これは、COM相互運用が非常に簡単になります。
C#4 VB.Netまでの相互運用のためのより良い言語でした。デフォルト値がなければ、あなたは、C#でダミーREFパラメータの膨大なリストを持っています。
コードの簡潔さが心にバネ明らかです。あなたは一つの関数を定義することができるのに、なぜいくつかのオーバーロードを定義します。あなたは2つの同一の型指定されたパラメータを持っている場合にも、しかし、あなたが必要な場合がありますオーバーロードのフルセットを構築することができるとは限らない。
また、これはコンパイルされません。
[AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = true)]
sealed class MyAttribute : Attribute
{
public MyAttribute(object a = null)
{
}
}
class Test
{
[My] // [My(a: "asd")]
int prop1 { get; set; }
}
これが行いながらます:
[AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = true)]
sealed class MyAttribute : Attribute
{
public MyAttribute()
{
}
public object a { get; set; }
}
class Test
{
[My] // [My(a=null)]
int prop1 { get; set; }
}