示例#1
0
        private static Expression GetValueTest(Expression sourceValue, ConstantExpression testValue)
        {
            if (sourceValue.Type != testValue.Type)
            {
                sourceValue = ToStringConverter.GetConversion(sourceValue);
            }

            var test = testValue.Value.ToString().Length == 1
                ? Expression.Equal(sourceValue, testValue)
                : sourceValue.GetCaseInsensitiveEquals(testValue);

            return(test);
        }
示例#2
0
        private static Expression GetFromNumericConversion(Expression sourceValue, Type targetType)
        {
            var isWholeNumberNumeric = sourceValue.Type.GetNonNullableType().IsWholeNumberNumeric();
            var sourceValueIsValid   = GetIsValidNumericValueCheck(sourceValue, isWholeNumberNumeric);

            var fallbackValue = targetType.ToDefaultExpression();
            var stringValue   = ToStringConverter.GetConversion(sourceValue);

            if (!isWholeNumberNumeric)
            {
                stringValue = stringValue.GetFirstOrDefaultCall();
            }

            var convertedStringValue = GetFromStringConversion(stringValue, targetType);

            return(Expression.Condition(sourceValueIsValid, fallbackValue, convertedStringValue));
        }
示例#3
0
        private static Expression GetStringValueConversion(
            Expression sourceValue,
            Expression fallbackValue,
            Type nonNullableTargetEnumType)
        {
            if (sourceValue.Type != typeof(string))
            {
                sourceValue = ToStringConverter.GetConversion(sourceValue);
            }

            var underlyingEnumType = Enum.GetUnderlyingType(nonNullableTargetEnumType);

            var isNumericTest = GetIsNumericTest(sourceValue);

            var numericConversion = GetNumericStringToEnumConversion(
                sourceValue,
                fallbackValue,
                nonNullableTargetEnumType,
                underlyingEnumType);

            var nameMatchingConversion = GetStringToEnumConversion(
                sourceValue,
                fallbackValue,
                nonNullableTargetEnumType);

            var numericOrNameConversion = Expression.Condition(
                isNumericTest,
                numericConversion,
                nameMatchingConversion);

            var valueIsNullOrEmpty = Expression.Call(
#if NET35
                typeof(StringExtensions)
#else
                typeof(string)
#endif
                .GetPublicStaticMethod("IsNullOrWhiteSpace"),
                sourceValue);

            var convertedValueOrDefault = Expression.Condition(
                valueIsNullOrEmpty,
                fallbackValue,
                numericOrNameConversion);

            return(convertedValueOrDefault);
        }
示例#4
0
        protected static Expression GetConversion(
            Expression sourceValue,
            Type targetType,
            MethodInfo tryParseMethod,
            ParameterExpression valueVariable)
        {
            if (sourceValue.Type != typeof(string))
            {
                sourceValue = ToStringConverter.GetConversion(sourceValue);
            }

            var tryParseCall = Expression.Call(tryParseMethod, sourceValue, valueVariable);
            var successfulParseReturnValue = valueVariable.GetConversionTo(targetType);
            var defaultValue         = targetType.ToDefaultExpression();
            var parsedValueOrDefault = Expression.Condition(tryParseCall, successfulParseReturnValue, defaultValue);
            var tryParseBlock        = Expression.Block(new[] { valueVariable }, parsedValueOrDefault);

            return(tryParseBlock);
        }
        public override Expression GetConversion(Expression sourceValue, Type targetType)
        {
            if (sourceValue.Type == _nullableTargetType)
            {
                return(sourceValue.GetValueOrDefaultCall());
            }

            if (sourceValue.Type != typeof(string))
            {
                sourceValue = _toStringConverter.GetConversion(sourceValue);
            }

            var tryParseCall = Expression.Call(_tryParseMethod, sourceValue, _valueVariable);
            var successfulParseReturnValue = _valueVariable.GetConversionTo(targetType);
            var defaultValue         = Expression.Default(targetType);
            var parsedValueOrDefault = Expression.Condition(tryParseCall, successfulParseReturnValue, defaultValue);
            var tryParseBlock        = Expression.Block(new[] { _valueVariable }, parsedValueOrDefault);

            return(tryParseBlock);
        }
