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

現在、すべてが正常に機能しています。しかし、要素を調べてクローン インスタンスに 1 つずつ追加すると、参照によって追加されないのはなぜですか? Addメソッドはそれを InnerList にどのように追加しますか? 参照によって追加されないのはなぜですか?そして、このコレクションのインスタンスを追加してList、リスト内の要素を変更するとどうなるでしょうか? 元のインスタンスは変更されますか?

編集:ここにあり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

コレクション内の項目が参照型の場合、それらは参照によって追加されます。複製されたコレクションに何かを追加しても、元のコレクションは変更されません。

于 2012-10-11T13:57:15.070 に答える
1

クローニング方法をどのように実装するかによって異なります。オブジェクトの浅いコピーを返したい場合は、Object.MemberwiseCloneメソッドを使用できます。ディープ コピーを返したい場合はBinaryFormatter、オブジェクト/コレクションをシリアル化および逆シリアル化するために使用できます。これにより、新しいオブジェクト/コレクションが返されます。

于 2012-10-11T14:04:37.663 に答える
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 に答える