public static T DeepCopy<T>(T obj)
{
if (obj == null)
throw new ArgumentNullException("Object cannot be null");
return (T)Process(obj);
}
static object Process(object obj)
{
if (obj == null)
return null;
Type type = obj.GetType();
if (type.IsValueType || type == typeof(string))
{
return obj;
}
else if (type.IsArray)
{
Type elementType = Type.GetType(
type.FullName.Replace("[]", string.Empty));
var array = obj as Array;
Array copied = Array.CreateInstance(elementType, array.Length);
for (int i = 0; i < array.Length; i++)
{
copied.SetValue(Process(array.GetValue(i)), i);
}
return Convert.ChangeType(copied, obj.GetType());
}
else if (type.IsClass)
{
object toret = Activator.CreateInstance(obj.GetType());
//FieldInfo[] fields = type.GetFields(BindingFlags.Public |
// BindingFlags.NonPublic | BindingFlags.Instance);
FieldInfo[] fields = GetAllFields(type).ToArray();
foreach (FieldInfo field in fields)
{
object fieldValue = field.GetValue(obj);
if (fieldValue == null)
continue;
field.SetValue(toret, Process(fieldValue));
}
return toret;
}
else
{
return null;
//throw new ArgumentException("Unknown type");
}
}
public static IEnumerable<FieldInfo> GetAllFields(Type t) {
if (t == null) return Enumerable.Empty<FieldInfo>();
BindingFlags flags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance
| BindingFlags.DeclaredOnly;
return t.GetFields(flags).Union(GetAllFields(t.BaseType));
}
Note that If we restrict to Serializable then using Memory Stream can deep copy
class Program
{
static void Main(string[] args)
{
Outside o = new Outside() { Data = new Inside() { Name = "n1", Price = 199 } };
Outside o_sc = o.ShadowCopy;
o_sc.Data.Name = "Changed"; // change o as well since Shadow copy reference
Outside o_dc = o.DeepCopy;
o_dc.Data.Name = "Reset"; // not affect o
}
}
[Serializable]
public class Outside
{
public Inside Data { get; set; }
public Outside ShadowCopy { get { return MemberwiseClone() as Outside ; } }
public Outside DeepCopy
{
get
{
MemoryStream m = new MemoryStream();
BinaryFormatter b = new BinaryFormatter();
b.Serialize(m, this);
m.Position = 0;
return b.Deserialize(m) as Outside;
}
}
}
[Serializable]
public class Inside
{
public string Name { get; set; }
public double Price { get; set; }
}
Wednesday, February 29, 2012
Deep Copy Helper
Sunday, February 19, 2012
HTML5 Canvas API
<canvas w h id="cv"/>
var ctx=document.getElementById("cv").getContext('2d');
Path Drawing:
ctx.beginPath();
ctx.moveTo(x,y);
ctx.lineTo(x1,y1);
ctx.closePath();
Fill
ctx.fillRec();
ctx.fillStyle='rgba(0,0,0,0.2)'; alpha 0.2 for black.
Mouse move vs. Touch move
cv.onMouseMove= function Draw(e) {..}
document.addEventListener('touchmove', function (e) { });
e.preventDefault(); not allow Ipad Giggle.
e.targetTouches[0].pageX;
ctx.transform (matrix+d);
cx.scale(60%);
Subscribe to:
Comments (Atom)