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

ArgumentException when calling Count() method from object returned by dynamic #324

Closed
alser opened this issue Nov 6, 2024 · 4 comments · Fixed by #333
Closed

ArgumentException when calling Count() method from object returned by dynamic #324

alser opened this issue Nov 6, 2024 · 4 comments · Fixed by #333
Labels

Comments

@alser
Copy link

alser commented Nov 6, 2024

  • DynamicExpresso.Core 2.17.1
  • .NET 8.0

Issue is reproduced in following default console template:

<Project Sdk="Microsoft.NET.Sdk">

    <PropertyGroup>
        <OutputType>Exe</OutputType>
        <TargetFramework>net8.0</TargetFramework>
        <ImplicitUsings>enable</ImplicitUsings>
        <Nullable>enable</Nullable>
    </PropertyGroup>

    <ItemGroup>
      <PackageReference Include="DynamicExpresso.Core" Version="2.17.1" />
    </ItemGroup>

</Project>
using System.Dynamic;
using DynamicExpresso;

var interpreter = new Interpreter();
var expr = interpreter.Parse("p.Value.Count()", new Parameter("p", typeof(SampleParameter)));
var result = expr.Invoke(new SampleParameter());

Console.WriteLine($"Result: {result}");

public sealed class SampleClass
{
    public int Count() => 42;
}

public sealed class SampleParameter : DynamicObject
{
    public override bool TryGetMember(GetMemberBinder binder, out object? result)
    {
        switch (binder.Name)
        {
            case "Value":
                result = new SampleClass();
                return true;

            default:
                result = null;
                return false;
        }
    }
}

Here we have parameter SampleParameter which is a dynamic object. Its dynamic property Value returns some other non-dynamic object SampleClass, which in turn has method named Count().

Trying to parse expression like "p.Value.Count()" results in exception:

System.ArgumentException: Type System.Collections.Generic.IEnumerable`1[TSource] contains generic parameters (Parameter 'type')
   at System.Dynamic.Utils.TypeUtils.ValidateType(Type type, String paramName, Int32 index)
   at System.Dynamic.Utils.TypeUtils.ValidateType(Type type, String paramName, Boolean allowByRef, Boolean allowPointer)
   at System.Linq.Expressions.Expression.Convert(Expression expression, Type type, MethodInfo method)
   at DynamicExpresso.Resolution.ExpressionUtils.PromoteExpression(Expression expr, Type type, Boolean exact)
   at DynamicExpresso.Resolution.MethodResolution.CheckIfMethodIsApplicableAndPrepareIt(MethodData method, Expression[] args)
   at DynamicExpresso.Resolution.MethodResolution.<>c__DisplayClass1_0.<FindBestMethod>b__0(MethodData m)
   at System.Linq.Enumerable.WhereEnumerableIterator`1.ToArray()
   at DynamicExpresso.Resolution.MethodResolution.FindBestMethod(IEnumerable`1 methods, Expression[] args)
   at DynamicExpresso.Resolution.MethodResolution.FindBestMethod(IEnumerable`1 methods, Expression[] args)
   at DynamicExpresso.Reflection.MemberFinder.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, TokenId open, String openExpected, TokenId close, String closeExpected)
   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 Program.<Main>$(String[] args) in C:\Users\User\RiderProjects\ConsoleApp2\ConsoleApp2\Program.cs:line 5
  1. If method Count() renamed to something else (like Count2()), then all is ok, expression p.Value.Count2() successfully returns our magic number.
  2. Using DynamicExpresso.Core 2.16.1 no issues occur with Count() method.

It may have something to do with commit 2696232 where condition "expr is DynamicExpression" is added.

@davideicardi
Copy link
Member

Thank you for the bug report. I will try to fix it in the future. As usual any help is appreciated.

@davideicardi
Copy link
Member

It could be related to #325 .

@metoule
Copy link
Contributor

metoule commented Nov 16, 2024

Yes, the root cause is the same as #325. I'll open a PR to revert the change made in #296

@metoule
Copy link
Contributor

metoule commented Nov 16, 2024

Closing this issue as duplicate of #325

@metoule metoule closed this as not planned Won't fix, can't repro, duplicate, stale Nov 16, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants