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

Enum variable with the same name as its type gives null reference exception #16

Closed efronberlian closed 6 years ago

efronberlian commented 6 years ago

I have a problem with naming enums with the same name as its type, The code below runs well as long as you don't have the variable SomeEnum. I put the comment on which line should be commented.


    public enum SomeEnum
    {
        A, B, C, D, E
    }

    public class Entity
    {
        // Commenting Variable SomeEnum will get rid of the runtime error
        public SomeEnum SomeEnum;
        public SomeEnum TheEnum;

        public Entity(SomeEnum someEnum)
        {
            TheEnum = someEnum;
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            var evalContext = new EvalContext();
            evalContext.BindingFlags = BindingFlags.IgnoreCase | evalContext.BindingFlags;

            evalContext.RegisterType(typeof(Entity));
            evalContext.RegisterType(typeof(SomeEnum));

            var hasSomeEnumA = evalContext.Compile<Func<Entity, bool>>("entity?.TheEnum == SomeEnum.A", "entity");

            var enumValues = Enum.GetValues(typeof(SomeEnum)).Cast<SomeEnum>();
            var entities = enumValues.Select(anEnum => new Entity(anEnum)).ToList();

            foreach (var entity in entities)
            {
                Console.WriteLine(hasSomeEnumA(entity));
            }
        }
    }

Here's the error:

Unhandled Exception: System.NullReferenceException: Object reference not set to an instance of an object.
   at ..(ExpressionScope ,  , Expression , Expression , Func`3 )
   at ..(ExpressionScope ,  , Func`3 )
   at Z.Expressions.CodeCompiler.CSharp.Compiler.(ExpressionScope ,  , Expression , Boolean )
   at Z.Expressions.CodeCompiler.CSharp.Compiler.(ExpressionScope ,  , Expression , Boolean )
   at Z.Expressions.CodeCompiler.CSharp.Compiler.(ExpressionScope ,  , Expression , Boolean )
   at ..(Type , ExpressionScope ,  )
   at Z.Expressions.EvalCompiler.Compile[TDelegate](EvalContext context, String code, IDictionary`2 parameterTypes, Type resultType, EvalCompilerParameterKind parameterKind, Boolean forceFirstParameterProperty)
   at Z.Expressions.EvalContext.Compile[TDelegate](String code, String[] parameterNames)
   at ConsoleApp4.Program.Main(String[] args) in C:\Projects\ConsoleApp4\ConsoleApp4\Program.cs:line 42
JonathanMagnan commented 6 years ago

Hello @efronberlian ,

Thank you for reporting.

This problem is due because by default, the library allow to directly reference property from the entity.

By example

evalContext.Compile<Func<Entity, bool>>("entity?.TheEnum == SomeEnum", "entity");

is equivalent to

evalContext.Compile<Func<Entity, bool>>("entity?.TheEnum == entity.SomeEnum", "entity");

We will look how we can fix it today or tomorrow.

Best Regards,

Jonathan

efronberlian commented 6 years ago

Ahh I see. So the compiler thinks tht 'SomeEnum.A' means 'entity.SomeEnum.A' instead of referencing the enum class. That looks like a tricky problem.

Thank you so much for replying so soon. I am currently using Eval-Expressions in the project that I am working on and it's working great. Keep up the good work! :)

JonathanMagnan commented 6 years ago

Yup, it was a little bit tricky to fix but I believe we did it.

The v2.4.3 has been released: https://www.nuget.org/packages/Z.Expressions.Eval/

Let me know if your scenario is now working correctly.

Best Regards,

Jonathan

efronberlian commented 6 years ago

It works perfectly. Thanks for the help!