From 999f0ac258e699365897c309708c68f2f00a3baa Mon Sep 17 00:00:00 2001 From: Roman Artiukhin Date: Mon, 12 Sep 2022 13:51:34 +0300 Subject: [PATCH 1/2] Compile lambda for null access expressions --- .../ExpressionProcessorFindValueFixture.cs | 30 +++++++++++++++++++ src/NHibernate/Impl/ExpressionProcessor.cs | 11 +++++-- 2 files changed, 39 insertions(+), 2 deletions(-) diff --git a/src/NHibernate.Test/Criteria/Lambda/ExpressionProcessorFindValueFixture.cs b/src/NHibernate.Test/Criteria/Lambda/ExpressionProcessorFindValueFixture.cs index d3ee7736433..b5bbe34cdd2 100644 --- a/src/NHibernate.Test/Criteria/Lambda/ExpressionProcessorFindValueFixture.cs +++ b/src/NHibernate.Test/Criteria/Lambda/ExpressionProcessorFindValueFixture.cs @@ -42,6 +42,36 @@ public void StaticPropertyInstanceMethodCall() Assert.AreEqual(expected, actual); } + + [Test] + public void NullableNullHasValue() + { + int? v = null; + var actual = GetValue(() => v.HasValue); + var expected = v.HasValue; + + Assert.AreEqual(expected, actual); + } + + [Test] + public void NullableNullGetValueOrDefault() + { + int? v = null; + var actual = GetValue(() => v.GetValueOrDefault()); + var expected = v.GetValueOrDefault(); + + Assert.AreEqual(expected, actual); + } + + [Test] + public void NullableNullValue() + { + int? v = null; + Expression> expression = () => v.Value; + + Assert.Throws(() => GetValue(expression)); + Assert.Throws(() => expression.Compile().Invoke()); + } [Test] public void StaticPropertyInstanceMultipleMethodCall() diff --git a/src/NHibernate/Impl/ExpressionProcessor.cs b/src/NHibernate/Impl/ExpressionProcessor.cs index 74bea3fdf90..ccd52778f1b 100644 --- a/src/NHibernate/Impl/ExpressionProcessor.cs +++ b/src/NHibernate/Impl/ExpressionProcessor.cs @@ -261,18 +261,25 @@ public static object FindValue(Expression expression) return constantExpression.Value; case ExpressionType.MemberAccess: var memberExpression = (MemberExpression) expression; + var instance = findValue(memberExpression.Expression); + if (instance == null && memberExpression.Expression != null) + break; + switch (memberExpression.Member.MemberType) { case MemberTypes.Field: - return ((FieldInfo) memberExpression.Member).GetValue(findValue(memberExpression.Expression)); + return ((FieldInfo) memberExpression.Member).GetValue(instance); case MemberTypes.Property: - return ((PropertyInfo) memberExpression.Member).GetValue(findValue(memberExpression.Expression)); + return ((PropertyInfo) memberExpression.Member).GetValue(instance); } break; case ExpressionType.Call: var methodCallExpression = (MethodCallExpression) expression; var args = methodCallExpression.Arguments.ToArray(arg => FindValue(arg)); var callingObject = findValue(methodCallExpression.Object); + if (callingObject == null && methodCallExpression.Object != null) + break; + return methodCallExpression.Method.Invoke(callingObject, args); case ExpressionType.Convert: var unaryExpression = (UnaryExpression) expression; From 7376d1a82d5114ada2882eefdc51f6032046095a Mon Sep 17 00:00:00 2001 From: Roman Artiukhin Date: Mon, 12 Sep 2022 14:01:02 +0300 Subject: [PATCH 2/2] oops --- .../Criteria/Lambda/ExpressionProcessorFindValueFixture.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/NHibernate.Test/Criteria/Lambda/ExpressionProcessorFindValueFixture.cs b/src/NHibernate.Test/Criteria/Lambda/ExpressionProcessorFindValueFixture.cs index b5bbe34cdd2..749dc0a657b 100644 --- a/src/NHibernate.Test/Criteria/Lambda/ExpressionProcessorFindValueFixture.cs +++ b/src/NHibernate.Test/Criteria/Lambda/ExpressionProcessorFindValueFixture.cs @@ -69,8 +69,8 @@ public void NullableNullValue() int? v = null; Expression> expression = () => v.Value; - Assert.Throws(() => GetValue(expression)); - Assert.Throws(() => expression.Compile().Invoke()); + Assert.Throws(() => GetValue(expression)); + Assert.Throws(() => expression.Compile().Invoke()); } [Test]