Deepclone - 传递给ctor的对象不再是==

时间:2014-10-30 20:18:28

标签: .net clone

见!=
我需要那个== 不只是返回true - 是同一个对象

如果我更改了MyObj1.MyRepeat,则更改也在MyObj2.MyRepeat中 如果我改变MyObj1Clone.MyRepeat它不会改变MyObj2Clone.MyRepeat(或MyObj1.MyRepeat)

非常确定我只需编写一个CustomClone而不使用此序列化/反序列化DeepClone
只是检查 - 还有另一种方式吗?

MyRepeatedObj MyRepeat = new MyRepeatedObj("xxx");

MyObj MyObj1 = new MyObj (1, MyRepeat );
MyObj MyObj2 = new MyObj (2, MyRepeat );

//  MyObj1.MyRepeat  == MyObj2.MyRepeat

MyObj MyObj1Clone = DeepClone(MyObj1);
MyObj MyObj2Clone = DeepClone(MyObj2);

//  MyObj1Clone.MyRepeat  != MyObj2Clone.MyRepeat


public static T DeepClone<T>(T obj)
{
    using (var ms = new MemoryStream())
    {
        var formatter = new BinaryFormatter();

        formatter.Serialize(ms, obj);
        ms.Position = 0;

        return (T)formatter.Deserialize(ms);
    }
}

正如汉斯所建议的那样,我将GUID引入PK并将其用于覆盖等于
.Equal返回true ==仍然是假的,因为看起来DeepCone创建了单独的对象

public Guid PK { get { return guid; } }
public override bool Equals(Object obj)
{
    // Check for null values and compare run-time types.
    if (obj == null) return false;
    if (!(obj is SearchEnum1MVand)) return false;
    SearchEnum1MVand comp = (SearchEnum1MVand)obj;
    return (comp.PK == this.PK);   // && comp.AndOr == this.AndOr
}
public override int GetHashCode()
{
    return FieldDef.ID;
}

我为没有在第一篇文章中包含更多细节而道歉

public MyRepeatedObj(GabeLib.FieldDefEnum1 FieldDef, GabeLib.enumAndOr paramAndOr)
{
    // the si... are MyObj that I pass the reference with this
    siAll = new SearchItemEnum1(paramAndOr, enumSrchCond.All, FieldDef, this);
    siAllNot = new SearchItemEnum1(paramAndOr, enumSrchCond.Not_All, FieldDef, this);
    siAny = new SearchItemEnum1(paramAndOr, enumSrchCond.Any, FieldDef, this);
    siAnyNot = new SearchItemEnum1(paramAndOr, enumSrchCond.Not_Any, FieldDef, this);

当我序列化/反序列化时,这是4个不同的

但是我序列化/反序列化了4个MyObj - 我将尝试序列化/反序列化MyRepeatedObj,然后将4个MyObj作为属性

MyRepeatedObj上的DeepClone修复了它

SearchEnum1MVand searchEnum1MVand = DeepClone<SearchEnum1MVand>(((SearchItemEnum1)fieldDefSSDrowSelected.SearchItems[0]).SearchEnum1MVand);
Debug.WriteLine(searchEnum1MVand.SIall.SearchEnum1MVand.MVid.ToString());
Debug.WriteLine(searchEnum1MVand.SIany.SearchEnum1MVand.MVid.ToString());
searchEnum1MVand.SIall.SearchEnum1MVand.MVid++;
Debug.WriteLine(searchEnum1MVand.SIall.SearchEnum1MVand.MVid.ToString());
Debug.WriteLine(searchEnum1MVand.SIany.SearchEnum1MVand.MVid.ToString());
Debug.WriteLine(searchEnum1MVand.SIall.EnterOrder.ToString());
Debug.WriteLine(searchEnum1MVand.SIany.EnterOrder.ToString());
Debug.WriteLine(searchEnum1MVand.SIany.SearchEnum1MVand.SIall.EnterOrder.ToString());
searchEnum1MVand.SIall.EnterOrder++;
Debug.WriteLine(searchEnum1MVand.SIall.EnterOrder.ToString());
Debug.WriteLine(searchEnum1MVand.SIany.EnterOrder.ToString());
Debug.WriteLine(searchEnum1MVand.SIany.SearchEnum1MVand.SIall.EnterOrder.ToString());

1 个答案:

答案 0 :(得分:2)

  

==仍然是假的,因为看起来DeepCone会创建单独的对象

嗯,是的 - 如果它返回了相同的对象,它就不会成为&#34;克隆&#34;!

Deserialization始终创建新对象。如果您想要一个新的父对象但保留对子对象的引用,那么您需要一个克隆。有几个选项可以做到这一点:

  • 向调用Clone()的{​​{1}}添加MyObj方法(您无法在外部调用它,因为它this.MemberwiseClone();而不是{{1} }}。
  • 使用反射循环遍历字段和属性。将它们复制到新对象