/// <summary>Clones a complex type using field-based value transfer</summary> /// <param name="original">Original instance that will be cloned</param> /// <returns>A clone of the original instance</returns> private static object shallowCloneComplexFieldBased(object original) { Type originalType = original.GetType(); #if (XBOX360 || WINDOWS_PHONE) object clone = Activator.CreateInstance(originalType); #else object clone = FormatterServices.GetUninitializedObject(originalType); #endif FieldInfo[] fieldInfos = ClonerHelpers.GetFieldInfosIncludingBaseClasses( originalType, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance ); for (int index = 0; index < fieldInfos.Length; ++index) { FieldInfo fieldInfo = fieldInfos[index]; object originalValue = fieldInfo.GetValue(original); if (originalValue != null) { // Everything's just directly assigned in a shallow clone fieldInfo.SetValue(clone, originalValue); } } return(clone); }
/// <summary>Clones a complex type using field-based value transfer</summary> /// <param name="original">Original instance that will be cloned</param> /// <returns>A clone of the original instance</returns> private static object deepCloneComplexFieldBased(object original) { Type originalType = original.GetType(); #if (XBOX360 || WINDOWS_PHONE) object clone = Activator.CreateInstance(originalType); #else object clone = FormatterServices.GetUninitializedObject(originalType); #endif FieldInfo[] fieldInfos = ClonerHelpers.GetFieldInfosIncludingBaseClasses( originalType, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance ); for (int index = 0; index < fieldInfos.Length; ++index) { FieldInfo fieldInfo = fieldInfos[index]; Type fieldType = fieldInfo.FieldType; object originalValue = fieldInfo.GetValue(original); if (originalValue != null) { // Primitive types can be assigned directly if (fieldType.IsPrimitive || (fieldType == typeof(string))) { fieldInfo.SetValue(clone, originalValue); } else if (fieldType.IsArray) { // Arrays need to be cloned element-by-element fieldInfo.SetValue( clone, deepCloneArrayFieldBased((Array)originalValue, fieldType.GetElementType()) ); } else { // Complex types need to be cloned member-by-member fieldInfo.SetValue(clone, deepCloneSingleFieldBased(originalValue)); } } } return(clone); }