示例#6
0
        public Expression GetConversion(Expression sourceValue, Type targetType)
        {
            if (sourceValue.Type == typeof(Guid?))
            {
                return(sourceValue.GetValueOrDefaultCall());
            }

            if (sourceValue.Type != typeof(string))
            {
                sourceValue = ToStringConverter.GetConversion(sourceValue);
            }

            var parseMethod = targetType == typeof(Guid)
                ? _parseGuidMethod
                : _parseGuidNullableMethod;

            var parseCall = Expression.Call(parseMethod, sourceValue);

            return(parseCall);
        }
示例#7
0
        public override Expression GetConversion(Expression sourceValue, Type targetType)
        {
            bool sourceIsAnEnum;

            if (sourceValue.Type != typeof(string))
            {
                sourceIsAnEnum = sourceValue.Type.GetNonNullableType().IsEnum();
                sourceValue    = _toStringConverter.GetConversion(sourceValue);
            }
            else
            {
                sourceIsAnEnum = false;
            }

            var nonNullableEnumType = targetType.GetNonNullableType();

            var tryParseMethod = typeof(Enum)
                                 .GetPublicStaticMethods()
                                 .First(m => (m.Name == "TryParse") && (m.GetParameters().Length == 3))
                                 .MakeGenericMethod(nonNullableEnumType);

            var valueVariable = Expression.Variable(nonNullableEnumType, nonNullableEnumType.GetShortVariableName());

            var tryParseCall = Expression.Call(
                tryParseMethod,
                sourceValue,
                Expression.Constant(true, typeof(bool)), // <- IgnoreCase
                valueVariable);

            var defaultValue       = Expression.Default(targetType);
            var parseSuccessBranch = GetParseSuccessBranch(sourceIsAnEnum, valueVariable, defaultValue);

            var parsedValueOrDefault = Expression.Condition(tryParseCall, parseSuccessBranch, defaultValue);
            var tryParseBlock        = Expression.Block(new[] { valueVariable }, parsedValueOrDefault);

            return(tryParseBlock);
        }
示例#8
0
        private static Expression GetStringValueConversion(
            Expression sourceValue,
            Expression fallbackValue,
            Type nonNullableTargetEnumType)
        {
            if (sourceValue.Type != typeof(string))
            {
                sourceValue = ToStringConverter.GetConversion(sourceValue);
            }

            var underlyingEnumType = Enum.GetUnderlyingType(nonNullableTargetEnumType);

            var isNumericTest = GetIsNumericTest(sourceValue);

            var numericConversion = GetNumericStringToEnumConversion(
                sourceValue,
                fallbackValue,
                nonNullableTargetEnumType,
                underlyingEnumType);

            var nameMatchingConversion = GetStringToEnumConversion(
                sourceValue,
                fallbackValue,
                nonNullableTargetEnumType);

            var numericOrNameConversion = Expression.Condition(
                isNumericTest,
                numericConversion,
                nameMatchingConversion);

            var convertedValueOrDefault = Expression.Condition(
                StringExpressionExtensions.GetIsNullOrWhiteSpaceCall(sourceValue),
                fallbackValue,
                numericOrNameConversion);

            return(convertedValueOrDefault);
        }
示例#9
0
        public Expression GetConversion(Expression sourceValue, Type targetType)
        {
            if (sourceValue.Type == typeof(char?))
            {
                return(sourceValue.GetValueOrDefaultCall());
            }

            if (sourceValue.Type == typeof(object))
            {
                sourceValue = ToStringConverter.GetConversion(sourceValue);
            }

            if (sourceValue.Type == typeof(string))
            {
                return(GetFromStringConversion(sourceValue, targetType));
            }

            if (sourceValue.Type.GetNonNullableType().IsEnum())
            {
                sourceValue = sourceValue.GetConversionTo <int>();
            }

            return(GetFromNumericConversion(sourceValue, targetType));
        }
