Generic C# Copy Constructor

前端 未结 5 1379
再見小時候
再見小時候 2021-01-31 10:55

What would be the best way to write a generic copy constructor function for my c# classes? They all inherit from an abstract base class so I could use reflection to map the prop

相关标签:
5条回答
  • 2021-01-31 11:07

    A copy constructor basically means you have a single parameter, which is the object you're going to copy.

    Also, do a deep copy, not a shallow copy.

    If you don't know what deep and shallow copies are, then here's the deal:

    Suppose you're copying a class that has a single row of integers as field.

    A shallow copy would be:

    public class Myclass()
    {
        private int[] row;
        public MyClass(MyClass class)
        {
            this.row = class.row
        }
    }
    

    deep copy is:

    public class Myclass()
    {
        private int[] row;
        public MyClass(MyClass class)
        {
            for(int i = 0; i<class.row.Length;i++)
            {
                this.row[i] = class.row[i];
            }
        }
    }
    

    A deep copy really gets the actuall values and puts them in a new field of the new object, whilst a shallow copy only copies the pointers.

    With the shallow copy, if you set:

    row[3] = 5;
    

    And then print both rows, both prints will have 5 as value of the 4th number. With a deep copy however, only the first print will have this, since the rows don't have the same pointers.

    0 讨论(0)
  • 2021-01-31 11:08

    Avoid reflection if you can. Each class should have the responsibility of copying its own properties, and send it further to the base method.

    0 讨论(0)
  • 2021-01-31 11:13

    You may reference valueinjecter and fasterflect nuget packages and use:

    public class Myclass()
    {
        private string _property;
        public MyClass(MyClass obj)
        {
             this.InjectFrom(obj.DeepClone());
        }
    }
    
    0 讨论(0)
  • 2021-01-31 11:15

    You can create a shallow copy efficiently with reflection by pre-compiling it, for example with Expression. For example, like so.

    For deep copies, serialization is the most reliable approach.

    0 讨论(0)
  • 2021-01-31 11:18

    Here's a constructor that I'm using. Note that this is a shallow constructor, and rather simplistic, due to the nature of my base class. Should be good enough to get you started.

    public partial class LocationView : Location
    {
        public LocationView() {}
    
        // base class copy constructor
        public LocationView(Location value) {
            Type t = typeof(Location);
            PropertyInfo[] properties = t.GetProperties();
            foreach (PropertyInfo pi in properties)
            {
                pi.SetValue(this, pi.GetValue(value, null), null);
            }
        }
        public Quote Quote { get; set; }
    }
    
    0 讨论(0)
提交回复
热议问题