diff --git a/src/System.Linq.Dynamic.Core/Parser/Constants.cs b/src/System.Linq.Dynamic.Core/Parser/Constants.cs
index da3e2e45..86555261 100644
--- a/src/System.Linq.Dynamic.Core/Parser/Constants.cs
+++ b/src/System.Linq.Dynamic.Core/Parser/Constants.cs
@@ -4,8 +4,9 @@ namespace System.Linq.Dynamic.Core.Parser
{
internal static class Constants
{
- public static readonly Expression TrueLiteral = Expression.Constant(true);
- public static readonly Expression FalseLiteral = Expression.Constant(false);
- public static readonly Expression NullLiteral = Expression.Constant(null);
+ public static bool IsNull(Expression exp)
+ {
+ return exp is ConstantExpression cExp && cExp.Value == null;
+ }
}
}
diff --git a/src/System.Linq.Dynamic.Core/Parser/ExpressionHelper.cs b/src/System.Linq.Dynamic.Core/Parser/ExpressionHelper.cs
index 65ae19ea..bb92daaf 100644
--- a/src/System.Linq.Dynamic.Core/Parser/ExpressionHelper.cs
+++ b/src/System.Linq.Dynamic.Core/Parser/ExpressionHelper.cs
@@ -256,7 +256,7 @@ public Expression GenerateAndAlsoNotNullExpression(Expression sourceExpression)
expresssions.Reverse();
// Convert all expressions into '!= null'
- var binaryExpressions = expresssions.Select(expression => Expression.NotEqual(expression, Constants.NullLiteral)).ToArray();
+ var binaryExpressions = expresssions.Select(expression => Expression.NotEqual(expression, Expression.Constant(null))).ToArray();
// Convert all binary expressions into `AndAlso(...)`
var andAlsoExpression = binaryExpressions[0];
diff --git a/src/System.Linq.Dynamic.Core/Parser/ExpressionParser.cs b/src/System.Linq.Dynamic.Core/Parser/ExpressionParser.cs
index 4fa446ed..e0c6ff0e 100644
--- a/src/System.Linq.Dynamic.Core/Parser/ExpressionParser.cs
+++ b/src/System.Linq.Dynamic.Core/Parser/ExpressionParser.cs
@@ -428,7 +428,7 @@ Expression ParseComparisonOperator()
if (isEquality && (!left.Type.GetTypeInfo().IsValueType && !right.Type.GetTypeInfo().IsValueType || left.Type == typeof(Guid) && right.Type == typeof(Guid)))
{
// If left or right is NullLiteral, just continue. Else check if the types differ.
- if (!(left == Constants.NullLiteral || right == Constants.NullLiteral) && left.Type != right.Type)
+ if (!(Constants.IsNull(left) || Constants.IsNull(right)) && left.Type != right.Type)
{
if (left.Type.IsAssignableFrom(right.Type))
{
@@ -1096,7 +1096,7 @@ Expression ParseFunctionNullPropagation()
{
var expressionTest = _expressionHelper.GenerateAndAlsoNotNullExpression(memberExpression);
var expressionIfTrue = memberExpression;
- var expressionIfFalse = args.Length == 2 ? args[1] : Constants.NullLiteral;
+ var expressionIfFalse = args.Length == 2 ? args[1] : Expression.Constant(null);
return GenerateConditional(expressionTest, expressionIfTrue, expressionIfFalse, errorPos);
}
@@ -1170,12 +1170,12 @@ Expression GenerateConditional(Expression test, Expression expr1, Expression exp
if (expr1.Type != expr2.Type)
{
- if ((expr1 == Constants.NullLiteral && expr2.Type.GetTypeInfo().IsValueType) || (expr2 == Constants.NullLiteral && expr1.Type.GetTypeInfo().IsValueType))
+ if ((Constants.IsNull(expr1) && expr2.Type.GetTypeInfo().IsValueType) || (Constants.IsNull(expr2) && expr1.Type.GetTypeInfo().IsValueType))
{
// If expr1 is a null constant and expr2 is a IsValueType:
// - create nullable constant from expr1 with type from expr2
// - convert expr2 to nullable
- if (expr1 == Constants.NullLiteral && expr2.Type.GetTypeInfo().IsValueType)
+ if (Constants.IsNull(expr1) && expr2.Type.GetTypeInfo().IsValueType)
{
Type nullableType = typeof(Nullable<>).MakeGenericType(expr2.Type);
expr1 = Expression.Constant(null, nullableType);
@@ -1185,7 +1185,7 @@ Expression GenerateConditional(Expression test, Expression expr1, Expression exp
// If expr2 is a null constant and expr1 is a IsValueType:
// - create nullable constant from expr2 with type from expr1
// - convert expr1 to nullable
- if (expr2 == Constants.NullLiteral && expr1.Type.GetTypeInfo().IsValueType)
+ if (Constants.IsNull(expr2) && expr1.Type.GetTypeInfo().IsValueType)
{
Type nullableType = typeof(Nullable<>).MakeGenericType(expr1.Type);
expr2 = Expression.Constant(null, nullableType);
@@ -1195,8 +1195,8 @@ Expression GenerateConditional(Expression test, Expression expr1, Expression exp
return Expression.Condition(test, expr1, expr2);
}
- Expression expr1As2 = expr2 != Constants.NullLiteral ? _parsingConfig.ExpressionPromoter.Promote(expr1, expr2.Type, true, false) : null;
- Expression expr2As1 = expr1 != Constants.NullLiteral ? _parsingConfig.ExpressionPromoter.Promote(expr2, expr1.Type, true, false) : null;
+ Expression expr1As2 = !Constants.IsNull(expr2) ? _parsingConfig.ExpressionPromoter.Promote(expr1, expr2.Type, true, false) : null;
+ Expression expr2As1 = !Constants.IsNull(expr1) ? _parsingConfig.ExpressionPromoter.Promote(expr2, expr1.Type, true, false) : null;
if (expr1As2 != null && expr2As1 == null)
{
expr1 = expr1As2;
@@ -1207,8 +1207,8 @@ Expression GenerateConditional(Expression test, Expression expr1, Expression exp
}
else
{
- string type1 = expr1 != Constants.NullLiteral ? expr1.Type.Name : "null";
- string type2 = expr2 != Constants.NullLiteral ? expr2.Type.Name : "null";
+ string type1 = !Constants.IsNull(expr1) ? expr1.Type.Name : "null";
+ string type2 = !Constants.IsNull(expr2) ? expr2.Type.Name : "null";
if (expr1As2 != null)
{
throw ParseError(errorPos, Res.BothTypesConvertToOther, type1, type2);
diff --git a/src/System.Linq.Dynamic.Core/Parser/ExpressionPromoter.cs b/src/System.Linq.Dynamic.Core/Parser/ExpressionPromoter.cs
index 1400fac7..1633c3ae 100644
--- a/src/System.Linq.Dynamic.Core/Parser/ExpressionPromoter.cs
+++ b/src/System.Linq.Dynamic.Core/Parser/ExpressionPromoter.cs
@@ -3,7 +3,7 @@
namespace System.Linq.Dynamic.Core.Parser
{
- internal class ExpressionPromoter : IExpressionPromoter
+ public class ExpressionPromoter : IExpressionPromoter
{
///
public virtual Expression Promote(Expression expr, Type type, bool exact, bool convertExpr)
@@ -17,7 +17,7 @@ public virtual Expression Promote(Expression expr, Type type, bool exact, bool c
if (ce != null)
{
- if (ce == Constants.NullLiteral || ce.Value == null)
+ if (Constants.IsNull(ce))
{
if (!type.GetTypeInfo().IsValueType || TypeHelper.IsNullableType(type))
{
diff --git a/src/System.Linq.Dynamic.Core/Parser/KeywordsHelper.cs b/src/System.Linq.Dynamic.Core/Parser/KeywordsHelper.cs
index 74cc2234..2f9098ea 100644
--- a/src/System.Linq.Dynamic.Core/Parser/KeywordsHelper.cs
+++ b/src/System.Linq.Dynamic.Core/Parser/KeywordsHelper.cs
@@ -1,4 +1,5 @@
using System.Collections.Generic;
+using System.Linq.Expressions;
namespace System.Linq.Dynamic.Core.Parser
{
@@ -22,9 +23,9 @@ internal class KeywordsHelper : IKeywordsHelper
private readonly IDictionary _keywords = new Dictionary(StringComparer.OrdinalIgnoreCase)
{
- { "true", Constants.TrueLiteral },
- { "false", Constants.FalseLiteral },
- { "null", Constants.NullLiteral }
+ { "true", Expression.Constant(true) },
+ { "false", Expression.Constant(false) },
+ { "null", Expression.Constant(null) }
};
public KeywordsHelper(ParsingConfig config)