Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions src/System.Linq.Dynamic.Core/Parser/ExpressionParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -430,11 +430,11 @@ Expression ParseComparisonOperator()
// If left or right is NullLiteral, just continue. Else check if the types differ.
if (!(Constants.IsNull(left) || Constants.IsNull(right)) && left.Type != right.Type)
{
if (left.Type.IsAssignableFrom(right.Type))
if (left.Type.IsAssignableFrom(right.Type) || HasImplicitConversion(right.Type, left.Type))
{
right = Expression.Convert(right, left.Type);
}
else if (right.Type.IsAssignableFrom(left.Type))
else if (right.Type.IsAssignableFrom(left.Type) || HasImplicitConversion(left.Type, right.Type))
{
left = Expression.Convert(left, right.Type);
}
Expand Down Expand Up @@ -543,7 +543,9 @@ Expression ParseComparisonOperator()

private bool HasImplicitConversion(Type baseType, Type targetType)
Comment thread
alexweav marked this conversation as resolved.
{
return baseType.GetMethods(BindingFlags.Public | BindingFlags.Static)
var methods = baseType.GetMethods(BindingFlags.Public | BindingFlags.Static).ToList();
methods.AddRange(targetType.GetMethods(BindingFlags.Public | BindingFlags.Static));
return methods
.Where(mi => mi.Name == "op_Implicit" && mi.ReturnType == targetType)
.Any(mi => mi.GetParameters().FirstOrDefault()?.ParameterType == baseType);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
using NFluent;
using System.Collections.Generic;
using System.Collections.Generic;
using System.Linq.Dynamic.Core.CustomTypeProviders;
using System.Linq.Dynamic.Core.Exceptions;
using System.Linq.Dynamic.Core.Tests.Helpers.Models;
using System.Linq.Expressions;
using System.Reflection;
using NFluent;
using Xunit;
using User = System.Linq.Dynamic.Core.Tests.Helpers.Models.User;

Expand Down Expand Up @@ -64,6 +64,36 @@ public override string ToString()
}
}

public class CustomClassWithOneWayImplicitConversion
{
public CustomClassWithOneWayImplicitConversion(string origin)
{
Origin = origin;
}

public string Origin { get; }

public static implicit operator CustomClassWithOneWayImplicitConversion(string origin)
{
return new CustomClassWithOneWayImplicitConversion(origin);
}

public override string ToString()
{
return Origin;
}
}

public class TestImplicitConversionContainer
{
public TestImplicitConversionContainer(CustomClassWithOneWayImplicitConversion oneWay)
{
OneWay = oneWay;
}

public CustomClassWithOneWayImplicitConversion OneWay { get; }
}

public class TextHolder
{
public TextHolder(string name, CustomTextClass note)
Expand Down Expand Up @@ -757,6 +787,21 @@ public void DynamicExpressionParser_ParseLambda_With_Concat_CustomType_String()
Assert.Equal("note1 (name1)", result);
}

[Fact]
public void DynamicExpressionParser_ParseLambda_With_One_Way_Implicit_Conversions()
{
// Arrange
var testValue = "test";
var container = new TestImplicitConversionContainer(testValue);
var expressionText = $"OneWay == \"{testValue}\"";

// Act
var lambda = DynamicExpressionParser.ParseLambda<TestImplicitConversionContainer, bool>(ParsingConfig.Default, false, expressionText);

// Assert
Assert.NotNull(lambda);
}

[Fact]
public void DynamicExpressionParser_ParseLambda_Operator_Less_Greater_With_Guids()
{
Expand Down