I was trying to create a "copy" of an object in memory within .Net framework. I ran headlong into the stack vs. heap storage. When I tried to "copy" the parent object to a child object each time I updated the child the parent was also updated. This is occurring because of the Framework memory management defaults. The child object is a reference to the parent. What I need is to clone the object.
Potential Solutions:
Source:
http://www.c-sharpcorner.com/UploadFile/rmcochran/chsarp_memory401152006094206AM/chsarp_memory4.aspx
Sample 1:
using System;
public class IdInfo
{
public int IdNumber;
public IdInfo(int IdNumber)
{
this.IdNumber = IdNumber;
}
}
public class Person
{
public int Age;
public string Name;
public IdInfo IdInfo;
public Person ShallowCopy()
{
return (Person)this.MemberwiseClone();
}
public Person DeepCopy()
{
Person other = (Person)this.MemberwiseClone();
other.IdInfo = new IdInfo(this.IdInfo.IdNumber);
return other;
}
}
public class Example
{
public static void Demo(System.Windows.Controls.TextBlock outputBlock)
{
// Create an instance of Person and assign values to its fields.
Person p1 = new Person();
p1.Age = 42;
p1.Name = "Sam";
p1.IdInfo = new IdInfo(6565);
// Perform a shallow copy of p1 and assign it to p2.
Person p2 = (Person)p1.ShallowCopy();
// Display values of p1, p2
outputBlock.Text += "Original values of p1 and p2:" + "\n";
outputBlock.Text += " p1 instance values: " + "\n";
DisplayValues(outputBlock, p1);
outputBlock.Text += " p2 instance values:" + "\n";
DisplayValues(outputBlock, p2);
// Change the value of p1 properties and display the values of p1 and p2.
p1.Age = 32;
p1.Name = "Frank";
p1.IdInfo.IdNumber = 7878;
outputBlock.Text += "\nValues of p1 and p2 after changes to p1:" + "\n";
outputBlock.Text += " p1 instance values: " + "\n";
DisplayValues(outputBlock, p1);
outputBlock.Text += " p2 instance values:" + "\n";
DisplayValues(outputBlock, p2);
// Make a deep copy of p1 and assign it to p3.
Person p3 = p1.DeepCopy();
// Change the members of the p1 class to new values to show the deep copy.
p1.Name = "George";
p1.Age = 39;
p1.IdInfo.IdNumber = 8641;
outputBlock.Text += "\nValues of p1 and p3 after changes to p1:" + "\n";
outputBlock.Text += " p1 instance values: " + "\n";
DisplayValues(outputBlock, p1);
outputBlock.Text += " p3 instance values:" + "\n";
DisplayValues(outputBlock, p3);
}
public static void DisplayValues(System.Windows.Controls.TextBlock outputBlock, Person p)
{
outputBlock.Text += String.Format(" Name: {0:s}, Age: {1:d}", p.Name, p.Age) + "\n";
outputBlock.Text += String.Format(" Value: {0:d}", p.IdInfo.IdNumber) + "\n";
}
}
// The example displays the following output:
// Original values of p1 and p2:
// p1 instance values:
// Name: Sam, Age: 42
// Value: 6565
// p2 instance values:
// Name: Sam, Age: 42
// Value: 6565
//
// Values of p1 and p2 after changes to p1:
// p1 instance values:
// Name: Frank, Age: 32
// Value: 7878
// p2 instance values:
// Name: Sam, Age: 42
// Value: 7878
//
// Values of p1 and p3 after changes to p1:
// p1 instance values:
// Name: George, Age: 39
// Value: 8641
// p3 instance values:
// Name: Frank, Age: 32
// Value: 7878
Source:
http://msdn.microsoft.com/en-us/library/windowsphone/develop/system.object.memberwiseclone(v=vs.105).aspx
Whilst the standard practice is to implement the
ICloneable
interface (described here, so I won't regurgitate), here's a nice deep clone object copier I found on The Code Project a while ago and incorporated it in our stuff.using System;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
/// <summary>
/// Reference Article http://www.codeproject.com/KB/tips/SerializedObjectCloner.aspx
/// Provides a method for performing a deep copy of an object.
/// Binary Serialization is used to perform the copy.
/// </summary>
public static class ObjectCopier
{
/// <summary>
/// Perform a deep Copy of the object.
/// </summary>
/// <typeparam name="T">The type of object being copied.</typeparam>
/// <param name="source">The object instance to copy.</param>
/// <returns>The copied object.</returns>
public static T Clone<T>(T source)
{
if (!typeof(T).IsSerializable)
{
throw new ArgumentException("The type must be serializable.", "source");
}
// Don't serialize a null object, simply return the default for that object
if (Object.ReferenceEquals(source, null))
{
return default(T);
}
IFormatter formatter = new BinaryFormatter();
Stream stream = new MemoryStream();
using (stream)
{
formatter.Serialize(stream, source);
stream.Seek(0, SeekOrigin.Begin);
return (T)formatter.Deserialize(stream);
}
}
}
Now the method call simply becomes
objectBeingCloned.Clone();
.Source:
http://stackoverflow.com/questions/78536/deep-cloning-objects-in-c-sharp
No comments:
Post a Comment