4

特定のオブジェクトが変更イベントをサブスクライブできるようにする次のクラスがあります。問題は、オブジェクトが同じ種類のものをサブスクライブできるようにするこの機能を必要とするクラスBとCもあることです。確かに、この動作をコピーして貼り付けたくはありません。

共通のベースクラスから継承することを検討しましたが、A、B、Cを含むすべてのクラスはすでに共通のBaseClassから継承しています。また、BaseClassから継承する他のクラスE、F、Gはこの動作を必要としないため、この動作をBaseClassに追加したくありません。

より良い解決策はありますか?

public class A : BaseClass
{

    /*other properties and code */

    public event EventHandler OnChange;
    private bool _hasChanged;
    public bool HasChanged
    {
        get { return _hasChanged; }
        set
        {
            _hasChanged = value;
            //only need to notify when we've changed.
            if (value)
            {
                if (OnChange != null)
                    OnChange(this, EventArgs.Empty);
            }
        }
    }
}
4

4 に答える 4

4

このPostSharpの例で使用されているような、アスペクト指向プログラミングのアプローチを考えてみましょう。これにより、属性を使用してその種の定型コードを挿入できます。

適切なアスペクトを作成した場合は、次のようなコードを作成できます。

public class A : BaseClass
{
    public event EventHandler OnChanged;

    [ChangedNotify("OnChanged")]
    public bool HasChanged { get; set; }
}

または、複数のプロパティに対して単一のイベントを作成するというアイデアの場合は、OnChangeそれをアスペクトにハードコーディングして、コードを次のように減らすことができます。

public class A : BaseClass
{
    [NotifyOnChanged]
    public bool HasChanged { get; set; }
}
于 2010-11-23T00:11:56.940 に答える
2

しばらく継承を使用しないとどうなりますか?

1-共通の基本クラスから継承する代わりに、イベントメカニズムを実装するオブジェクトを使用してイベントメカニズムを必要とするクライアントクラスを作成するとします。

私たちのクラスが

 public class EventNotifier
{
    public event EventHandler OnChange;
    private bool _hasChanged;
    public bool HasChanged
    {
        get { return _hasChanged; }
        set
        {
            _hasChanged = value;
            //only need to notify when we've changed. 
            if (value)
            {
                if (OnChange != null)
                    OnChange(this, EventArgs.Empty);
            }
        }
    }
}

2-2-

 public class A
{
    private EventNotifier eventNotifier;
    public EventNotifier MyEventNotifier { get { return eventNotifier; } }

    public A()
    {
        eventNotifier = new EventNotifier();
    }


}

3-クラスA(継承/構成されたクラスA)のユーザー

これは、BにAが含まれている場合に使用します

 public class b
{
    A obj ;
    public b()
    {
        obj = new A();
        obj.MyEventNotifier.OnChange += new EventHandler(delegate { Console.WriteLine("Hi"); });
        obj. MyEventNotifier.HasChanged = true;
    }
}
于 2010-11-23T05:17:38.420 に答える
1

BaseClassとA、B、Cの間に、共通の動作を含む中間クラスを導入することを検討できます。このようにして、動作を必要としないE、F、Gを汚染することはありません。

             BaseClass
  -----------------------------
  |                           |
-----                   NotifyBaseClass
E,F,G                         |
                            -----
                            A,B,C

NB AOPは美味しそうに見えますが、PostsharpをMSCodeAnalysisやMSBuildなどの他のテクノロジと連携させるのに大きな問題がありました。

于 2010-11-23T02:10:34.837 に答える
0

通知可能なオブジェクトのサブクラスを用意するのは良い方法かもしれませんが、その方法でさまざまなクラスに乗算する側面があると、注意が必要になる場合があります。別の方法は、それを基本クラスに実際に含めて、そのインターフェースを定義することです。そうすれば、関連するクラスのインターフェースに簡単に取り組むことができます。

実行するときは、それがIChangeable(または何か)であるかどうかを確認し、イベントにのみ接続します。

于 2010-11-23T03:11:24.037 に答える