示例#10
0
        private static Expression GetFlagsEnumConversion(
            Expression sourceValue,
            Expression fallbackValue,
            Type nonNullableSourceType,
            Type nonNullableTargetEnumType)
        {
            var enumTypeName       = GetVariableNameFor(nonNullableTargetEnumType);
            var underlyingEnumType = Enum.GetUnderlyingType(nonNullableTargetEnumType);

            var enumValueVariable     = Expression.Variable(underlyingEnumType, enumTypeName + "Value");
            var underlyingTypeDefault = underlyingEnumType.ToDefaultExpression();
            var assignEnumValue       = enumValueVariable.AssignTo(underlyingTypeDefault);

            if (nonNullableSourceType.IsNumeric())
            {
                return(GetNumericToFlagsEnumConversion(
                           sourceValue,
                           fallbackValue,
                           nonNullableTargetEnumType,
                           enumTypeName,
                           enumValueVariable,
                           assignEnumValue));
            }

            if (sourceValue.Type != typeof(string))
            {
                sourceValue = ToStringConverter.GetConversion(sourceValue);
            }

            var sourceValuesVariable = GetEnumValuesVariable(enumTypeName, typeof(string));

            var splitSourceValueCall = Expression.Call(
                sourceValue,
                typeof(string).GetPublicInstanceMethod("Split", typeof(char[])),
                Expression.NewArrayInit(typeof(char), ','.ToConstantExpression()));

            var assignSourceValues = GetValuesEnumeratorAssignment(sourceValuesVariable, splitSourceValueCall);

            var ifNotMoveNextBreak = GetLoopExitCheck(sourceValuesVariable, out var loopBreakTarget);

            var localSourceValueVariable = Expression.Variable(typeof(string), enumTypeName);
            var enumeratorCurrent        = Expression.Property(sourceValuesVariable, "Current");
            var stringTrimMethod         = typeof(string).GetPublicInstanceMethod("Trim", parameterCount: 0);
            var currentTrimmed           = Expression.Call(enumeratorCurrent, stringTrimMethod);
            var assignLocalVariable      = localSourceValueVariable.AssignTo(currentTrimmed);

            var isNumericTest = GetIsNumericTest(localSourceValueVariable);

            var sourceNumericValueVariableName = enumTypeName + underlyingEnumType.Name + "Value";
            var sourceNumericValueVariable     = Expression.Variable(underlyingEnumType, sourceNumericValueVariableName);
            var parsedString          = GetStringParseCall(localSourceValueVariable, underlyingEnumType);
            var assignNumericVariable = sourceNumericValueVariable.AssignTo(parsedString);

            var numericValuePopulationLoop = GetNumericToFlagsEnumPopulationLoop(
                nonNullableTargetEnumType,
                enumTypeName,
                enumValueVariable,
                sourceNumericValueVariable,
                out var enumValuesVariable,
                out var assignEnumValues);

            var numericValuePopulationBlock = Expression.Block(
                new[] { enumValuesVariable },
                assignNumericVariable,
                assignEnumValues,
                numericValuePopulationLoop);

            var stringValueConversion = GetStringToEnumConversion(
                localSourceValueVariable,
                underlyingTypeDefault,
                nonNullableTargetEnumType);

            var assignParsedEnumValue = Expression.OrAssign(enumValueVariable, stringValueConversion);

            var assignValidValuesIfPossible = Expression.IfThenElse(
                isNumericTest,
                numericValuePopulationBlock,
                assignParsedEnumValue);

            var loopBody = Expression.Block(
                new[] { localSourceValueVariable, sourceNumericValueVariable },
                ifNotMoveNextBreak,
                assignLocalVariable,
                assignValidValuesIfPossible);

            var populationBlock = Expression.Block(
                new[] { sourceValuesVariable, enumValueVariable },
                assignEnumValue,
                assignSourceValues,
                Expression.Loop(loopBody, loopBreakTarget),
                enumValueVariable.GetConversionTo(fallbackValue.Type));

            return(populationBlock);
        }