private void CopyFields(object originalObject, object cloneObject, Type typeToReflect) { IList <ReflectedField> affectedFields = GetAffectedFields(typeToReflect); for (int i = 0; i < affectedFields.Count; i++) { ReflectedField rField = affectedFields[i]; object originalFieldValue; //If fasterflect cannot resolve the type use native GetValue try { originalFieldValue = rField.MemberGetter(originalObject); } catch (InvalidCastException) { originalFieldValue = rField.FieldInfo.GetValue(originalObject); } if (_flagUpdateReferences == false && rField.Behaviour == DeepCloneBehavior.UpdateReferences) { _referencesToUpdate.Add(Tuple.Create(rField, originalFieldValue, cloneObject)); continue; } if (originalFieldValue == null) { continue; } CloneFieldValue(cloneObject, rField, originalFieldValue); } }
private void UpdateReferences() { for (int i = 0; i < _referencesToUpdate.Count; i++) { Tuple <ReflectedField, object, object> refToUpdate = _referencesToUpdate[i]; if (refToUpdate.Item2 != null) { object clonedFieldValue; //can be null and thats ok _visited.TryGetValue(refToUpdate.Item2, out clonedFieldValue); if (clonedFieldValue == null) { clonedFieldValue = InternalCopy(refToUpdate.Item2); } ReflectedField rField = refToUpdate.Item1; try { rField.MemberSetter(refToUpdate.Item3, clonedFieldValue); } catch (InvalidCastException) { rField.FieldInfo.SetValue(refToUpdate.Item3, clonedFieldValue); } } } }
private void CloneFieldValue(object cloneObject, ReflectedField rField, object originalFieldValue) { object clonedFieldValue; if (rField.Behaviour == DeepCloneBehavior.Reinitialize) { object visitedObject; if (_visited.TryGetValue(originalFieldValue, out visitedObject)) { clonedFieldValue = visitedObject; } else { if (rField.InitValue == null) { clonedFieldValue = GetDefault(rField.FieldInfo.FieldType); rField.InitValue = clonedFieldValue; _visited.Add(originalFieldValue, clonedFieldValue); } else { clonedFieldValue = InternalCopy(rField.InitValue); _visited.Add(originalFieldValue, clonedFieldValue); } } } else if (rField.Behaviour == DeepCloneBehavior.SetToDefault) { if (originalFieldValue.GetType().IsValueType) { clonedFieldValue = Activator.CreateInstance(originalFieldValue.GetType()); } else { clonedFieldValue = null; } } else { clonedFieldValue = InternalCopy(originalFieldValue); } try { rField.MemberSetter(cloneObject, clonedFieldValue); } catch (InvalidCastException) { rField.FieldInfo.SetValue(cloneObject, clonedFieldValue); } }