10

「'new' 式で作成された割り当てられていないオブジェクト」に関して、よりシャープな警告が表示されることがよくあります。切り取られた次のコードは、状況を示します。

Observer.cs他のクラス ( ) の一部のプロパティを監視するヘルパー クラス ( ) を使用していますMonitoredClass.cs。プロパティが変更されると、オブザーバー クラスは変更された値を他のデータ クラスに書き込みます ( DataClass.cs)。

簡素化されたコードが切り取られました:

MonitoredClass.cs:

public class MonitoredClass : INotifyPropertyChanged
{
   // simplified: in fact property calls OnPropertyChange(..)
   public string Property1 { get; set; }
}

DataClass.cs:

public class DataClass
{
   public string LastProperty1Value { get; set; }
}

オブザーバー.cs:

public class Observer
{
   private MonitoredClass _monitoredClass;
   private DataClass _dataClass;
   public Observer(MonitoredClass monitoredClass, DataClass dataClass)
   {
      _monitoredClass = monitoredClass;
      _dataClass = dataClass;
      _monitoredClass.PropertyChanged+=MonitoredClassPropertyChanged;
   }

   private void MonitoredClassPropertyChanged(..)
   {
      _dataClass.LastProperty1Value = _monitoredClass.Property1;
   }
}

ここまでは順調ですね。

上記の Observer クラスを次のように使用すると、次のようになります。

...
new Observer(monitoredClassInstance, dataClassInstance);
...

「「新しい」式によって作成された割り当てられていないオブジェクトの可能性」という再シャープな警告が表示されるよりも。

私の質問は、このオブザーバーを設計するためのより良い解決策/パターンがあるかどうかです。大まかに言うと、新しいオブザーバー インスタンスをプライベート フィールドに割り当てることができます。しかし、私は決して使用されていないフィールドを持っています。または、コンストラクターで渡す代わりに、monitoredClassInstance と dataClassInstance をプロパティで設定できます。しかし、これは警告を防ぐだけで、実際にはアーキテクチャを変更しません。

アドバイス、ご意見、パターンなどよろしくお願いします。

4

2 に答える 2

9

このままでいいのかもしれません。もちろん、これが機能するのは、イベント ハンドラーをアタッチして、Observer の有効期間を MonitoredClass の有効期間に結び付けた場合のみです。イベント ハンドラーをアタッチしていない場合、オブザーバーはそれへの参照を持たず、(最終的に) ガベージ コレクトされます。

考えてみると、コンストラクターを非公開にし、それを作成する public 静的ファクトリー メソッドを作成する方が明確かもしれません。

public class Observer
{
    private MonitoredClass _monitoredClass;
    private DataClass _dataClass;

    public static void Observe(MonitoredClass monitoredClass, DataClass dataClass)
    {
        new Observer(monitoredClass, dataClass);
    }

    private Observer(MonitoredClass monitoredClass, DataClass dataClass)
    {
        _monitoredClass = monitoredClass;
        _dataClass = dataClass;
        _monitoredClass.PropertyChanged+=MonitoredClassPropertyChanged;
    }

    private void MonitoredClassPropertyChanged(..)
    {
        _dataClass.LastProperty1Value = _monitoredClass.Property1;
    }
}

その後、Observe() 内の警告を抑制することができ、それを呼び出す人はそれについて心配する必要がなくなります。

于 2013-01-08T14:40:21.497 に答える
2
public class Observer
{
 private MonitoredClass _monitoredClass;
 private DataClass _dataClass;

 public void Setup(MonitoredClass monitoredClass, DataClass dataClass)
 {
    _monitoredClass = monitoredClass;
    _dataClass = dataClass;
    _monitoredClass.PropertyChanged+=MonitoredClassPropertyChanged;
 }

 private void MonitoredClassPropertyChanged(..)
 {
    _dataClass.LastProperty1Value = _monitoredClass.Property1;
 }
}

Observer o = new Observer();
o.Setup( foo, bar );

これにより、警告が回避されるだけでなく、次のようなオブザーバーに他のメソッドを実装するための変更も得られます。

 public void Close()
 {
    _monitoredClass.PropertyChanged-=MonitoredClassPropertyChanged;
 }

明示的な方法で購読解除を制御したい場合。

于 2013-01-08T14:37:58.910 に答える