Is there a way to copy a class in C#? Something like var dupe = MyClass(original).
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.
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).
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
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();
~~~
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();
}
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;
}