public CloneDel <T> Create <T>() { var type = typeof(T); if (type.IsArray && type.GetArrayRank() == 1 && type.HasElementType) { var elementType = type.GetElementType(); if (elementType.CanShallowClone()) { var args = CloneArgs.Create(type, true); var assign = Expression.Assign( args.Target, Expression.NewArrayBounds(elementType, Expression.Property(args.Source, "Length"))); var copy = Expression.Call( args.Source, _arrayCopy, args.Target, Expression.Constant(0)); args.CloneExpression = Expression.Block( assign, ExpressionHelper.RecordCopy(args.Context, args.Source, args.Target), copy); return(ExpressionHelper.Get <T>(args).Compile()); } } return(null); }
public CloneDel <T> Create <T>() { var type = typeof(T); if (type.IsGenericType() && type.GetGenericTypeDefinition() == typeof(List <>) && type.GetGenericArguments()[0].CanShallowClone()) { var args = CloneArgs.Create(type, true); ConstructorInfo constructor = args .Type .GetConstructors() .Where(x => x.GetParameters().Length == 1 && x.GetParameters().ElementAt(0).ParameterType.IsGenericType()) .FirstOrDefault(); args.CloneExpression = Expression.Block( Expression.Assign(args.Target, Expression.New(constructor, args.Source)), ExpressionHelper.RecordCopy(args.Context, args.Source, args.Target)); return(ExpressionHelper.Get <T>(args).Compile()); } return(null); }
public CloneDel <T> Create <T>() { var type = typeof(T); if (type.IsGenericType() && (type.GetGenericTypeDefinition() == typeof(Tuple <>) || type.GetGenericTypeDefinition() == typeof(Tuple <,>) || type.GetGenericTypeDefinition() == typeof(Tuple <, ,>) || type.GetGenericTypeDefinition() == typeof(Tuple <, , ,>) || type.GetGenericTypeDefinition() == typeof(Tuple <, , , ,>) || type.GetGenericTypeDefinition() == typeof(Tuple <, , , , ,>) || type.GetGenericTypeDefinition() == typeof(Tuple <, , , , , ,>) || type.GetGenericTypeDefinition() == typeof(Tuple <, , , , , , ,>))) { var args = CloneArgs.Create(type, true); Type[] genericTypes = typeof(T).GetGenericArguments(); var cloneItems = new Expression[genericTypes.Length]; // Can't loop to 8, because instead of Item8 the last one is called Rest var loopCount = Math.Min(genericTypes.Length, 7); for (int i = 0; i < loopCount; i++) { string itemName = "Item" + (i + 1).ToString(CultureInfo.InvariantCulture); var itemType = genericTypes[i]; cloneItems[i] = itemType.CanShallowClone() ? Expression.Property(args.Source, itemName) : (Expression)ExpressionHelper.GetSafeClone(itemType, Expression.Property(args.Source, itemName), args.Context); } // add Rest expression if it's necessary if (genericTypes.Length == 8) { string itemName = "Rest"; var itemType = genericTypes[7]; cloneItems[7] = itemType.CanShallowClone() ? Expression.Property(args.Source, itemName) : (Expression)ExpressionHelper.GetSafeClone(itemType, Expression.Property(args.Source, itemName), args.Context); } ConstructorInfo constructor = args.Type.GetConstructors()[0]; var newExpression = Expression.New(constructor, cloneItems); args.CloneExpression = Expression.Block( Expression.Assign(args.Target, newExpression), ExpressionHelper.RecordCopy(args.Context, args.Source, args.Target)); return(ExpressionHelper.Get <T>(args).Compile()); } return(null); }
public CloneDel <T> Create <T>() { var type = typeof(T); if (type.CanShallowClone()) { var args = CloneArgs.Create(type, false); args.CloneExpression = Expression.Assign(args.Target, args.Source); return(ExpressionHelper.Get <T>(args).Compile()); } return(null); }
public CloneDel <T> Create <T>() { var type = typeof(T); if (type.IsNullable()) { var structType = typeof(T).GetGenericArguments()[0]; if (structType.CanShallowClone()) { var args = CloneArgs.Create(type, false); args.CloneExpression = Expression.Assign(args.Target, args.Source); return(ExpressionHelper.Get <T>(args).Compile()); } } return(null); }
public CloneDel <T> Create <T>() { var type = typeof(T); if (type.IsNullable()) { var structType = typeof(T).GetGenericArguments()[0]; if (!structType.CanShallowClone()) { var args = CloneArgs.Create(type, false); var sourceProperty = Expression.Property(args.Source, "Value"); var cloneCall = ExpressionHelper.GetUnSafeClone(structType, sourceProperty, args.Context); var newNullable = Expression.New(typeof(T).GetConstructor(new[] { structType }), cloneCall); args.CloneExpression = Expression.Assign(args.Target, newNullable); return(ExpressionHelper.Get <T>(args).Compile()); } } return(null); }
public CloneDel <T> Create <T>() { var type = typeof(T); if (type.IsClass() && !type.IsArray && !type.IsAnonymous()) { if (type.HasDefaultConstructor() || CloneConfig <T> .Initializer != null) { var args = CloneArgs.Create(type, true); Expression createExpression = CloneConfig <T> .Initializer != null? Expression.Invoke(Expression.Constant(CloneConfig <T> .Initializer), args.Source) : (Expression)Expression.New(args.Type); List <Expression> expressions = new List <Expression>() { Expression.Assign(args.Target, createExpression), ExpressionHelper.RecordCopy(args.Context, args.Source, args.Target), ExpressionHelper.GetMemberAssignments <T>(args.Source, args.Target, args.Context), ExpressionHelper.GetCollectionAssignment <T>(args.Source, args.Target, args.Context) }; args.CloneExpression = Expression.Block(expressions.Where(x => x != null)); return(ExpressionHelper.Get <T>(args).Compile()); } else { return((source, context) => { throw new ArgumentException($"({type}) has no default constructor or registered initializer."); }); } } return(null); }
public CloneDel <T> Create <T>() { var type = typeof(T); if (type.IsGenericType() && type.GetGenericTypeDefinition() == typeof(KeyValuePair <,>)) { var args = CloneArgs.Create(type, false); var keyType = args.Type.GetGenericArguments()[0]; var valueType = args.Type.GetGenericArguments()[1]; ConstructorInfo _constructor = args .Type .GetConstructors() .Where(x => x.GetParameters().Length == 2) .FirstOrDefault(); Expression cloneKey = keyType.CanShallowClone() ? Expression.Property(args.Source, "Key") : (Expression)ExpressionHelper.GetSafeClone(keyType, Expression.Property(args.Source, "Key"), args.Context); Expression cloneValue = valueType.CanShallowClone() ? Expression.Property(args.Source, "Value") : (Expression)ExpressionHelper.GetSafeClone(valueType, Expression.Property(args.Source, "Value"), args.Context); var newExpression = Expression.New( _constructor, cloneKey, cloneValue); args.CloneExpression = Expression.Assign(args.Target, newExpression); return(ExpressionHelper.Get <T>(args).Compile()); } return(null); }