Exemple #1
0
        public static Expression NullCheckSource(ProfileMap profileMap, Expression sourceParameter, Expression destinationParameter, Expression mapExpression, MemberMap memberMap)
        {
            var sourceType = sourceParameter.Type;

            if (sourceType.IsValueType && !sourceType.IsNullableType())
            {
                return(mapExpression);
            }
            var destinationType    = destinationParameter.Type;
            var isCollection       = destinationType.IsCollection();
            var mustUseDestination = memberMap is { MustUseDestination : true };
            var ifSourceNull       = memberMap == null?
                                     destinationParameter.IfNullElse(DefaultDestination(), ClearDestinationCollection()) :
                                         mustUseDestination?ClearDestinationCollection() : DefaultDestination();

            return(sourceParameter.IfNullElse(ifSourceNull, mapExpression));

            Expression ClearDestinationCollection()
            {
                if (!isCollection)
                {
                    return(destinationParameter);
                }
                MethodInfo clearMethod;
                var        destinationVariable = Variable(destinationParameter.Type, "collectionDestination");
                Expression collection          = destinationVariable;

                if (destinationType.IsListType())
                {
                    clearMethod = IListClear;
                }
                else
                {
                    var destinationCollectionType = destinationType.GetICollectionType();
                    if (destinationCollectionType == null)
                    {
                        if (!mustUseDestination)
                        {
                            return(destinationParameter);
                        }
                        var destinationElementType = GetEnumerableElementType(destinationType);
                        destinationCollectionType = typeof(ICollection <>).MakeGenericType(destinationElementType);
                        collection = Convert(collection, destinationCollectionType);
                    }
                    clearMethod = destinationCollectionType.GetMethod("Clear");
                }
                return(Block(new[] { destinationVariable },
                             Assign(destinationVariable, destinationParameter),
                             Condition(ReferenceEqual(destinationVariable, Null), Empty, Expression.Call(collection, clearMethod)),
                             destinationVariable));
            }

            Expression DefaultDestination()
            {
                if ((isCollection && profileMap.AllowsNullCollectionsFor(memberMap)) || (!isCollection && profileMap.AllowsNullDestinationValuesFor(memberMap)))
                {
                    return(destinationParameter.NodeType == ExpressionType.Default ? destinationParameter : Default(destinationType));
                }
                if (destinationType.IsArray)
                {
                    var destinationElementType = destinationType.GetElementType();
                    var rank = destinationType.GetArrayRank();
                    return(rank == 1 ?
                           Expression.Call(ArrayEmptyMethod.MakeGenericMethod(destinationElementType)) :
                           NewArrayBounds(destinationElementType, Enumerable.Repeat(Zero, rank)));
                }
                return(ObjectFactory.GenerateConstructorExpression(destinationType));
            }
        }