private Expression NewDiffChanged(ParameterExpression ret, Property property, ParameterExpression @base, ParameterExpression changed) { IDiffAlgorithm diff = this.aMergerImplementation.Partial.Algorithms.GetDiffAlgorithm(property.Type); if (diff.IsDirect) { return(this.NewDiffReplaced(ret, property, @base, changed)); } MemberExpression baseProperty = Expression.Property(@base, property.ReflectionPropertyInfo); MemberExpression changedProperty = Expression.Property(changed, property.ReflectionPropertyInfo); ParameterExpression tmp = Expression.Parameter(typeof(IDiff <>).MakeGenericType(property.Type), "tmp"); return(Expression.Block( new[] { tmp }, Expression.Assign( tmp, Expression.Call( Expression.Constant(diff), DiffAlgorithmMembers.Compute(property.Type), baseProperty, changedProperty ) ), Expression.IfThenElse( Expression.NotEqual( Expression.Property(tmp, DiffMembers.Count()), Expression.Constant(0) ), Expression.Call( ret, ListMembers.Add(typeof(IDiffItem)), Expression.New( DiffItemsMembers.NewClassChanged(property.Type), Expression.Constant(property), tmp ) ), this.NewDiffUnchanged(ret, property, @base) ) )); }
private Expression <Func <IDiff <TType>, IDiff <TType>, IConflictContainer, List <IDiffItem> > > Compile() { ParameterExpression left = Expression.Parameter(typeof(IDiff <TType>), "left"); ParameterExpression right = Expression.Parameter(typeof(IDiff <TType>), "right"); ParameterExpression conflicts = Expression.Parameter(typeof(IConflictContainer), "ret"); ParameterExpression ret = Expression.Parameter(typeof(List <IDiffItem>), "ret"); ParameterExpression leftEnumerator = Expression.Parameter(typeof(IEnumerator <IDiffItem>), "leftEnumerator"); ParameterExpression leftSomeLeft = Expression.Parameter(typeof(bool), "leftSomeLeft"); ParameterExpression rightEnumerator = Expression.Parameter(typeof(IEnumerator <IDiffItem>), "rightEnumerator"); ParameterExpression rightSomeLeft = Expression.Parameter(typeof(bool), "rightSomeLeft"); return(Expression.Lambda <Func <IDiff <TType>, IDiff <TType>, IConflictContainer, List <IDiffItem> > >( Expression.Block( new[] { ret, leftEnumerator, leftSomeLeft, rightEnumerator, rightSomeLeft }, Expression.Assign( ret, Expression.New( ListMembers.NewWithCount(typeof(IDiffItem)), Expression.Add( Expression.Property(left, DiffMembers.Count()), Expression.Property(right, DiffMembers.Count()) ) ) ), Expression.Assign( leftEnumerator, Expression.Call(left, EnumerableMembers.GetEnumerator(typeof(IDiffItem))) ), Expression.Assign( rightEnumerator, Expression.Call(right, EnumerableMembers.GetEnumerator(typeof(IDiffItem))) ), this.MoveEnumerator(leftEnumerator, leftSomeLeft), this.MoveEnumerator(rightEnumerator, rightSomeLeft), Expression.Block(Class <TType> .Properties.Select(x => this.EvaluateProperty(leftEnumerator, leftSomeLeft, rightEnumerator, rightSomeLeft, conflicts, ret, x))), ret ), left, right, conflicts )); }