Example #1
0
            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
                               ));
                }
            }