Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Getting error on IEnumerable Sum() method: "violates the constraint of type 'TAccumulator'." #280

Closed
davideicardi opened this issue Mar 22, 2023 Discussed in #279 · 2 comments

Comments

@davideicardi
Copy link
Member

Discussed in #279

Originally posted by pburrows March 19, 2023
I have an expression:

Enemies.Sum(p=>p.TotalDollarsEarned) > 50

Where "Enemies" is a parameter of type List<ComplexExpressionParameter>

Defined as:

    private class ComplexExpressionParameter
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public decimal TotalDollarsEarned { get; set; }
    }

I am getting the error (I'll paste the full error at the bottom):

 ---> System.Security.VerificationException: Method System.Linq.Enumerable.Sum: type argument 'System.Object' violates the constraint of type parameter 'TAccumulator'.

Is there something I'm missing in getting Sum() to work? It looks like some issue where the variable Enemies is an object and not an IEnumerable, but I'm not sure what to do about that. I already tried casting it as List in my expression and that doesn't work.


Full Error:

System.ArgumentException: GenericArguments[2], 'System.Object', on 'TResult Sum[TSource,TResult,TAccumulator](System.Collections.Generic.IEnumerable`1[TSource], System.Func`2[TSource,TResult])' violates the constraint of type 'TAccumulator'.
 ---> System.Security.VerificationException: Method System.Linq.Enumerable.Sum: type argument 'System.Object' violates the constraint of type parameter 'TAccumulator'.
   at System.RuntimeMethodHandle.GetStubIfNeeded(RuntimeMethodHandleInternal method, RuntimeType declaringType, RuntimeType[] methodInstantiation)
   at System.Reflection.RuntimeMethodInfo.MakeGenericMethod(Type[] methodInstantiation)
   --- End of inner exception stack trace ---
   at System.RuntimeType.ValidateGenericArguments(MemberInfo definition, RuntimeType[] genericArguments, Exception e)
   at System.Reflection.RuntimeMethodInfo.MakeGenericMethod(Type[] methodInstantiation)
   at DynamicExpresso.Parsing.Parser.MakeGenericMethod(MethodData method)
   at DynamicExpresso.Parsing.Parser.CheckIfMethodIsApplicableAndPrepareIt(MethodData method, Expression[] args)
   at DynamicExpresso.Parsing.Parser.<>c__DisplayClass110_0.<FindBestMethod>b__0(MethodData m)
   at System.Linq.Enumerable.WhereEnumerableIterator`1.ToArray()
   at DynamicExpresso.Parsing.Parser.FindBestMethod(IEnumerable`1 methods, Expression[] args)
   at DynamicExpresso.Parsing.Parser.FindBestMethod(IEnumerable`1 methods, Expression[] args)
   at DynamicExpresso.Parsing.Parser.FindExtensionMethods(String methodName, Expression[] args)
   at DynamicExpresso.Parsing.Parser.ParseExtensionMethodInvocation(Type type, Expression instance, Int32 errorPos, String id, Expression[] args)
   at DynamicExpresso.Parsing.Parser.ParseMethodInvocation(Type type, Expression instance, Int32 errorPos, String methodName)
   at DynamicExpresso.Parsing.Parser.ParseMemberAccess(Type type, Expression instance)
   at DynamicExpresso.Parsing.Parser.ParseMemberAccess(Expression instance)
   at DynamicExpresso.Parsing.Parser.ParsePrimary()
   at DynamicExpresso.Parsing.Parser.ParseUnary()
   at DynamicExpresso.Parsing.Parser.ParseMultiplicative()
   at DynamicExpresso.Parsing.Parser.ParseAdditive()
   at DynamicExpresso.Parsing.Parser.ParseShift()
   at DynamicExpresso.Parsing.Parser.ParseTypeTesting()
   at DynamicExpresso.Parsing.Parser.ParseComparison()
   at DynamicExpresso.Parsing.Parser.ParseLogicalAnd()
   at DynamicExpresso.Parsing.Parser.ParseLogicalXor()
   at DynamicExpresso.Parsing.Parser.ParseLogicalOr()
   at DynamicExpresso.Parsing.Parser.ParseConditionalAnd()
   at DynamicExpresso.Parsing.Parser.ParseConditionalOr()
   at DynamicExpresso.Parsing.Parser.ParseConditional()
   at DynamicExpresso.Parsing.Parser.ParseAssignment()
   at DynamicExpresso.Parsing.Parser.ParseExpressionSegment()
   at DynamicExpresso.Parsing.Parser.ParseExpressionSegment(Type returnType)
   at DynamicExpresso.Parsing.Parser.Parse()
   at DynamicExpresso.Parsing.Parser.Parse(ParserArguments arguments)
   at DynamicExpresso.Interpreter.ParseAsLambda(String expressionText, Type expressionType, Parameter[] parameters)
   at DynamicExpresso.Interpreter.Parse(String expressionText, Type expressionType, Parameter[] parameters)
   at DynamicExpresso.Interpreter.Parse(String expressionText, Parameter[] parameters)
   at Commissions.Api.CommissionPlans.Engine.ExpressionEngines.DynamicExpresso.DynamicExpressoHelpers.GetLambdaFromExpression(String expression, Parameter[] parameters, Boolean cache) in ...
@metoule
Copy link
Contributor

metoule commented Mar 23, 2023

I confirm it's a duplicate of #270 and that it was fixed via #274.

The following test works on the master branch (and fails when #274 is reverted):

private class ComplexExpressionParameter
{
  public decimal TotalDollarsEarned { get; set; }
}

[Test]
public void GitHub_Issue_280()
{
  var interpreter = new Interpreter(InterpreterOptions.Default | InterpreterOptions.LambdaExpressions);
  interpreter.SetVariable("Enemies", new List<ComplexExpressionParameter>
  {
  	new ComplexExpressionParameter() { TotalDollarsEarned = 22 },
  	new ComplexExpressionParameter() { TotalDollarsEarned = 23 },
  });
  
  var result = interpreter.Eval<decimal>("Enemies.Sum(p => p.TotalDollarsEarned)");
  Assert.AreEqual(45, result);
}

@davideicardi maybe you can release a new version?

@davideicardi
Copy link
Member Author

Close this because already fixed in v2.16.0. Thank you @metoule !

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants