【发布时间】:2021-04-20 18:26:01
【问题描述】:
我有一个这样定义的抽象基类:
public abstract class BaseItem: INotifyPropertyChanged, ICloneable
{
// Various Properties...
public event public event PropertyChangedEventHandler PropertyChanged;
public object Clone()
{
var clone = (BaseItem)MemberwiseClone();
return clone;
}
}
派生类继承并使用基类的 Clone 方法,因此它们不必实现自己的 Clone 方法(加上一些额外的、不相关的原因)。
通常,此代码按预期工作。唯一的问题是有一个不需要的副作用。因为我使用 MemberwiseClone 来克隆实例,所以引用类型是浅拷贝的,不幸的是其中包括事件。因此,任何已订阅原始实例事件的对象也将订阅克隆实例上的事件。这就是问题所在。
有没有什么方法可以使用 BaseItem.Clone 方法克隆 BaseItem 派生类的实例而不也克隆事件?
【问题讨论】:
-
不幸的是
MemberwiseClose是一个extern所以很难复制+粘贴+修改它来做你想做的事。我建议您致电MemberwiseClone,然后使用this technique 删除事后的事件处理程序。 -
只要
clone.PropertyChanged = null;。如果您拥有事件处理程序,则无需采用@JohnWu 提到的复杂方式。 -
是的,我希望能够完全不复制事件处理程序,而不是事后删除它们,但如果前者确实不可能,那么我猜后者将不得不工作。 @ckuri 的解决方案非常有效。谢谢。
-
您需要每个派生类用正确的复制语义覆盖
Clone。要获得DerivedClass的返回值,您可以使用Curiously Recurring Template Patternpublic abstract class BaseItem<T> where T : BaseItem<T>
标签: c# cloning icloneable