Skip to content

Commit a7899b8

Browse files
authored
No longer promote generic types if their arguments aren't compatible (#277)
1 parent cd73460 commit a7899b8

File tree

2 files changed

+26
-2
lines changed

2 files changed

+26
-2
lines changed

src/DynamicExpresso.Core/Parsing/Parser.cs

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2452,7 +2452,7 @@ private static Expression PromoteExpression(Expression expr, Type type, bool exa
24522452

24532453
if (type.IsGenericType && !IsNumericType(type))
24542454
{
2455-
var genericType = FindAssignableGenericType(expr.Type, type.GetGenericTypeDefinition());
2455+
var genericType = FindAssignableGenericType(expr.Type, type);
24562456
if (genericType != null)
24572457
return Expression.Convert(expr, genericType);
24582458
}
@@ -2476,6 +2476,11 @@ private static bool IsCompatibleWith(Type source, Type target)
24762476
return true;
24772477
}
24782478

2479+
if (target.IsGenericParameter)
2480+
{
2481+
return true;
2482+
}
2483+
24792484
if (!target.IsValueType)
24802485
{
24812486
return target.IsAssignableFrom(source);
@@ -2626,8 +2631,9 @@ private static bool IsWritable(Expression expression)
26262631
}
26272632

26282633
// from http://stackoverflow.com/a/1075059/209727
2629-
private static Type FindAssignableGenericType(Type givenType, Type genericTypeDefinition)
2634+
private static Type FindAssignableGenericType(Type givenType, Type constructedGenericType)
26302635
{
2636+
var genericTypeDefinition = constructedGenericType.GetGenericTypeDefinition();
26312637
var interfaceTypes = givenType.GetInterfaces();
26322638

26332639
foreach (var it in interfaceTypes)
@@ -2639,7 +2645,16 @@ private static Type FindAssignableGenericType(Type givenType, Type genericTypeDe
26392645
}
26402646

26412647
if (givenType.IsGenericType && givenType.GetGenericTypeDefinition() == genericTypeDefinition)
2648+
{
2649+
// the given type has the same generic type of the fully constructed generic type
2650+
// => check if the generic arguments are compatible (e.g. Nullable<int> and Nullable<DateTime>: int is not compatible with DateTime)
2651+
var givenTypeGenericsArgs = givenType.GenericTypeArguments;
2652+
var constructedGenericsArgs = constructedGenericType.GenericTypeArguments;
2653+
if (givenTypeGenericsArgs.Zip(constructedGenericsArgs, (g, c) => IsCompatibleWith(g, c)).Any(compatible => !compatible))
2654+
return null;
2655+
26422656
return givenType;
2657+
}
26432658

26442659
var baseType = givenType.BaseType;
26452660
if (baseType == null)

test/DynamicExpresso.UnitTest/GithubIssues.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -719,6 +719,15 @@ public void GitHub_Issue_263(string paramsArguments)
719719
var result = interpreter.Eval<int>($"Utils.ParamArrayObjects({paramsArguments})");
720720
Assert.AreEqual(4, result);
721721
}
722+
723+
[Test]
724+
public void GitHub_Issue_276()
725+
{
726+
var interpreter = new Interpreter();
727+
728+
var result = interpreter.Eval<bool>("((int?)5)>((double?)4)");
729+
Assert.IsTrue(result);
730+
}
722731
}
723732

724733
internal static class GithubIssuesTestExtensionsMethods

0 commit comments

Comments
 (0)