/// <summary> /// Merge the changed members (recursively) from one object into another. /// /// <para/> /// This function will recurse through the members of the "from" object and /// take all the members that have a change flag set and copy them into the "into" /// object. /// </summary> /// <param name="into">Object to merge into.</param> /// <param name="from">Object whose changes shall be merged into "into".</param> public static void MergeChanges(Object into, Object from) { if (from == null || into == null) { throw new SoftwareViolationException("Objects must not be null in call to MergeChanges"); } if (from.GetTypeId() != into.GetTypeId()) { throw new SoftwareViolationException("Objects must have same TypeId for MergeChanges"); } try { System.Int32 numMembers = Members.GetNumberOfMembers(into.GetTypeId()); for (System.Int32 member = 0; member < numMembers; ++member) { System.Int32 arraySize = Members.GetArraySize(into.GetTypeId(), member); for (System.Int32 index = 0; index < arraySize; ++index) { ContainerBase fromContainerB = from.GetMember(member, index); ContainerBase intoContainerB = into.GetMember(member, index); //is it an object member? if (fromContainerB is ObjectContainerBase) { ObjectContainerBase fromContainerOB = fromContainerB as ObjectContainerBase; ObjectContainerBase intoContainerOB = intoContainerB as ObjectContainerBase; if (fromContainerOB.IsChangedHere()) //this specific member has changed { if (fromContainerOB.IsNull()) { intoContainerOB.SetNull(); } else { intoContainerOB.InternalObj = fromContainerOB.InternalObj.Clone(); intoContainerOB.SetChangedHere(true); } } else if (fromContainerOB.IsChanged()) //some child has changed we need to recurse { //unless the type has changed or the into-member is null if (intoContainerOB.IsNull() || intoContainerOB.InternalObj.GetTypeId() != fromContainerOB.InternalObj.GetTypeId()) { //If the type is changing we write a warning if (!intoContainerOB.IsNull()) { System.Console.WriteLine("Warning (Contact a DOB developer if you do not understand it):"); System.Console.WriteLine("The type of a member has changed without the change flag being set in 'from'."); } //if it was null we don't warn (even if it is a little bit suspicious to do that...) intoContainerOB.InternalObj = fromContainerOB.InternalObj.Clone(); intoContainerOB.SetChangedHere(true); } else { //recurse MergeChanges(intoContainerOB.InternalObj, fromContainerOB.InternalObj); } } } else //no, normal member { if (fromContainerB.IsChanged()) { intoContainerB.Copy(fromContainerB); } } } } } catch (System.InvalidCastException exc) { throw new SoftwareViolationException("Cast failed inside MergeChanges" + exc.Message); } }
/// <summary> /// Copy constructor. /// </summary> /// <param name="other">ObjectContainerBase.</param> protected ObjectContainerBase(ObjectContainerBase other) : base(other) { }