设计-防止未分配对象的图案

本文关键字:对象 分配 设计 | 更新日期: 2023-09-27 17:50:57

我经常收到一些关于"使用'new'表达式创建的未分配对象"的重新锐化警告。剪下的以下代码应说明情况:

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

简化代码剪切:

监控类.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;
   }
}

到目前为止还不错。

如果我现在使用上面的观察者类,如下所示:

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

比我得到一个重新锐化警告"可能未分配的对象创建'新'表达式"。

我现在的问题是,是否有更好的解决方案/模式来设计这个观察者。当然,我可以将新的观察者实例分配给一个私有字段。但我有一块从未使用过的田地。或者我可以用属性设置monitoredClassInstance和dataClassInstance,而不是在构造函数中传递它们。但这只是防止了警告,但实际上并没有改变体系结构。

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

设计-防止未分配对象的图案

它可能很好。当然,它之所以有效,是因为您附加了一个事件处理程序,从而将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((中抑制警告,调用它的人就不必担心了

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

如果您想以明确的方式控制取消订阅。