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); } } } } }