12

C#コンストラクターを作成するときにどのようなアプローチを取るべきか、誰かにアドバイスしてもらえますか?

のような他の言語ではC++、すべて問題ありません。通常、内部フィールドを表示せず、ゲッター/セッターを提供しません。

これは、クラスにコンストラクターを提供して、ローカル メンバーのすべてまたは一部を初期化し、満足できることを意味します。


C#しかし、 は を持っているpropertiesので、次のように書くことができます:

Class x = new Class { Field1 = new Field1 ...., Field2 = new Field2 }

これにより、オブジェクト構築の連鎖が可能になり、私が推測するように、多くのコンストラクターを削除できますproperties

これをプロパティのデフォルト値と組み合わせると、私が推測するように、実際にいくつかの作業を行う特殊化されていないコンストラクターを完全に取り除くことができます。

さて、冗長なコンストラクターを削除し、フィールドの初期化によるオブジェクトの構築を許可してもよろしいですか?

このアプローチの欠点は何ですか? フィールドとコンストラクターの使用法を組み合わせることについて、誰かが一般的な推奨事項rules of thumbを教えてくれますか?

ありがとうございました。

4

9 に答える 9

16

私自身の経験則は単純です。オブジェクトを完全に構築するために何かが必要な場合、それは ctor パラメータでなければなりません。

良い例は、StreamReader や BinaryReader などの Stream ヘルパー オブジェクトの 1 つです。関連する Stream オブジェクトがないと機能しないため、コンストラクターで指定する必要があります。

于 2011-03-30T12:49:44.973 に答える
6

私の意見では、冗長コンストラクターと呼ばれるものを使用しても問題はありません。コンストラクターを定義することが十分に理にかなっている場合、それはおそらく、そのようにする必要性が本当にあるからです。

于 2011-03-30T12:48:41.870 に答える
4

コンストラクターを使用して、コンシューマーに強制的に値をクラスに提供させることができます。

私の経験則では、フィールドはオプションのデータ用であり、コンストラクターは必要なデータを強制するために使用できます。

しかし、質問は誤った二分法です。C++ は C# と同じように動作します。「フィールド」(実際にはプロパティです。フィールドはクラスレベルの変数です) は通常、内部値を設定するためのゲッター/セッターとして使用されnewます。フィールドを設定できる構文は、

Class x = new Class();
x.Field1 = new Field1();
x.Field2 = new Field2();
于 2011-03-30T12:49:30.553 に答える
2

ベスト プラクティスは、使用可能な状態でオブジェクトを作成することです。プロパティ セッターへの依存を制限するようにしてください。

これにより、不完全なオブジェクトを作成する可能性が減り、コードが壊れにくくなります。

于 2011-03-30T12:49:59.297 に答える
2

あなたが投稿したコードは、オブジェクト初期化子と呼ばれるものを使用しています。これは、ごく最近導入された単なる構文糖衣です。オブジェクト初期化子の使用は、コンストラクターを呼び出してプロパティを設定する簡単な方法です。他の言語で使用したのと同じ方法で、C# でコンストラクターを引き続き使用する必要があります。一般的なルールは、クラスが適切に初期化されるためにオブジェクトまたは値を必要とする場合、そのパラメーターをコンストラクターを介して渡す必要があるということです。値が必要ない場合は、設定可能なプロパティにするのが合理的です。

一般的に言えば、可能な場合はセッターの使用をまったく避けます (不可能な場合が非常に多くあります)。

于 2011-03-30T12:50:41.387 に答える
1

パブリック パラメーターなしの構築とそれに続くプロパティの初期化のアプローチは、XAML で使用するために一般的 (必須?) であり、多くの WPF おもちゃがこれを行います。

直面する唯一の問題は部分的に初期化されたオブジェクトですが、フィールドを使用する前にオブジェクトの状態を簡単に検証できます。

個人的には、コンストラクターで重要な値のパラメーターを作成し、オブジェクトのコピーと一連のオプション パラメーターからコピー コンストラクターを作成しますが、XAML で使用する必要があるものはまだ作成していません。

于 2011-03-30T12:51:35.163 に答える
1

オブジェクト初期化構文は単なる構文糖衣です。C#1でも書くことができます

Class c = new Class();
c.Property1 = value1;
c.Property2 = value2;
c.Property3 = value3;
....

C# 3 は基本的に構文を次のように短縮します。

Class c = new Class 
{
   Property1 = value1, 
   Property2 = value2, 
   Property3 = value3
   ....
}

コンストラクターのポイントは、フィールドを設定するだけではありません。コンストラクターは、パラメーターに基づいてオブジェクトを論理的に構築する必要があります。これにより、コンストラクターが返されたときに、すぐに使用できるオブジェクトが得られます。

于 2011-03-30T12:54:27.327 に答える
0

ここでドメイン オブジェクトを参照していると思われますが、サービスの場合、サービスの依存関係をコンストラクターを介して注入すると、依存関係を「新しくする」のではなく、サービスがより自己文書化されます。さらに、これにより、依存性注入コンテナーをより簡単に使用できるようになります。

于 2011-03-30T12:58:08.073 に答える
0

大丈夫ですか?まあ、それは依存します...

オブジェクト初期化子を使用するには、パブリック セッターをすべてのフィールドに公開する必要がありますが、これは望ましくない場合があります。それらを公開してよろしければ、先に進んでコンストラクターを削除してください。しかし、何かできるからといって、そうしなければならないわけではありません。すべてのフィールドがパブリックに設定可能であることがわかった場合は、コンストラクターを削除する必要があります。コンストラクターを削除できるようにするためだけにフィールドを設定可能にしないでください。

于 2011-03-30T12:51:58.140 に答える