public Expression MapExpression( IGlobalConfiguration configurationProvider, ProfileMap profileMap, MemberMap memberMap, Expression sourceExpression, Expression destExpression ) { var sourceArguments = sourceExpression.Type.GenericTypeArguments; var destinationType = destExpression.Type; var destinationArguments = destinationType.GenericTypeArguments; var keys = new TypePair(sourceArguments[0], destinationArguments[0]); var values = new TypePair(sourceArguments[1], destinationArguments[1]); var mapKeys = configurationProvider.MapExpression( profileMap, keys, ExpressionBuilder.Property(sourceExpression, "Key") ); var mapValues = configurationProvider.MapExpression( profileMap, values, ExpressionBuilder.Property(sourceExpression, "Value") ); return(Expression.New( destinationType.GetConstructor(destinationArguments), mapKeys, mapValues )); }
public static Expression MapToArray( IGlobalConfiguration configurationProvider, ProfileMap profileMap, Expression sourceExpression, Type destinationType ) { var destinationElementType = destinationType.GetElementType(); if (destinationType.GetArrayRank() > 1) { return(Call( MapMultidimensionalMethod, sourceExpression, Constant(destinationElementType), ContextParameter )); } var sourceType = sourceExpression.Type; Type sourceElementType = typeof(object); Expression createDestination; var destination = Parameter(destinationType, "destinationArray"); if (sourceType.IsArray) { var mapFromArray = MapFromArray(); if (mapFromArray != null) { return(mapFromArray); } } else { var mapFromIEnumerable = MapFromIEnumerable(); if (mapFromIEnumerable != null) { return(mapFromIEnumerable); } var count = Call( CountMethod.MakeGenericMethod(sourceElementType), sourceExpression ); createDestination = Assign( destination, NewArrayBounds(destinationElementType, count) ); } var itemParam = Parameter(sourceElementType, "sourceItem"); var itemExpr = configurationProvider.MapExpression( profileMap, new TypePair(sourceElementType, destinationElementType), itemParam ); var indexParam = Parameter(typeof(int), "destinationArrayIndex"); var setItem = Assign( ArrayAccess(destination, PostIncrementAssign(indexParam)), itemExpr ); return(Block( new[] { destination, indexParam }, createDestination, Assign(indexParam, Zero), ForEach(itemParam, sourceExpression, setItem), destination )); Expression MapFromArray() { sourceElementType = sourceType.GetElementType(); createDestination = Assign( destination, NewArrayBounds(destinationElementType, ArrayLength(sourceExpression)) ); if ( !destinationElementType.IsAssignableFrom(sourceElementType) || configurationProvider.FindTypeMapFor( sourceElementType, destinationElementType ) != null ) { return(null); } return(Block( new[] { destination }, createDestination, Call(sourceExpression, CopyToMethod, destination, Zero), destination )); } Expression MapFromIEnumerable() { var iEnumerableType = sourceType.GetIEnumerableType(); if ( iEnumerableType == null || (sourceElementType = iEnumerableType.GenericTypeArguments[0]) != destinationElementType || configurationProvider.FindTypeMapFor( sourceElementType, destinationElementType ) != null ) { return(null); } return(Call( ToArrayMethod.MakeGenericMethod(sourceElementType), sourceExpression )); } }
public Expression MapExpression(IGlobalConfiguration configurationProvider, ProfileMap profileMap, MemberMap memberMap, Expression sourceExpression, Expression destExpression) => configurationProvider.MapExpression(profileMap, GetAssociatedTypes(sourceExpression.Type, destExpression.Type), sourceExpression, memberMap);