为什么DependencyObject.MemberwiseClone会这样做?

时间:2016-06-10 18:27:36

标签: c#

为什么在下面调用ShallowCopy会失败Debug.Assert?我希望这两个属性引用不同的集合。

public class MyClass : DependencyObject
{
    public static readonly DependencyProperty ItemsProperty = DependencyProperty.Register(
        "Items",
        typeof(ObservableCollection<int>),
        typeof(MyClass),
        new PropertyMetadata(default(ObservableCollection<int>)));

    public ObservableCollection<int> Items
    {
        get { return (ObservableCollection<int>)GetValue(ItemsProperty); }
        set { SetValue(ItemsProperty, value); }
    }

    public MyClass ShallowCopy()
    {
        Items = new ObservableCollection<int>();

        var copy = (MyClass)this.MemberwiseClone();
        copy.Items = new ObservableCollection<int>();

       Debug.Assert(!ReferenceEquals(copy.Items,Items), "WHY???");
       return copy;
    }
}

1 个答案:

答案 0 :(得分:0)

您无法克隆任意对象。给定对象必须支持克隆。 Object.MemberwiseClone进行调用是不安全的,除非你能证明它是安全的。

例如,在您的脑海中克隆FileStreamButton的内容是什么?这没有意义。

就像当你使用私人反射来混淆某个对象的内部状态时。你得到了未定义的行为。真的,任何事情都可能发生。

如果您很好奇为什么要获得这种确切的行为,您需要反编译DependencyObject.Items.set以查看为什么损坏DependencyObject可能会以这种方式行为不端。我的猜测:由于所有字段都被复制,旧对象和新对象都共享一些状态。这就是为什么在一个对象上设置Items也将其设置在另一个对象上的原因。它下面的变量实际上是相同的。

Object.MemberwiseClone是.NET Framework中的一个设计错误,因为无法充分保护该方法。你发现,默认存在是不安全的。