How to Clone Objects

后端 未结 13 1174
北海茫月
北海茫月 2020-11-30 04:36

When I do the following.. anything done to Person b modifies Person a (I thought doing this would clone Person b from Person a). I also have NO idea if changing Person a wil

相关标签:
13条回答
  • 2020-11-30 04:56

    In my opinion, the best way to do this is by implementing your own Clone() method as shown below.

    class Person
    {
        public string head;
        public string feet;
    
        // Downside: It has to be manually implemented for every class
        public Person Clone()
        {
            return new Person() { head = this.head, feet = this.feet };
        }
    }
    
    class Program
    {
        public static void Main(string[] args)
        {
            Person a = new Person() { head = "bigAF", feet = "smol" };
            Person b = a.Clone();
    
            b.head = "notEvenThatBigTBH";
    
            Console.WriteLine($"{a.head}, {a.feet}");
            Console.WriteLine($"{b.head}, {b.feet}");
        }
    }
    

    Output:

    bigAf, smol

    notEvenThatBigTBH, smol

    b is totally independent to a, due to it not being a reference, but a clone.

    Hope I could help!

    0 讨论(0)
  • 2020-11-30 04:57

    I use AutoMapper for this. It works like this:

    Mapper.CreateMap(typeof(Person), typeof(Person));
    Mapper.Map(a, b);
    

    Now person a has all the properties of person b.

    As an aside, AutoMapper works for differing objects as well. For more information, check it out at http://automapper.org

    Update: I use this syntax now (simplistically - really the CreateMaps are in AutoMapper profiles):

    Mapper.CreateMap<Person, Person>;
    Mapper.Map(a, b);
    

    Note that you don't have to do a CreateMap to map one object of the same type to another, but if you don't, AutoMapper will create a shallow copy, meaning to the lay man that if you change one object, the other changes also.

    0 讨论(0)
  • 2020-11-30 04:58

    To clone your class object you can use the Object.MemberwiseClone method,

    just add this function to your class :

    public class yourClass
    {
        // ...
        // ...
    
        public yourClass DeepCopy()
        {
            yourClass othercopy = (yourClass)this.MemberwiseClone();
            return othercopy;
        }
    }
    

    then to perform a deep independant copy, just call the DeepCopy method :

    yourClass newLine = oldLine.DeepCopy();
    
    0 讨论(0)
  • 2020-11-30 04:58
      public static T Clone<T>(T obj)
      {
          DataContractSerializer dcSer = new  DataContractSerializer(obj.GetType());
          MemoryStream memoryStream = new MemoryStream();
    
          dcSer.WriteObject(memoryStream, obj);
          memoryStream.Position = 0;
    
          T newObject = (T)dcSer.ReadObject(memoryStream);
          return newObject;
      }
    
    0 讨论(0)
  • 2020-11-30 05:00

    MemberwiseClone is a good way to do a shallow copy as others have suggested. It is protected however, so if you want to use it without changing the class, you have to access it via reflection. Reflection however is slow. So if you are planning to clone a lot of objects it might be worthwhile to cache the result:

    public static class CloneUtil<T>
    {
        private static readonly Func<T, object> clone;
    
        static CloneUtil()
        {
            var cloneMethod = typeof(T).GetMethod("MemberwiseClone", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);
            clone = (Func<T, object>)cloneMethod.CreateDelegate(typeof(Func<T, object>));
        }
    
        public static T ShallowClone(T obj) => (T)clone(obj);
    }
    
    public static class CloneUtil
    {
        public static T ShallowClone<T>(this T obj) => CloneUtil<T>.ShallowClone(obj);
    }
    

    You can call it like this:

    Person b = a.ShallowClone();
    
    0 讨论(0)
  • 2020-11-30 05:04

    What you are looking is for a Cloning. You will need to Implement IClonable and then do the Cloning.

    Example:

    class Person() : ICloneable
    {
        public string head;
        public string feet; 
    
        #region ICloneable Members
    
        public object Clone()
        {
            return this.MemberwiseClone();
        }
    
        #endregion
    }
    

    Then You can simply call the Clone method to do a ShallowCopy (In this particular Case also a DeepCopy)

    Person a = new Person() { head = "big", feet = "small" };
    Person b = (Person) a.Clone();  
    

    You can use the MemberwiseClone method of the Object class to do the cloning.

    0 讨论(0)
提交回复
热议问题