Creating a Deep Clone of an object in C#.
Usage:
//Item is a class you have created. substitute it with your Person object or other
CloneFactory<Item> clone = new CloneFactory<Item>();
Item item = clone.Clone(item);
CloneFactory class code.
public class CloneFactory
{
public CloneFactory()
{
}
public virtual T Clone(T toBeCloned)
{
T copy = default(T);
if (toBeCloned == null)
return copy;
#region if it supports ICloneable
if (toBeCloned is ICloneable)
{
copy = (T) ((ICloneable)toBeCloned).Clone();
return copy;
}
#endregion
#region Does it Contain SerializableAttribute ?
int serialized = (int)toBeCloned.GetType().Attributes & (int)TypeAttributes.Serializable;
if (serialized == 0)
{
//No serialization Attribute found
return copy;
}
else
{
try
{
//It has a Serializable Attribute, lets try serialization
using (Mutex mutex = new Mutex())
{
mutex.WaitOne();
lock (toBeCloned)
{
MemoryStream stream = new MemoryStream();
BinaryFormatter binFormatter = new BinaryFormatter();
binFormatter.Serialize(stream, toBeCloned);
stream.Close();
byte[] buffer = stream.GetBuffer();
MemoryStream mem = new MemoryStream(buffer);
object obj = binFormatter.Deserialize(mem);
copy = (T)obj;
mem.Close();
}
return copy;
}
}
catch (Exception ex)
{
throw;
}
}
#endregion
}
}
When serializing using XmlSerializer and/or the BinaryFormatter, if you have events hooked up within the object graph, with handlers on your form, you can get serialization errors. if you do, you will get an error like the one below. To remedy this, your must specify that you do not want to serialize certain objects, events by using the NonSerialized for binary and XmlIgnore ? for xml serialization.
For example, often if you are creating proper business objects, you will be implementing the IPropertyChanged interface. A good thing to do! But when trying to serialize you may get errors, if your form has eventhandlers attached.
The answer is to tell the .NET runtime, to
not serialize the event. However, you cannot place the [NonSerialized] attribute on an event.
The answer is to tell the runtime that the
field (behind the scenes, holding the property event delegate) should be marked as NonSerializable by specifying the
field: prefix.
Example error:
Type 'Form1' in Assembly 'MyAssembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' is not marked as serializable.
Answer: Put NonSerialized on all fields and/or public event declarations
[field: NonSerialized]
public event PropertyChangedEventHandler PropertyChanged;
Tags: cloning, serialization, c#, .net