Skip to content

Commit b734bfb

Browse files
CopilotStefH
andauthored
Fix enum type preservation in additive arithmetic operations (#976)
* Initial plan * Fix: enum + int and int + enum now return enum type (C# semantics); enum - int returns enum type Agent-Logs-Url: https://github.com/zzzprojects/System.Linq.Dynamic.Core/sessions/0cb2e89e-56b5-4db3-8850-f5013136f847 Co-authored-by: StefH <249938+StefH@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: StefH <249938+StefH@users.noreply.github.com>
1 parent 4ff9105 commit b734bfb

File tree

2 files changed

+50
-4
lines changed

2 files changed

+50
-4
lines changed

src/System.Linq.Dynamic.Core/Parser/ExpressionParser.cs

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -766,14 +766,34 @@ private Expression ParseAdditive()
766766
}
767767
else
768768
{
769+
var leftTypeForAdd = left.Type;
770+
var rightTypeForAdd = right.Type;
769771
CheckAndPromoteOperands(typeof(IAddSignatures), op.Id, op.Text, ref left, ref right, op.Pos);
770772
left = _expressionHelper.GenerateAdd(left, right);
773+
// C# semantics: enum + int = enum, int + enum = enum
774+
if (TypeHelper.IsEnumType(leftTypeForAdd) && TypeHelper.IsNumericType(rightTypeForAdd))
775+
{
776+
left = Expression.Convert(left, leftTypeForAdd);
777+
}
778+
else if (TypeHelper.IsNumericType(leftTypeForAdd) && TypeHelper.IsEnumType(rightTypeForAdd))
779+
{
780+
left = Expression.Convert(left, rightTypeForAdd);
781+
}
771782
}
772783
break;
773784

774785
case TokenId.Minus:
775-
CheckAndPromoteOperands(typeof(ISubtractSignatures), op.Id, op.Text, ref left, ref right, op.Pos);
776-
left = _expressionHelper.GenerateSubtract(left, right);
786+
{
787+
var leftTypeForSubtract = left.Type;
788+
var rightTypeForSubtract = right.Type;
789+
CheckAndPromoteOperands(typeof(ISubtractSignatures), op.Id, op.Text, ref left, ref right, op.Pos);
790+
left = _expressionHelper.GenerateSubtract(left, right);
791+
// C# semantics: enum - int = enum (but enum - enum = underlying int type)
792+
if (TypeHelper.IsEnumType(leftTypeForSubtract) && TypeHelper.IsNumericType(rightTypeForSubtract))
793+
{
794+
left = Expression.Convert(left, leftTypeForSubtract);
795+
}
796+
}
777797
break;
778798
}
779799
}

test/System.Linq.Dynamic.Core.Tests/QueryableTests.Select.cs

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -224,8 +224,34 @@ public void Select_Dynamic_Add_Integer_And_DayOfWeekEnum()
224224
// Act
225225
var rangeResult = range.AsQueryable().Select("it + DayOfWeek.Monday");
226226

227-
// Assert
228-
Assert.Equal(range.Select(x => x + DayOfWeek.Monday).Cast<int>().ToArray(), rangeResult.Cast<int>().ToArray());
227+
// Assert - C# semantics: int + enum = enum
228+
Assert.Equal(range.Select(x => x + DayOfWeek.Monday).ToArray(), rangeResult.Cast<DayOfWeek>().ToArray());
229+
}
230+
231+
[Fact]
232+
public void Select_Dynamic_Subtract_DayOfWeekEnum_And_Integer()
233+
{
234+
// Arrange
235+
var range = new DayOfWeek[] { DayOfWeek.Tuesday };
236+
237+
// Act
238+
var rangeResult = range.AsQueryable().Select("it - 1");
239+
240+
// Assert - C# semantics: enum - int = enum
241+
Assert.Equal(range.Select(x => x - 1).ToArray(), rangeResult.Cast<DayOfWeek>().ToArray());
242+
}
243+
244+
[Fact]
245+
public void Select_Dynamic_Subtract_DayOfWeekEnum_And_DayOfWeekEnum()
246+
{
247+
// Arrange
248+
var range = new DayOfWeek[] { DayOfWeek.Tuesday };
249+
250+
// Act
251+
var rangeResult = range.AsQueryable().Select("it - DayOfWeek.Monday");
252+
253+
// Assert - C# semantics: enum - enum = underlying int type
254+
Assert.Equal(range.Select(x => x - DayOfWeek.Monday).ToArray(), rangeResult.Cast<int>().ToArray());
229255
}
230256

231257
[Fact]

0 commit comments

Comments
 (0)