dynamicexpresso / DynamicExpresso

C# expressions interpreter
http://dynamic-expresso.azurewebsites.net/
MIT License
1.91k stars 364 forks source link

Unknown identifier IDictionary #264

Closed rob53twenty closed 1 year ago

rob53twenty commented 1 year ago

I am trying to get dynamic expresso to interpret this line of code:

(((IDictionary<string, object>)o)["Diesel % in oil"].ToString().StartsWith("<") ? ((IDictionary<string, object>)o)["Diesel % in oil"].ToString().Replace("<", String.Empty) : ((IDictionary<string, object>)o)["Diesel % in oil"].ToString())

When it executes I get the following exception Unknown identifier 'IDictionary' (at index 3).

I am testing for a "<" at the start and then replacing all instances of the "<" (excuse the terrible key name - out of my control that one!).

I have tried adding typeof(System.Collections.Generic.IDictionary<string, object>) as a reference to the interpreter object, but no joy.

The full code:

    var interpreter = new Interpreter();
    interpreter.Reference(typeof(System.Collections.Generic.IDictionary<string, object>));
    interpreter.SetVariable("o", o);
    return (T)interpreter.Eval(code);

I'm sure I'm missing something simple.

davideicardi commented 1 year ago

Can you try instead with this code

o["Diesel % in oil"].ToString().StartsWith("<") ? o["Diesel % in oil"].ToString().Replace("<", String.Empty) : o["Diesel % in oil"].ToString()

?

And configuring interpreter with:

    var interpreter = new Interpreter();
    interpreter.SetVariable("o", o, , typeof(IDictionary<string, object>));
    return (T)interpreter.Eval(code);

If still doesn't work can you try to reproduce the bug with an unit test similar to the one that we already have in the source code?

metoule commented 1 year ago

For generics, the reference type must be the generic type definition:

interpreter.Reference(typeof(System.Collections.Generic.IDictionary<,>));
metoule commented 1 year ago

I've opened a PR to throw an exception when trying to register a generic type that's not a type definition.

rob53twenty commented 1 year ago

Thank you @davideicardi & @metoule, a combination of them both has worked.

For reference, the working solution was:

string code = "o[\"Diesel % in oil\"].ToString().StartsWith(\"<\") ? o[\"Diesel % in oil\"].ToString().Replace(\"<\", String.Empty) : o[\"Diesel % in oil\"].ToString()";
var interpreter = new Interpreter();
interpreter.Reference(typeof(System.Collections.Generic.IDictionary<,>));
interpreter.SetVariable("o", o, typeof(IDictionary<string, object>));
return (T)interpreter.Eval(code);