3

簡単に解決できますが、若い頃にはまだ遭遇したことのない設計上の問題に遭遇しました。

他の何かが起こる前に、いくつかのセットアップ手順を実行する必要があるクラスがあります。

ただし、このクラスの構築中に、ユーザーが独自の情報をクラスに追加できるように、コンストラクターのパラメーターにデリゲートを渡すことができます。

ただし、これが呼び出されると、クラスを作成しているスコープにはまだ有効なインスタンスがないため、null 例外エラーが発生します。

これを回避するにはどうすればよいですか?「this」のインスタンスをそのデリゲートに渡す必要がありますか?

ここでどのような決定を下すのが良いでしょうか? デリゲートへの呼び出しを簡単に行うことができる「StartServices()」メソッドがありますが、設計上はコンストラクターに含める必要があると感じています。

アドバイスありがとう!

4

5 に答える 5

6

(または同様の)を渡したいように思われるAction<T>ので、クラスがデリゲートを必要とする任意の時点で、;を呼び出すことができますtheDelegate(this)。例えば:

var instance = new SomeType(..., obj => { /* extra code invovling obj */ });

次にobj、それが作成されたときのインスタンスになります。これには、コンパイラによって生成されたメソッドが状態/キャプチャを必要としないという利点があります(自分で必要な場合を除く)。

でも!注意して扱う必要があるのと同じ理由で、コンストラクターでデリゲートを呼び出すことには注意します-ディープオブジェクトモデルでは、中間レベルのコンストラクター(デリゲートを呼び出すかオーバーライドされる)の時点でクラス全体が完全に作成されない場合がありますvirtualメソッド)が起動し、不完全な状態のオブジェクトへの危険なアクセスを提供します。

于 2009-12-28T23:05:19.453 に答える
4

ファクトリメソッドの使用を検討してください:

public class MyClass
{
    private MyClass() {}

    public static MyClass Create(delegate d ...)
    {
        var instance = new MyClass();
        d.(instance);
        return instance;
    }
}

次に、次のように使用します。

var o = MyClass.Create(...);

ファクトリクラスを使用することもできます。

var o = factory.CreateMyClass(...);
于 2009-12-28T23:07:13.680 に答える
3

コンストラクター内でデリゲートを使用しないことをお勧めします。デリゲートは他のスレッドのデータに簡単にアクセスでき、いくつかの明らかでない副作用を引き起こします。この場合、クラスの作成とクラスの初期化を分割する必要があります。

Factory パターンを使用すると、複雑なオブジェクトの作成の責任を明確に分離できますが、オブジェクトの初期化は不要です。コンストラクターに動作を注入することはアンチパターンだと考えています。

問題の解決策は、明確に定義されたインターフェイスを使用して、(オブジェクト) 依存関係として動作を注入することです。デリゲートをコンストラクターに渡したいというあなたの希望は、懸念の分離が不十分であり、私にとって SingelResponsibilityPrinciple に違反していることを示しています。

于 2009-12-28T23:23:24.023 に答える
2

基本的に、必要なコードをコンストラクターに含めるべきではないように思われます。コンストラクターは、オブジェクトを作成するものです。オブジェクトが終了するまで、オブジェクトが「正しく機能する」ことは保証されません。これで、機能する可能性があります。はい、このポインターを取得できますが、コードを呼び出すと、完全に構築されていることが期待されます。したがって、設計の観点からは、これは良い習慣ではありません。コンストラクターの後に呼び出される別のメソッドを用意するだけです(ポリモーフィズムに役立つ場合はインターフェースを使用します)。

于 2009-12-28T23:08:38.157 に答える
0

そのアプローチは奇妙に思えますが、デリゲートを介してどのようなセットアップ作業が行われるのでしょうか?

おそらく、コンストラクターの最後でイベントを発生させる方が、もう少し標準的な方法になるでしょう。

于 2009-12-28T23:12:25.283 に答える