10

我经常收到一些关于“使用‘新’表达式创建的未分配对象”的更清晰的警告。以下代码片段将演示这种情况:

我正在使用一个助手类(Observer.cs),它监视其他类(MonitoredClass.cs)的一些属性。当一个属性改变时,观察者类将改变的值写入另一个数据类(DataClass.cs)。

简化的代码被剪断:

监控类.cs:

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

数据类.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);
...

比我得到一个更清晰的警告“可能由'new'表达式创建的未分配对象”。

我现在的问题是,是否有更好的解决方案/模式来设计这个观察者。粗略地说,我可以将新的观察者实例分配给一个私有字段。但比我有一个从未使用过的字段。或者我可以设置带属性的监控类实例和数据类实例,而不是在构造函数中传递它们。但这只是防止警告,实际上并没有改变架构。

提前感谢您的建议、意见、模式等。

4

2 回答 2

9

它可能很好。当然,它之所以有效,是因为您附加了一个事件处理程序,从而将 Observer 的生命周期与 MonitoredClass 的生命周期联系起来。如果您没有附加事件处理程序,那么 Observer 将没有对它的引用,并且它(最终)将被垃圾收集。

考虑一下,因此将构造函数设为私有并编写公共静态工厂方法来创建它可能会更清楚:

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 回答