/// <summary> /// Method to assign the value of one type to another /// </summary> /// <param name="from">Other object</param> public void Assign(ModelObject from) { // Assigning null values is not supported if (from == null) { throw new ArgumentNullException(nameof(from)); } // Validate the types Type myType = GetType(); if (from.GetType() != myType) { throw new ArgumentException("Types do not match", nameof(from)); } // Assign property values foreach (PropertyInfo property in GetType().GetProperties()) { if (property.PropertyType.IsSubclassOf(typeof(ModelObject))) { ModelObject oldValue = (ModelObject)property.GetValue(this); ModelObject newValue = (ModelObject)property.GetValue(from); if (oldValue == null || newValue == null) { property.SetValue(this, newValue); } else if (oldValue.GetType() != newValue.GetType()) { property.SetValue(this, newValue.Clone()); } else { oldValue.Assign(newValue); } } else if (ModelCollection.GetItemType(property.PropertyType, out Type itemType)) { IList oldModelCollection = (IList)property.GetValue(this); IList newModelCollection = (IList)property.GetValue(from); if (ModelGrowingCollection.TypeMatches(property.PropertyType)) { ModelGrowingCollectionHelper.Assign(oldModelCollection, newModelCollection); } else { ModelCollectionHelper.Assign(oldModelCollection, itemType, newModelCollection); } } else { object newValue = property.GetValue(from); property.SetValue(this, newValue); } } }
/// <summary> /// Create a clone of this instance /// </summary> /// <returns>Cloned object</returns> public object Clone() { // Make a new clone Type myType = GetType(); ModelObject clone = (ModelObject)Activator.CreateInstance(myType); // Assign cloned property values foreach (PropertyInfo property in GetType().GetProperties()) { if (property.PropertyType.IsSubclassOf(typeof(ModelObject))) { ModelObject value = (ModelObject)property.GetValue(this); ModelObject cloneValue = (ModelObject)property.GetValue(clone); if (value == null || cloneValue == null) { property.SetValue(clone, value); } else if (value.GetType() != cloneValue.GetType()) { property.SetValue(clone, value.Clone()); } else { cloneValue.Assign(value); } } else if (ModelCollection.GetItemType(property.PropertyType, out Type itemType)) { IList collection = (IList)property.GetValue(this); IList clonedCollection = (IList)property.GetValue(clone); if (ModelGrowingCollection.TypeMatches(property.PropertyType)) { ModelGrowingCollectionHelper.Assign(clonedCollection, collection); } else { ModelCollectionHelper.Assign(clonedCollection, itemType, collection); } } else if (property.PropertyType.IsAssignableFrom(typeof(ICloneable))) { ICloneable value = (ICloneable)property.GetValue(this); property.SetValue(clone, value?.Clone()); } else { object value = property.GetValue(this); property.SetValue(clone, value); } } return(clone); }