0

我有一个代表一些数据的类和一个集合类(从 CollectionBase 派生)。当我将集合类的一个实例分配给另一个时,它是通过引用分配的,因此我实现了ICloneable接口。

    public void Add(object item)
    {
        InnerList.Add(item);
    }

    public object Clone()
    {
        MyCollection clone = new MyCollection();

        foreach (MyClass item in this)
        {
            clone.Add(item);
        }

        return clone;
    }

现在一切正常。但是当我遍历元素并将它们一一添加到克隆实例时,为什么不通过引用添加它们呢?该方法如何Add将其添加到 InnerList 中?为什么不通过引用添加?如果我添加这个集合的一个实例,比如说 aList并更改列表中的元素呢?原来的实例会被改变吗?

编辑:这里是MyClass.

public class MyClass
{
    public bool IsEnabled { get; set; }

    public string Parent { get; set; }

    public string Child { get; set; }

    public MyClass()
    {
        IsEnabled = false;
        Parent = string.Empty;
        Child = string.Empty;
    }

    public MyClass(bool isEnabled, string parent, string child)
    {
        IsEnabled = isEnabled;
        Parent = parent;
        Child = child;
    }

    public bool IsValid()
    {
        return (!Parent.Equals(string.Empty) &&
                !Child.Equals(string.Empty));
    }

    public override bool Equals(object obj)
    {
        if (obj == null)
        {
            return false;
        }

        if (!obj.GetType().IsAssignableFrom(this.GetType()))
        {
            return false;
        }

        return ((MyClass)obj).Parent.Equals(Parent) ||
               ((MyClass)obj).Child.Equals(Child);
    }

    public bool Equals(MyClass myClass)
    {
        if (myClass == null)
        {
            return false;
        }

        return myClass.Parent.Equals(Parent) ||
               myClass.Child.Equals(Child);
    }

    public override int GetHashCode()
    {
        return Parent.GetHashCode();
    }
}

编辑2:我所做的是

MyClass item = new MyClass(true, "test", "test");
MyCollection collection = new MyCollection();

collection.Add(item);

MyCollection newCollection = new MyCollection();
newCollection = (MyCollection) collection.Clone();

newCollection[0].Parent = "changed";

现在,在此之后,我预计 collection[0].Parent 也会更改为“已更改”,但它仍然保持不变。它不是通过引用克隆实例添加的吗?

4

3 回答 3

1

这取决于您要如何实现克隆方法。如果要返回对象的浅表副本,则可以使用Object.MemberwiseClone方法。如果要返回深层副本,则可以使用BinaryFormatter序列化和反序列化对象/集合。这将返回一个新的对象/集合。

于 2012-10-11T14:04:37.663 回答
1

如果您的集合中的项目是引用类型,则它们是通过引用添加的。如果您在克隆集合中添加一些内容,它不会修改原始集合。

于 2012-10-11T13:57:15.070 回答
0
    [Serializable]
    class CustomClass
    {
        int _id;
        string _value;

        public CustomClass(int id, string value)
        {
            _id = id;
            _value = value;
        }
    }

    [Serializable]
    class CustomClassCollection
    {
        private IList<CustomClass> _list = null;

        public CustomClassCollection()
        {
            _list = new List<CustomClass>();
        }

        public void Add(CustomClass a)
        {
            _list.Add(a);
        }
    }



    public static class ObjectCopier
    {
        public static T Clone<T>(this T source)
        {
            if (!typeof(T).IsSerializable)
            {
                throw new ArgumentException("The type must be serializable.", "source");
            }

            if (Object.ReferenceEquals(source, null))
            {
                return default(T);
            }

            IFormatter formatter = new BinaryFormatter();
            Stream stream = new MemoryStream();
            using (stream)
            {
                formatter.Serialize(stream, source);
                stream.Seek(0, SeekOrigin.Begin);
                return (T)formatter.Deserialize(stream);
            }
        }
    }

像这样使用它:

        CustomClassCollection a = new CustomClassCollection();
        CustomClassCollection b = ObjectCopier.Clone<CustomClassCollection>(a);

        a.Add(new CustomClass(1, "A"));
        a.Add(new CustomClass(2, "B"));
        a.Add(new CustomClass(3, "C"));

        b.Add(new CustomClass(1, "A"));
        b.Add(new CustomClass(2, "B"));
于 2012-10-11T14:49:31.590 回答