private static Func <EnumerableLoopBodyCargo, Expression> CloneKeyValuePair(ParameterExpression clone, ParameterExpression refTrackerParam) { Func <EnumerableLoopBodyCargo, Expression> loopBody = cargo => { var keyExpression = Expression.Property(Expression.Property(cargo.Enumerator, cargo.EnumeratorType.GetTypeInfo().GetDeclaredProperty("Current")), cargo.KvpType.GetTypeInfo().GetDeclaredProperty("Key")); var valueExpression = Expression.Property(Expression.Property(cargo.Enumerator, cargo.EnumeratorType.GetTypeInfo().GetDeclaredProperty("Current")), cargo.KvpType.GetTypeInfo().GetDeclaredProperty("Value")); var addExpr = Expression.Call(clone, DictionaryMih.Add <string, object>(), keyExpression, ClassCloner.CallCopyExpression(valueExpression, refTrackerParam, Expression.Call(valueExpression, ObjectMih.GetTypeMethod()))); var addNullExpr = Expression.Call(clone, DictionaryMih.Add <string, object>(), keyExpression, Expression.Constant(null)); return(Expression.IfThenElse(Expression.NotEqual(valueExpression, Expression.Constant(null)), addExpr, addNullExpr)); }; return(loopBody); }
private static Expression CloneDictionaryWithCustomComparer(Type genericDictionaryType, ConstructorInfo comparerConstructor, List <ParameterExpression> variables, ParameterExpression source, ParameterExpression clone, Type sourceType, ParameterExpression refTrackerParam) { if (comparerConstructor == null) { throw new MissingConstructorException("Type " + sourceType + " must have a public constructor that takes an IEqualityComparer<> parameter."); } var expressions = new List <Expression>(); var sourceComparer = Expression.Property(source, nameof(Dictionary <int, int> .Comparer)); var comparerType = typeof(IEqualityComparer <>).MakeGenericType(genericDictionaryType.GetGenericArguments()[0]); var clonedComparer = ClassCloner.CallCopyExpression(sourceComparer, refTrackerParam, Expression.Constant(comparerType)); expressions.Add(Expression.Assign(clone, Expression.New(comparerConstructor, Expression.Convert(clonedComparer, comparerType)))); expressions.Add(Expression.Call(refTrackerParam, ObjectClonerReferenceTrackerMih.Track(), source, clone)); CopyFieldsAndValues(genericDictionaryType, source, clone, sourceType, refTrackerParam, expressions, variables); return(ObjectCloner.GenerateNullTrackedOrUntrackedExpression(source, clone, sourceType, refTrackerParam, Expression.Block(expressions))); }