copy a class, C#

后端 未结 12 1758
失恋的感觉
失恋的感觉 2020-12-03 10:13

Is there a way to copy a class in C#? Something like var dupe = MyClass(original).

相关标签:
12条回答
  • 2020-12-03 10:42

    Not any straightforward way that will always work. If your class is [Serializable] or implements ISerializable, you can do a roundtrip serialization to create an identical copy. The same works for [DataContract]

    If you only want a shallow copy, you can try Object.MemberwiseClone(). It's a protected method though, and you can only use it from within the class.

    If you're lucky, the class implements ICloneable and you can just call the Clone() method.

    0 讨论(0)
  • 2020-12-03 10:44

    Not all classes have this functionality. Probably, if a class does, it provides a Clone method. To help implement that method for your own classes there's a MemberwiseClone protected method defined in System.Object that makes a shallow copy of the current instance (i.e. fields are copied; if they are reference types, the reference will point to the original location).

    0 讨论(0)
  • 2020-12-03 10:45

    If your class has just got properties, you could do something like this:

    SubCentreMessage actual;
    actual = target.FindSubCentreFullDetails(120); //for Albany
    SubCentreMessage s = new SubCentreMessage();
    
    //initialising s with the same values as 
    foreach (var property in actual.GetType().GetProperties())
    {
        PropertyInfo propertyS = s.GetType().GetProperty(property.Name);
        var value = property.GetValue(actual, null);
        propertyS.SetValue(s, property.GetValue(actual, null), null);
    }
    

    If you have fields and methods, I am sure you can recreate them in new class using reflections. Hope this helps

    0 讨论(0)
  • 2020-12-03 10:45

    How about something like:

    public class MyClass 
    {
        int i;
        double d;
        string something;
    
        public MyClass(int i, double d) {}
    
        public MyClass Clone()
        {
            return (new MyClass(i, d));
        }
    }
    

    Or if you also need to copy something else not usually known when constructing a new object:

        public MyClass CloneMore()
        {
            MyClass obj = new MyClass(i, d);
            obj.something = this.something;
            return (obj);
        }
    

    Call using:

    MyClass us = them.Clone();
    

    ~~~

    0 讨论(0)
  • 2020-12-03 10:46

    Some reasonable solutions here serializing is a valid way to go about it as well as a clone method for each class.. Whipped this up and It seems to work for the few tests i did on it

    using System.Reflection; using System.Text.StringBuilder();
    
    public static T CopyClass2<T>(T obj){
        T objcpy = (T)Activator.CreateInstance(typeof(T));
        obj.GetType().GetProperties().ToList()
        .ForEach( p => objcpy.GetType().GetProperty(p.Name).SetValue(objcpy, p.GetValue(obj)));
        return objcpy;
    

    }

    And here is the more verbose version I suppose, above suggests you understand Lambda Expressions which isn't common. If you respect readability (Which is totally valid) more I would use below

    public static T CopyClass<T>(T obj)
    {
        T objcpy = (T)Activator.CreateInstance(typeof(T));
        foreach (var prop in obj.GetType().GetProperties())
        {
            var value = prop.GetValue(obj);
            objcpy.GetType().GetProperty(prop.Name).SetValue(objcpy, value);
        }
        return objcpy;
    

    }

    Use this method to list out property's to see if it copied to new reference.. simple it does not list properties of none primitives(structured types).. so you will get a class name

    public static string ListAllProperties<T>(T obj)
    {
            StringBuilder sb = new System.Text.StringBuilder();
            PropertyInfo[] propInfo = obj.GetType().GetProperties();
            foreach (var prop in propInfo)
            {
                var value = prop.GetValue(obj) ?? "(null)";
                sb.AppendLine(prop.Name + ": " + value.ToString());
            }
            return sb.ToString();
    }
    
    0 讨论(0)
  • 2020-12-03 10:50

    How about with JSON?

    You can get JSON package from : https://www.nuget.org/packages/Newtonsoft.Json/

    using Newtonsoft.Json;
    public static List<T> CopyAll<T>(this List<T> list) {
      List<T> ret = new List<T>();
      string tmpStr = JsonConvert.SerializeObject(list);
      ret = JsonConvert.DeserializeObject<List<T>>(tmpStr);
      return ret;
    }
    
    0 讨论(0)
提交回复
热议问题