コード例 #1
0
 /// <summary>
 /// Checks whether type is primitive or decimal or if nullable types allowed also checks for nullable primitives and nullable decimal.
 /// </summary>
 /// <param name="type">The type to check.</param>
 /// <returns>A boolean determining convert capability,</returns>
 public virtual bool CanConvert(Type type)
 {
     return(type.IsPrimitiveOrDecimal() || type == typeof(string) ||
            (AllowNullableTypes && type.IsNullable(out var nullableBaseType)
                ? nullableBaseType.IsPrimitiveOrDecimal()
                : throw TypeConvertHelper.ConvertException(type)));
 }
コード例 #2
0
        /// <summary>
        /// Create an expression to call <c>Array.Copy</c> to copy arrays.
        /// </summary>
        /// <param name="arraySource">The source array.</param>
        /// <param name="arrayDestination">The destination array.</param>
        /// <param name="length">A nullable length expression, if null passes </param>
        /// <returns></returns>
        /// <exception cref="TypeConvertException"></exception>
        /// <exception cref="NotImplementedException"></exception>
        public static Expression CreateCopyArrayExpression(Expression arraySource, Expression arrayDestination,
                                                           Expression length)
        {
            if (!arraySource.Type.IsArray || !arrayDestination.Type.IsArray)
            {
                throw TypeConvertHelper.ConvertException(arraySource.Type, arrayDestination.Type);
            }

            var sourceElementType = arraySource.Type.GetElementType().GetTypeOrNullableBaseType();

            //TODO: add IConvertible support
            //TSource must be array and same as TDestination
            //Source's rank must be 1
            //TSource must be primitive or decimal or object
            if (arraySource.Type.GetElementType() == arrayDestination.Type.GetElementType() &&
                arraySource.Type.GetArrayRank() == 1 &&
                (
                    sourceElementType.IsPrimitive ||
                    sourceElementType == typeof(object) ||
                    sourceElementType == typeof(decimal)
                )
                )
            {
                //Array.Copy(source, destination, Math.Floor(source.Length, destination.Length))

                if (length == null)
                {
                    //Math.Min(source.Length, destination.Length)
                    length = Expression.Call(
                        typeof(System.Math).GetMethod(nameof(System.Math.Min),
                                                      new[] { typeof(int), typeof(int) }), //int Math.Min(int)
                        Expression.ArrayLength(arraySource),                               //source.Length
                        Expression.ArrayLength(arrayDestination)                           //destination.Length
                        );
                }

                var block = Expression.Call(
                    typeof(Array).GetMethod(nameof(Array.Copy),
                                            new[] { typeof(Array), typeof(Array), typeof(int) }), //Array.Copy(Array, Array, int)
                    arraySource,
                    arrayDestination,
                    length
                    );

                return(block);
            }
            else
            {
                throw new NotImplementedException();
            }
        }
コード例 #3
0
        public static Expression ConvertInlineExpressionAllowNullable(Expression source, Type destinationType)
        {
            var convert    = source;
            var sourceType = source.Type;

            if (sourceType != destinationType)
            {
                if (sourceType.IsNullable(out var nullableBaseType))
                {
                    convert = Expression.Convert(convert, nullableBaseType);

                    //src == null ? default(TDestination) : {convert}(src)
                    var compareNull = Expression.Equal(convert, Expression.Constant(null, sourceType));
                    convert = Expression.Condition(compareNull, Expression.Default(destinationType), convert);
                }
                else if (sourceType.IsPrimitiveOrDecimal())
                {
                    convert = Expression.Convert(convert, destinationType);
                }
                else if (sourceType.IsConvertible())
                {
                    MethodInfo convertMethodInfo;
                    if (TypeConvertHelper.ConvertMethodNameMapping.TryGetValue(destinationType, out var methodName) &&
                        (convertMethodInfo = typeof(System.Convert).GetMethod(methodName, new[] { sourceType })) != null
                        )
                    {
                        //Convert.To{DestinationType}(source)
                        convert = Expression.Call(convertMethodInfo, convert);
                    }
                    else
                    {
                        convertMethodInfo = typeof(System.Convert).GetMethod(nameof(System.Convert.ChangeType),
                                                                             new[] { typeof(object), typeof(Type) });

                        convert = Expression.Call(convertMethodInfo,
                                                  Expression.Convert(source, typeof(object)),
                                                  Expression.Constant(destinationType));

                        convert = Expression.Convert(convert, destinationType);
                    }
                }
                else
                {
                    throw TypeConvertHelper.ConvertException(sourceType, destinationType);
                }
            }

            return(convert);
        }
コード例 #4
0
        public static Expression CreateToArrayExpression(Expression enumerableSource, Type destinationType)
        {
            if (!typeof(IEnumerable).IsAssignableFrom(enumerableSource.Type))
            {
                throw TypeConvertHelper.ConvertException(enumerableSource.Type, destinationType);
            }

            if (destinationType == null)
            {
                destinationType = enumerableSource.Type.GetEnumerableBaseType();
            }

            //source.ToArray()
            var toArray = Expression.Call(
                typeof(Enumerable).GetMethod(nameof(Enumerable.ToArray)),
                enumerableSource
                );

            return(toArray);
        }