2013-01-08 8 views
7

「新しい表現で作成された未割り当てオブジェクト」に関する警告が表示されることがよくあります。他のクラス(MonitoredClass.cs)のいくつかのプロパティを監視するヘルパークラス(Observer.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; } 
} 

Observer.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); 
... 

私はReSharperの警告が表示されますよりも、「『新しい』式によって作成された可能性割り当てられていないオブジェクト」。

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

おかげで、意見、パターンなど

+0

"新しいオブザーバ(mci、dci)"を変数に割り当てていますか? –

+0

ガーベッジ・コレクターがnewleyのインスタンス化された 'Observer'を収集するのを止めますか? – Jodrell

+0

var a =新しいオブザーバ(monitoredClassInstance、dataClassInstance); – phnkha

答えて

8

そのままの場合があります。もちろん、イベントハンドラをアタッチしてオブザーバの存続期間をMonitoredClassのものに結びつけているためにのみ機能します。イベントハンドラを添付していない場合、オブザーバは参照を持たず、(最終的に)ガベージコレクションされます。それについて考えて

、それゆえ、コンストラクタをプライベートにしてより明確にし、それを作成するためのpublic staticファクトリメソッドを記述することがあります

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; 
    } 
} 

次にあなたが守って内部の警告を抑制することができます()と呼ん人それを心配する必要はありません。

+0

あなたは正しいです。クラス外では、このソリューションははるかに優れています。 – rhe1980

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; 
} 

のように、サブスクライビングをn明示的な方法。

関連する問題