/// <summary> /// Get field by Name /// </summary> /// <param name="type"></param> /// <param name="name"></param> /// <returns></returns> public static IFastDeepClonerProperty GetField(this Type type, string name) { return(FastDeepClonerCachedItems.GetFastDeepClonerFields(type).ContainsKey(name) ? FastDeepClonerCachedItems.GetFastDeepClonerFields(type)[name] : null); }
internal object Clone(object objectToBeCloned) { if (objectToBeCloned == null) { return(null); } var primaryType = objectToBeCloned.GetType(); if (primaryType.IsArray && primaryType.GetArrayRank() > 1) { return(((Array)objectToBeCloned).Clone()); } if (objectToBeCloned.IsInternalObject()) { return(objectToBeCloned); } object resObject; if (primaryType.IsArray || (objectToBeCloned as IList) != null) { resObject = primaryType.IsArray ? Array.CreateInstance(primaryType.GetIListType(), (objectToBeCloned as Array).Length) : Activator.CreateInstance(primaryType.GetIListType()); var i = 0; var ilist = resObject as IList; var array = resObject as Array; foreach (var item in (objectToBeCloned as IList)) { object clonedIteam = null; if (item != null) { clonedIteam = item.GetType().IsInternalType() ? item : Clone(item); } if (!primaryType.IsArray) { ilist?.Add(clonedIteam); } else { array?.SetValue(clonedIteam, i); } i++; } foreach (var prop in FastDeepClonerCachedItems.GetFastDeepClonerProperties(primaryType).Where(x => !FastDeepClonerCachedItems.GetFastDeepClonerProperties(typeof(List <string>)).Any(a => a.Key == x.Key))) { var property = prop.Value; if (!property.CanRead || property.FastDeepClonerIgnore) { continue; } var value = property.GetValue(objectToBeCloned); if (value == null) { continue; } var clonedIteam = value.GetType().IsInternalType() ? value : Clone(value); property.SetValue(resObject, clonedIteam); } } else if (objectToBeCloned is IDictionary) { resObject = Activator.CreateInstance(primaryType); var resDic = resObject as IDictionary; var dictionary = (IDictionary)objectToBeCloned; foreach (var key in dictionary.Keys) { var item = dictionary[key]; object clonedIteam = null; if (item != null) { clonedIteam = item.GetType().IsInternalType() ? item : Clone(item); } resDic?.Add(key, clonedIteam); } } else if (primaryType.IsAnonymousType()) // dynamic types { var props = FastDeepClonerCachedItems.GetFastDeepClonerProperties(primaryType); resObject = new ExpandoObject(); var d = resObject as IDictionary <string, object>; foreach (var prop in props.Values) { var item = prop.GetValue(objectToBeCloned); var value = item == null || prop.IsInternalType || (item?.IsInternalObject() ?? true) ? item : Clone(item); if (!d.ContainsKey(prop.Name)) { d.Add(prop.Name, value); } } } else { resObject = ReferenceTypeClone((_settings.FieldType == FieldType.FieldInfo ? FastDeepClonerCachedItems.GetFastDeepClonerFields(primaryType) : FastDeepClonerCachedItems.GetFastDeepClonerProperties(primaryType)), primaryType, objectToBeCloned); if (_settings.FieldType == FieldType.Both) { resObject = ReferenceTypeClone(FastDeepClonerCachedItems.GetFastDeepClonerFields(primaryType).Values.ToList().Where(x => !FastDeepClonerCachedItems.GetFastDeepClonerProperties(primaryType).ContainsKey(x.Name)).ToDictionary(x => x.Name, x => x), primaryType, objectToBeCloned, resObject); } } return(resObject); }
/// <summary> /// will return fieldInfo from the cached fieldinfo. Get and set value is much faster. /// </summary> /// <param name="type"></param> /// <returns></returns> public static List <IFastDeepClonerProperty> GetFastDeepClonerFields(this Type type) { return(FastDeepClonerCachedItems.GetFastDeepClonerFields(type).Values.ToList()); }