public static bool Matches(this ExpressionType expressionType, OperatorFlags flags) { return((((flags & OperatorFlags.Addition) != 0) && expressionType.IsAddition()) || (((flags & OperatorFlags.Arithmetic) != 0) && expressionType.IsArithmetic()) || (((flags & OperatorFlags.Bitwise) != 0) && expressionType.IsBitwise()) || (((flags & OperatorFlags.Comparison) != 0) && expressionType.IsComparison()) || (((flags & OperatorFlags.Equality) != 0) && expressionType.IsEquality()) || (((flags & OperatorFlags.Logical) != 0) && expressionType.IsLogical()) || (((flags & OperatorFlags.Relational) != 0) && expressionType.IsRelational()) || (((flags & OperatorFlags.Shift) != 0) && expressionType.IsShift()) || (((flags & OperatorFlags.Subtraction) != 0) && expressionType.IsSubtraction())); }
public static void BinaryExpressionArgumentConverter(ref Expression left, ref Expression right, ExpressionType type) { BinaryExpressionEnumArgumentConverter(ref left, ref right); PreparingNullableArguments(ref left, ref right); if (type.IsBinary()) { var leftTypeIsNullable = left.Type.IsNullableType(); var rightTypeIsNullable = right.Type.IsNullableType(); var logicalOperation = type.IsBinaryLogical() || type.IsCompare(); var arifmeticOperation = type.IsArithmetic(); #region Arifmetic operation if (arifmeticOperation) { if (left.Type == right.Type && ArifmeticResultTypes.ContainsKey(left.Type)) { var commonType = ArifmeticResultTypes[left.Type]; left = ConvertExpression(left, commonType); right = ConvertExpression(right, commonType); } else { var leftType = Nullable.GetUnderlyingType(left.Type); var rightType = Nullable.GetUnderlyingType(right.Type); if ((leftTypeIsNullable && leftType == right.Type && ArifmeticResultTypes.ContainsKey(right.Type)) || (rightTypeIsNullable && rightType == left.Type && ArifmeticResultTypes.ContainsKey(left.Type))) { if (leftTypeIsNullable) { var commonType = ArifmeticResultTypes[left.Type]; if (!rightTypeIsNullable) { var commonUnderlyingType = commonType.GetGenericArguments().First(); right = ConvertExpression(right, commonUnderlyingType); } right = ConvertExpression(right, commonType); left = ConvertExpression(left, commonType); } else { var commonType = ArifmeticResultTypes[right.Type]; var commonUnderlyingType = commonType.GetGenericArguments().First(); left = ConvertExpression(left, commonUnderlyingType); left = ConvertExpression(left, commonType); right = ConvertExpression(right, commonType); } } } } #endregion if (logicalOperation && left.Type == right.Type) { return; } if (logicalOperation && left.Type == right.Type) { return; } if (leftTypeIsNullable || rightTypeIsNullable) { var leftType = Nullable.GetUnderlyingType(left.Type) ?? left.Type; var rightType = Nullable.GetUnderlyingType(right.Type) ?? right.Type; if (leftType == rightType) { var commonType = NullableType.MakeGenericType(leftType); left = ConvertExpression(left, commonType); right = ConvertExpression(right, commonType); } else { if (ImplicitNumericConversions.ContainsKey(leftType) && ImplicitNumericConversions.ContainsKey(rightType)) { var leftTypes = ImplicitNumericConversions[leftType]; var rightTypes = ImplicitNumericConversions[rightType]; var isIntegralTypes = IntegralTypes.Contains(left.Type) && IntegralTypes.Contains(right.Type); var commonType = isIntegralTypes ? leftTypes.Where(t => IntegralTypes.Contains(t)) .Intersect(rightTypes.Where(t => IntegralTypes.Contains(t))) .FirstOrDefault() : leftTypes.Intersect(rightTypes).FirstOrDefault(); if (commonType != null) { commonType = NullableType.MakeGenericType(commonType); left = ConvertExpression(left, commonType); right = ConvertExpression(right, commonType); } } } } else { if (ImplicitNumericConversions.ContainsKey(left.Type) && ImplicitNumericConversions.ContainsKey(right.Type)) { var leftTypes = ImplicitNumericConversions[left.Type]; var rightTypes = ImplicitNumericConversions[right.Type]; var isIntegralTypes = IntegralTypes.Contains(left.Type) && IntegralTypes.Contains(right.Type); var commonType = isIntegralTypes ? leftTypes.Where(t => IntegralTypes.Contains(t)) .Intersect(rightTypes.Where(t => IntegralTypes.Contains(t))) .FirstOrDefault() : leftTypes.Intersect(rightTypes).FirstOrDefault(); if (commonType != null) { left = ConvertExpression(left, commonType); right = ConvertExpression(right, commonType); } } } } }