You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Here is what to include in your request to make sure we implement a solution as quickly as possible.
1. Description
In order to explain the use case, I will track back to how we got there.
I needed a way to evaluate this type of expression SomeBool == 1 or SomeBool != 0. To solve that, we create in runtime a new type that swaps bool properties with BooleanVariable type. That BooleanVariable type has operator overloads to support comparison with int hence the expression above works.
Now, even when the expression is a bit more complex, for example SomeBool1 == 1 && SomeBool2 == 1, it works well. But in doing so it broke the standard usage of logical boolean operators and we run into a parsing exception in an expression like SomeBool1 && SomeBool2.
2. Exception
Exception message:
System.Linq.Dynamic.Core.Exceptions.ParseException
Operator '&&' incompatible with operand types 'BooleanVariable' and 'Boolean'
Stack trace:
at System.Linq.Dynamic.Core.Parser.ExpressionParser.CheckAndPromoteOperands(Type signatures, TokenId opId, String opName, Expression& left, Expression& right, Int32 errorPos) in C:\Dev\GitHub\System.Linq.Dynamic.Core\src\System.Linq.Dynamic.Core\Parser\ExpressionParser.cs:line 2082
at System.Linq.Dynamic.Core.Parser.ExpressionParser.ParseAndOperator() in C:\Dev\GitHub\System.Linq.Dynamic.Core\src\System.Linq.Dynamic.Core\Parser\ExpressionParser.cs:line 289
at System.Linq.Dynamic.Core.Parser.ExpressionParser.ParseOrOperator() in C:\Dev\GitHub\System.Linq.Dynamic.Core\src\System.Linq.Dynamic.Core\Parser\ExpressionParser.cs:line 265
at System.Linq.Dynamic.Core.Parser.ExpressionParser.ParseLambdaOperator() in C:\Dev\GitHub\System.Linq.Dynamic.Core\src\System.Linq.Dynamic.Core\Parser\ExpressionParser.cs:line 245
at System.Linq.Dynamic.Core.Parser.ExpressionParser.ParseNullCoalescingOperator() in C:\Dev\GitHub\System.Linq.Dynamic.Core\src\System.Linq.Dynamic.Core\Parser\ExpressionParser.cs:line 232
at System.Linq.Dynamic.Core.Parser.ExpressionParser.ParseConditionalOperator() in C:\Dev\GitHub\System.Linq.Dynamic.Core\src\System.Linq.Dynamic.Core\Parser\ExpressionParser.cs:line 216
at System.Linq.Dynamic.Core.Parser.ExpressionParser.Parse(Type resultType, Boolean createParameterCtor) in C:\Dev\GitHub\System.Linq.Dynamic.Core\src\System.Linq.Dynamic.Core\Parser\ExpressionParser.cs:line 154
at System.Linq.Dynamic.Core.DynamicExpressionParser.ParseLambda(Type delegateType, ParsingConfig parsingConfig, Boolean createParameterCtor, ParameterExpression[] parameters, Type resultType, String expression, Object[] values) in C:\Dev\GitHub\System.Linq.Dynamic.Core\src\System.Linq.Dynamic.Core\DynamicExpressionParser.cs:line 122
at System.Linq.Dynamic.Core.DynamicExpressionParser.ParseLambda(ParsingConfig parsingConfig, Boolean createParameterCtor, ParameterExpression[] parameters, Type resultType, String expression, Object[] values) in C:\Dev\GitHub\System.Linq.Dynamic.Core\src\System.Linq.Dynamic.Core\DynamicExpressionParser.cs:line 97
at System.Linq.Dynamic.Core.DynamicExpressionParser.ParseLambda(Boolean createParameterCtor, ParameterExpression[] parameters, Type resultType, String expression, Object[] values) in C:\Dev\GitHub\System.Linq.Dynamic.Core\src\System.Linq.Dynamic.Core\DynamicExpressionParser.cs:line 450
at System.Linq.Dynamic.Core.DynamicExpressionParser.ParseLambda(Boolean createParameterCtor, Type itType, Type resultType, String expression, Object[] values) in C:\Dev\GitHub\System.Linq.Dynamic.Core\src\System.Linq.Dynamic.Core\DynamicExpressionParser.cs:line 201
at System.Linq.Dynamic.Core.DynamicExpressionParser.ParseLambda(Type itType, Type resultType, String expression, Object[] values) in C:\Dev\GitHub\System.Linq.Dynamic.Core\src\System.Linq.Dynamic.Core\DynamicExpressionParser.cs:line 305
at Program.Main()
usingSystem;usingSystem.Linq.Dynamic.Core;publicclassProgram{publicstaticvoidMain(){varmodel=newModel{SomeBool1=newBooleanVariable(true),SomeBool2=true};Console.WriteLine(model.SomeBool1&&model.SomeBool2);varexpr=DynamicExpressionParser.ParseLambda(typeof(Model),null,"SomeBool1 && SomeBool2");varcompiled=expr.Compile();varresult=compiled.DynamicInvoke(model);Console.WriteLine(result);}}publicclassModel{publicBooleanVariableSomeBool1{get;set;}publicboolSomeBool2{get;set;}}publicreadonlystructBooleanVariable:IEquatable<bool>,IEquatable<BooleanVariable>,IConvertible{privatereadonlyboolinnerValue;publicBooleanVariable(boolinnerValue){this.innerValue=innerValue;}publicoverrideboolEquals(objectobj){returnobjisboolval&&this.Equals(val);}publicboolEquals(boolother){returnthis.innerValue==other;}publicboolEquals(BooleanVariableother){returnthis.Equals(other.innerValue);}publicoverrideintGetHashCode(){returnthis.innerValue.GetHashCode();}publicstaticimplicitoperatorbool(BooleanVariablev)=>v.innerValue;publicstaticimplicitoperatorBooleanVariable(boolb)=>newBooleanVariable(b);publicstaticbooloperator true(BooleanVariablev)=>v.innerValue;publicstaticbooloperator false(BooleanVariablev)=>!v.innerValue;// comparison to boolpublicstaticbooloperator==(BooleanVariablea,boolb)=>a.innerValue==b;publicstaticbooloperator!=(BooleanVariablea,boolb)=>a.innerValue!=b;// comparison to intpublicstaticbooloperator==(BooleanVariablea,intb)=>a.innerValue==(b!=0);publicstaticbooloperator!=(BooleanVariablea,intb)=>a.innerValue!=(b!=0);// comparison to decimalpublicstaticbooloperator==(BooleanVariablea,decimalb)=>a.innerValue==(b!=0);publicstaticbooloperator!=(BooleanVariablea,decimalb)=>a.innerValue!=(b!=0);// To/from selfpublicstaticbooloperator==(BooleanVariablea,BooleanVariableb)=>a.innerValue==b.innerValue;publicstaticbooloperator!=(BooleanVariablea,BooleanVariableb)=>a.innerValue!=b.innerValue;// see remaining code in Fiddle...}
4. Any further technical details
Of course, our usage is more complex than that with several types replaced in the same pattern, such as enums for comparison with strings (for example, Color == 'Red').
The text was updated successfully, but these errors were encountered:
Here is what to include in your request to make sure we implement a solution as quickly as possible.
1. Description
In order to explain the use case, I will track back to how we got there.
I needed a way to evaluate this type of expression
SomeBool == 1
orSomeBool != 0
. To solve that, we create in runtime a new type that swaps bool properties withBooleanVariable
type. ThatBooleanVariable
type has operator overloads to support comparison withint
hence the expression above works.Now, even when the expression is a bit more complex, for example
SomeBool1 == 1 && SomeBool2 == 1
, it works well. But in doing so it broke the standard usage of logical boolean operators and we run into a parsing exception in an expression likeSomeBool1 && SomeBool2
.2. Exception
Exception message:
Stack trace:
3. Fiddle or Project
Fiddle: https://dotnetfiddle.net/1UNldU
Or code for reference:
4. Any further technical details
Of course, our usage is more complex than that with several types replaced in the same pattern, such as enums for comparison with strings (for example,
Color == 'Red'
).The text was updated successfully, but these errors were encountered: