/// <summary> /// 浅表复制,将源对象中与目标对象同名的公共非静态字段或属性的值复制到目标对象。 /// 如果字段是值类型的,则对该字段执行逐位复制。 如果字段是引用类型,则复制引用但不复制引用的对象;因此,源对象及当前对象引用同一对象。 /// </summary> public static T MemberwiseClone <T>(this T source) where T : class { if (source != null) { Type sourceType = source.GetType(); ObjectExtensiones.MemberwiseCloneDelegate cloneDelegate = null; lock (ObjectExtensiones.memberwiseCloneDelegates) { if (ObjectExtensiones.memberwiseCloneDelegates.ContainsKey(sourceType)) { cloneDelegate = ObjectExtensiones.memberwiseCloneDelegates[sourceType]; } else { cloneDelegate = ObjectExtensiones.CreateMemberwiseCloneDelegate(sourceType); ObjectExtensiones.memberwiseCloneDelegates[sourceType] = cloneDelegate; } } if (cloneDelegate != null) { return((T)((object)cloneDelegate(source))); } } return(default(T)); }
private static ObjectExtensiones.MemberwiseCopyDelegate GetCopyDelegate(Type sourceType, Type targetType, bool ignoreCase) { ObjectExtensiones.MemberwiseCopyDelegate copyDelegate = null; Dictionary <Type, Dictionary <Type, ObjectExtensiones.MemberwiseCopyDelegate> > memberwiseCopyDelegates = ignoreCase ? ObjectExtensiones.memberwiseCopyDelegates_true : ObjectExtensiones.memberwiseCopyDelegates_false; lock (memberwiseCopyDelegates) { if (memberwiseCopyDelegates.ContainsKey(sourceType)) { Dictionary <Type, ObjectExtensiones.MemberwiseCopyDelegate> dict = memberwiseCopyDelegates[sourceType]; if (dict.ContainsKey(targetType)) { copyDelegate = dict[targetType]; } else { copyDelegate = ObjectExtensiones.CreateMemberwiseCopyDelegate(sourceType, targetType, ignoreCase); dict[targetType] = copyDelegate; } } else { Dictionary <Type, ObjectExtensiones.MemberwiseCopyDelegate> dict = new Dictionary <Type, ObjectExtensiones.MemberwiseCopyDelegate>(); memberwiseCopyDelegates.Add(sourceType, dict); copyDelegate = ObjectExtensiones.CreateMemberwiseCopyDelegate(sourceType, targetType, ignoreCase); dict[targetType] = copyDelegate; } } return(copyDelegate); }
/// <summary> /// 调用 Convert.ToXXX(object) 方法将指定对象转换为具有等效值的公共语言运行时类型, 如:Boolean、 SByte、 Byte、 Int16、 UInt16、 Int32、 UInt32、 Int64、 UInt64、 Single、 Double、 Decimal、 DateTime、 Char 和 String等, /// 如果对象为 null 或转换过程中发生异常,则返回 defaultValue 参数指定的默认值。 /// </summary> /// <typeparam name="T">目标类型。</typeparam> /// <param name="value">指定的对象。</param> /// <param name="defaultValue">默认值,如果不指定,则为目标类型的默认值。</param> /// <returns>对象转换后的值。</returns> public static T ConvertTo <T>(this object value, T defaultValue) where T : IConvertible { if (value == null) { return(defaultValue); } object retValue = ObjectExtensiones.ConvertInternal(typeof(T), value); if (retValue == null) { return(defaultValue); } return((T)((object)retValue)); }
/// <summary> /// 浅表复制,将源对象中与目标对象同名的公共非静态字段或属性的值复制到目标对象。 /// 如果字段是值类型的,则对该字段执行逐位复制。 如果字段是引用类型,则复制引用但不复制引用的对象;因此,源对象及当前对象引用同一对象。 /// </summary> public static void MemberwiseCopy(this object source, object target, bool ignoreCase = false) { if (source == null) { throw new ArgumentNullException("source"); } if (target == null) { throw new ArgumentNullException("target"); } ObjectExtensiones.MemberwiseCopyDelegate copyDelegate = ObjectExtensiones.GetCopyDelegate(source.GetType(), target.GetType(), ignoreCase); if (copyDelegate != null) { copyDelegate(source, target); } }
/// <summary> /// 浅表复制,将源对象中与目标对象同名的公共非静态字段或属性的值复制到目标对象。 /// 如果字段是值类型的,则对该字段执行逐位复制。 如果字段是引用类型,则复制引用但不复制引用的对象;因此,源对象及当前对象引用同一对象。 /// 此方法要求 source 类型必须为 TSource 或从其继承,但仅复制源对象中由 TSource 限定的部分字段或属性。 /// </summary> public static void MemberwiseCopy <TSource>(this object source, object target, bool ignoreCase = false) { if (source == null) { throw new ArgumentNullException("source"); } if (target == null) { throw new ArgumentNullException("target"); } if (!typeof(TSource).IsAssignableFrom(source.GetType())) { throw new ArgumentException("源对象的类型不是类型参数指定的类型或其子类。"); } ObjectExtensiones.MemberwiseCopyDelegate copyDelegate = ObjectExtensiones.GetCopyDelegate(typeof(TSource), target.GetType(), ignoreCase); if (copyDelegate != null) { copyDelegate(source, target); } }
/// <summary> /// 动态创建一个委托并返回 /// </summary> /// <param name="sourceType"></param> /// <param name="targetType"></param> /// <returns></returns> private static ObjectExtensiones.MemberwiseCopyDelegate CreateMemberwiseCopyDelegate(Type sourceType, Type targetType, bool ignoreCase) { DynamicMethod dynCopyMethod = new DynamicMethod(ObjectExtensiones.CreateMemberwiseCopyMethodName(targetType, ignoreCase), null, new Type[] { TypeHelper.Object, TypeHelper.Object }, sourceType); MemberInfo[] sourceMembers = sourceType.GetMembers(BindingFlags.Instance | BindingFlags.Public); MemberInfo[] targetMembers = targetType.GetMembers(BindingFlags.Instance | BindingFlags.Public); ILGenerator il = dynCopyMethod.GetILGenerator(); for (int i = 0; i < sourceMembers.Length; i++) { MemberTypes memberType = sourceMembers[i].MemberType; if (memberType != MemberTypes.Field) { if (memberType == MemberTypes.Property) { int j = 0; while (j < targetMembers.Length) { if (ObjectExtensiones.CheckMemberName(sourceMembers[i], targetMembers[j], ignoreCase)) { MemberTypes memberType2 = targetMembers[j].MemberType; if (memberType2 != MemberTypes.Field) { if (memberType2 == MemberTypes.Property && ((PropertyInfo)targetMembers[j]).CanWrite) { ObjectExtensiones.EnsureMemberType(sourceMembers[i], targetMembers[j], ((PropertyInfo)sourceMembers[i]).PropertyType, ((PropertyInfo)targetMembers[j]).PropertyType); il.Emit(OpCodes.Ldarg_1); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Callvirt, ((PropertyInfo)sourceMembers[i]).GetGetMethod()); il.Emit(OpCodes.Callvirt, ((PropertyInfo)targetMembers[j]).GetSetMethod()); break; } break; } else { if (!((FieldInfo)targetMembers[j]).IsInitOnly) { ObjectExtensiones.EnsureMemberType(sourceMembers[i], targetMembers[j], ((PropertyInfo)sourceMembers[i]).PropertyType, ((FieldInfo)targetMembers[j]).FieldType); il.Emit(OpCodes.Ldarg_1); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Callvirt, ((PropertyInfo)sourceMembers[i]).GetGetMethod()); il.Emit(OpCodes.Stfld, (FieldInfo)targetMembers[j]); break; } break; } } else { j++; } } } } else { int k = 0; while (k < targetMembers.Length) { if (ObjectExtensiones.CheckMemberName(sourceMembers[i], targetMembers[k], ignoreCase)) { MemberTypes memberType3 = targetMembers[k].MemberType; if (memberType3 != MemberTypes.Field) { if (memberType3 == MemberTypes.Property && ((PropertyInfo)targetMembers[k]).CanWrite) { ObjectExtensiones.EnsureMemberType(sourceMembers[i], targetMembers[k], ((FieldInfo)sourceMembers[i]).FieldType, ((PropertyInfo)targetMembers[k]).PropertyType); il.Emit(OpCodes.Ldarg_1); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldfld, (FieldInfo)sourceMembers[i]); il.Emit(OpCodes.Callvirt, ((PropertyInfo)targetMembers[k]).GetSetMethod()); break; } break; } else { if (!((FieldInfo)targetMembers[k]).IsInitOnly) { ObjectExtensiones.EnsureMemberType(sourceMembers[i], targetMembers[k], ((FieldInfo)sourceMembers[i]).FieldType, ((FieldInfo)targetMembers[k]).FieldType); il.Emit(OpCodes.Ldarg_1); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldfld, (FieldInfo)sourceMembers[i]); il.Emit(OpCodes.Stfld, (FieldInfo)targetMembers[k]); break; } break; } } else { k++; } } } } il.Emit(OpCodes.Ret); return((ObjectExtensiones.MemberwiseCopyDelegate)dynCopyMethod.CreateDelegate(typeof(ObjectExtensiones.MemberwiseCopyDelegate))); }