zzzprojects / Eval-Expression.NET

C# Eval Expression | Evaluate, Compile, and Execute C# code and expression at runtime.
https://eval-expression.net/
Other
449 stars 86 forks source link

DynamicObject w/ index access throws InvalidOperationException #86

Closed marcOcram closed 3 years ago

marcOcram commented 3 years ago

Hello,

if I try to access a property by index of a class derived from DynamicObject, I get an error that the sequence contains no elements.

using System;
using System.Dynamic;
using System.Collections.Generic;
using Z.Expressions;

public class Program
{
    public class Globals
    {
        private readonly DynamicIndexAccess _values = new DynamicIndexAccess();

        public dynamic Values { get { return _values; } }
    }

    public class DynamicIndexAccess : DynamicObject
    {
        private readonly IReadOnlyDictionary<string, object> _values;

        public DynamicIndexAccess()
        {
            var values = new Dictionary<string, object>();
            values.Add("Hello", "Hello World!");
            _values = values;
        }

        public override bool TryGetIndex(GetIndexBinder binder, object[] indexes, out object result)
        {
            return _values.TryGetValue((string)indexes[0], out result);
        }

        public override bool TryGetMember(GetMemberBinder binder, out object result)
        {
            return _values.TryGetValue(binder.Name, out result);
        }
    }

    public static void Main()
    {
        Globals globals = new Globals();
        // runs
        Console.WriteLine(globals.Values.Hello);
        // runs
        Console.WriteLine(Eval.Execute<string>("Values.Hello", globals));
        // runs
        Console.WriteLine(globals.Values["Hello"]);
        // fails
        Console.WriteLine(Eval.Execute<string>("Values[\"Hello\"]", globals));
    }
}

Stacktrace

[System.InvalidOperationException: Sequence contains no matching element]
   at System.Linq.Enumerable.First[TSource](IEnumerable`1 source, Func`2 predicate)
   at .DynamicIndex(Object obj, Object[] parameters)
   at lambda_method(Closure , Object )
   at Z.Expressions.EvalContext.Execute[TResult](String code, Object parameters)
   at Z.Expressions.Eval.Execute[TResult](String code, Object parameters)
   at Program.Main() :line 50

The code above is available as fiddle

JonathanMagnan commented 3 years ago

Hello @marcOcram

Thank you for reporting, my developer will look at it.

Best Regards,

Jon

JonathanMagnan commented 3 years ago

Hello @marcOcram ,

The v4.0.24 has been released.

Could you try it and let us know if everything is now fixed with your scenario?

Best Regards,

Jon

marcOcram commented 3 years ago

Hello @JonathanMagnan ,

that works. Thank you.

JonathanMagnan commented 3 years ago

Awesome @marcOcram !

Don't hesitate to contact us with any questions, issues or feedback.

Best regards,

Jon