I\'m working in c# with several workspaces that have one specific class which his always the same in each workspace. I would like to be able have a copy of this class to be
Two identical or similar objects from different namespaces ?
You have this:
namespace Cars
{
public class car {
public string Name;
public void Start() { ... }
}
}
namespace Planes
{
public class plane {
public string Name;
public void Fly() { ... }
}
}
Time to apply some class inheritance:
namespace Vehicles
{
public class vehicle
{
public string Name;
} // class
} // namespace
using Vehicles;
namespace Cars
{
public class car: vehicle
{
public string Name;
public void Start() { ... }
} // class
} // namespace
using Vehicles;
namespace Planes
{
public class plane: vehicle
{
public void Fly() { ... }
}
}
And to copy, there is a copy method or constructor, but, I prefer a custom one:
namespace Vehicles
{
public class vehicle {
public string Name;
public virtual CopyFrom (vehicle Source)
{
this.Name = Source.Name;
// other fields
}
} // class
} // namespace
Cheers.
public static T DeepClone<T>(T obj)
{
using (var ms = new MemoryStream())
{
var formatter = new BinaryFormatter();
formatter.Serialize(ms, obj);
ms.Position = 0;
return (T) formatter.Deserialize(ms);
}
}
from here
I had the similar problem. I got to use similar classes but different in terms of namespace only. As a quick solution I performed below steps and it works.
I know there is performance overhead with above way but it is quick to implement and error free.
I got it solved , just to let you know how I did it : This solution is sot perfect because it handle only 1 dimensions array not more.
public static Object CopyObject(Object from , Object to)
{
try
{
Type fromType = from.GetType();
Type toType = to.GetType();
PropertyInfo[] fromProps = fromType.GetProperties();
PropertyInfo[] toProps = toType.GetProperties();
for (int i = 0; i < fromProps.Length; i++)
{
PropertyInfo fromProp = fromProps[i];
PropertyInfo toProp = toType.GetProperty(fromProp.Name);
if (toProp != null)
{
if (toProp.PropertyType.Module.ScopeName != "CommonLanguageRuntimeLibrary")
{
if (!toProp.PropertyType.IsArray)
{
ConstructorInfo ci = toProp.PropertyType.GetConstructor(new Type[0]);
if (ci != null)
{
toProp.SetValue(to, ci.Invoke(null), null);
toProp.SetValue(to, gestionRefelexion.CopyObject(fromProp.GetValue(from, null), toProp.GetValue(to, null)), null);
}
}
else
{
Type typeToArray = toProp.PropertyType.GetElementType();
Array fromArray = fromProp.GetValue(from, null) as Array;
toProp.SetValue(to, copyArray(fromArray, typeToArray), null);
}
}
else
{
toProp.SetValue(to, fromProp.GetValue(from, null), null);
}
}
}
}
catch (Exception ex)
{
}
return to;
}
public static Array copyArray(Array from, Type toType)
{
Array toArray =null;
if (from != null)
{
toArray= Array.CreateInstance(toType, from.Length);
for (int i = 0; i < from.Length; i++)
{
ConstructorInfo ci = toType.GetConstructor(new Type[0]);
if (ci != null)
{
toArray.SetValue(ci.Invoke(null), i);
toArray.SetValue(gestionRefelexion.CopyObject(from.GetValue(i), toArray.GetValue(i)), i);
}
}
}
return toArray;
}
Hope this can help some people. Thanks for helping everyone. Cheers
You either need to refactor all of your duplicate classes into a single shared class or implement a common interface that all of your various classes implement. If you really can't modify the underlying types, create a subclass for each that implements your common interface.
Yes, you can do it with reflection... but you really shouldn't because you end up with brittle, error prone, code.
BinaryFormatter does not work in .Net 4.5 as it remembers from what type of class the instance was created. But with JSON format, it does not. JSON serializer is implemented by Microsoft in DataContractJosnSerializer.
This works:
public static T2 DeepClone<T1, T2>(T1 obj)
{
DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(T1));
DataContractJsonSerializer deserializer = new DataContractJsonSerializer(typeof(T2));
using (var ms = new MemoryStream())
{
serializer.WriteObject(ms, obj);
ms.Position = 0;
return (T2)deserializer.ReadObject(ms);
}
}
and uses as follows:
var b = DeepClone<A, B>(a);