次のような大量のパラメーターを使用してコンストラクターを作成する必要があります。
new MyClass(param1, param2, param3, ..., param100);
次のように、そのようなオブジェクトを段階的に初期化する方法はありますか?
MyClass obj = new MyClass();
obj.Prop1 = val1;
obj.Prop2 = val2;
obj.checkIfInit() //I am not sure how to do that.
クレイジーコンストラクターが使用されていない場合、正しく初期化されていることを確認するにはどうすればよいですか?
他の人が指摘しているように、実際にはそれほど多くのパラメーターを持つコンストラクターは必要ありません-データモデル型クラスの依存性注入では、多くの場合、多くのパラメーターが必要になります。その場合、通常は、パラメーターを独自のクラスにカプセル化されたサブセットにグループ化するのが最善です。
そのアドバイスにもかかわらず、「ビルダーパターン」の変種で問題に対処することができます。
たとえば、次のようになります。
public sealed class MyClass
{
public MyClass(int prop1, string prop2, DateTime prop3)
{
Prop1 = prop1;
Prop2 = prop2;
Prop3 = prop3;
}
public int Prop1 { get; }
public string Prop2 { get; }
public DateTime Prop3 { get; }
}
最初に、デフォルトのコンストラクターがなく、プロパティがすべて読み取り専用であるため、このクラスが不変になることに注意してください(多くの場合、良い考えです)。
(簡潔にするためにパラメーターチェックを省略しました。)
これで、オブジェクトを構築するためのヘルパークラスを作成できます。
public sealed class MyClassBuilder
{
public MyClass Build()
{
if (!_prop1Set || !_prop2Set || !_prop3Set)
throw new InvalidOperationException("Not all properties set.");
return new MyClass(_prop1, _prop2, _prop3);
}
public MyClassBuilder Prop1(int value)
{
_prop1 = value;
_prop1Set = true;
return this;
}
public MyClassBuilder Prop2(string value)
{
_prop2 = value;
_prop2Set = true;
return this;
}
public MyClassBuilder Prop3(DateTime value)
{
_prop3 = value;
_prop3Set = true;
return this;
}
int _prop1;
string _prop2;
DateTime _prop3;
bool _prop1Set;
bool _prop2Set;
bool _prop3Set;
}
プロパティを設定するための各メソッドはthis
、次のように流暢に使用できるように、を返します。
var builder = new MyClassBuilder();
builder
.Prop1(1)
.Prop2("test")
.Prop3(DateTime.Now);
var myClass = builder.Build(); // Throws if not all properties set.
これにより、パラメーターの検証に大きな柔軟性がもたらされ、一部のパラメーターを省略できるようになります(適切なデフォルトを提供することにより)。
ビルダークラスの実際の例は、AutofacのContainerBuilderクラスであり、その使用法についてはここで説明します。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加