private static MemberInitExpression createMemberInit(ParameterExpression parameterExpression, Type destination, Type source = null, Type filter = null, ObjectChangesRegister changesRegister = null) { var internalBindings = BuildBindings(destination, source, filter); IEnumerable <MemberAssignment> bindings; if (changesRegister != null) { changesRegister.MoveToComplex(); var lbindings = new List <MemberAssignment>(); if (internalBindings != null) { foreach (var binding in internalBindings) { var bind = BuildBinding(parameterExpression, binding, null, true); lbindings.Add(bind); changesRegister .AddChange(new ObjectChangesRegister(binding.Destination as PropertyInfo, false, null, bind.Expression)); } } bindings = lbindings; } else { bindings = internalBindings .Select(m => BuildBinding(parameterExpression, m, null, changesRegister != null)); } return(Expression.MemberInit(Expression.New(destination), bindings)); }
private static Expression processTreeRec( Expression node, ParameterExpression parameterExpression, Type filter = null, string prefix = null, Stack <PropertyInfo> sourceProperties = null, PropertyInfo currProperty = null, ObjectChangesRegister changesRegister = null) { if (node.NodeType == ExpressionType.MemberInit) { if (changesRegister != null) { changesRegister.MoveToComplex(); } var currType = sourceProperties != null && sourceProperties.Count > 0 ? sourceProperties.Peek().PropertyType : parameterExpression.Type; string newPrefix = prefix == null ? currProperty?.Name : prefix + currProperty?.Name;; var sourceProperty = newPrefix == null ? null : currType.GetProperty(newPrefix); if (currProperty != null && currProperty.PropertyType.GetTypeInfo().IsInterface) { filter = currProperty.PropertyType; } else { filter = null; } if (sourceProperty != null) { if (sourceProperties == null) { sourceProperties = new Stack <PropertyInfo>(); } sourceProperties.Push(sourceProperty); var res = completeMemberInit(node as MemberInitExpression, parameterExpression, filter, null, sourceProperties, changesRegister); sourceProperties.Pop(); if (sourceProperties.Count == 0) { sourceProperties = null; } return(res); } else { return(completeMemberInit(node as MemberInitExpression, parameterExpression, filter, newPrefix, sourceProperties, changesRegister)); } } else if (node.NodeType == ExpressionType.Conditional) { var cond = node as ConditionalExpression; var ifTrue = processTreeRec(cond.IfTrue, parameterExpression, filter, prefix, sourceProperties, currProperty, changesRegister); var ifFalse = processTreeRec(cond.IfFalse, parameterExpression, filter, prefix, sourceProperties, currProperty, changesRegister); if (ifTrue == cond.IfTrue && ifFalse == cond.IfFalse) { return(node); } return(Expression.Condition(cond.Test, ifTrue, ifFalse)); } else if (node.NodeType == ExpressionType.Convert) { var conv = node as UnaryExpression; var toConvert = processTreeRec(conv.Operand, parameterExpression, filter, prefix, sourceProperties, currProperty, changesRegister); if (toConvert == conv.Operand) { return(node); } return(Expression.Convert(toConvert, conv.Type, conv.Method)); } else if (node.NodeType == ExpressionType.ConvertChecked) { var conv = node as UnaryExpression; var toConvert = processTreeRec(conv.Operand, parameterExpression, filter, prefix, sourceProperties, currProperty, changesRegister); if (toConvert == conv.Operand) { return(node); } return(Expression.ConvertChecked(toConvert, conv.Type, conv.Method)); } else if (node.NodeType == ExpressionType.New) { if (changesRegister != null) { changesRegister.MoveToComplex(); } return(node); } else { return(node); } }