private Expression <Func <TType, TType, List <IDiffItem> > > Compile() { List <Expression> body = new List <Expression>(); ParameterExpression ret = Expression.Parameter(typeof(List <IDiffItem>), "ret"); ParameterExpression @base = Expression.Parameter(typeof(TType), "base"); ParameterExpression changed = Expression.Parameter(typeof(TType), "changed"); body.Add( Expression.Assign( ret, Expression.New( ListMembers.NewWithCount(typeof(IDiffItem)), Expression.Constant(Class <TType> .Properties.Count) // maximum number of different items ) ) ); foreach (Property property in Class <TType> .Properties) { if (this.aIgnoreProperties.Contains(property)) { continue; } IDiffAlgorithm diff = this.aMergerImplementation.Partial.Algorithms.GetDiffAlgorithm(property.Type); if (diff.IsDirect) { body.Add(this.MightBeReplaced(ret, property, @base, changed)); } else { body.Add(this.MightBeChanged(ret, property, @base, changed)); } } body.Add(ret); return(Expression.Lambda <Func <TType, TType, List <IDiffItem> > >( Expression.Block(new[] { ret }, body), @base, changed )); }
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 )); }
private Func <TType, TType, List <IDiffItem> > CompileDiff() { ParameterExpression ret = Expression.Parameter(typeof(List <IDiffItem>), "ret"); ParameterExpression @base = Expression.Parameter(typeof(TType), "base"); ParameterExpression changed = Expression.Parameter(typeof(TType), "changed"); Expression differ; if (this.aIDProperty == null) { differ = Expression.IfThen( ExpressionExtensions.NotEqual(@base, changed), Expression.Call( ret, ListMembers.Add(typeof(IDiffItem)), Expression.New( DiffItemsMembers.NewValueReplaced(typeof(TType)), @base, changed ) ) ); } else { differ = Expression.IfThen( ExpressionExtensions.NotEqual( Expression.Property(@base, this.aIDProperty.ReflectionPropertyInfo), Expression.Property(changed, this.aIDProperty.ReflectionPropertyInfo) ), Expression.Call( ret, ListMembers.Add(typeof(IDiffItem)), Expression.New( DiffItemsMembers.NewValueReplaced(typeof(TType)), @base, changed ) ) ); } if (!typeof(TType).IsValueType) { differ = Expression.IfThenElse( Expression.OrElse( Expression.ReferenceEqual(@base, Expression.Constant(null)), Expression.ReferenceEqual(changed, Expression.Constant(null)) ), Expression.IfThen( Expression.ReferenceEqual(@base, changed), Expression.New( DiffItemsMembers.NewValueReplaced(typeof(TType)), @base, changed ) ), differ ); } Expression <Func <TType, TType, List <IDiffItem> > > comparer = Expression.Lambda <Func <TType, TType, List <IDiffItem> > >( Expression.Block( new[] { ret }, Expression.Assign( ret, Expression.New( ListMembers.NewWithCount(typeof(IDiffItem)), Expression.Constant(1) // maximum number of changes ) ), differ, ret ), @base, changed ); return(comparer.Compile()); }