This project has moved and is read-only. For the latest updates, please go here.

(NET 3.5) Passing a registered type to a function

Nov 23, 2014 at 6:14 AM
Hi! I'm trying to utilize this library with Unity and so far it is working great!

I have come across a strange issue though. I've registered two items with the expression, both instances of classes. One, the player. Another, the current dialog node.

The expression: "player.Test(dialog)"

The error:
InvalidCastException: Cannot cast from source type to destination type.
ExpressionEvaluator.Parser.Parse (Boolean isScope)
Rethrow as Exception: Parser error at position 18: Cannot cast from source type to destination type.
ExpressionEvaluator.Parser.Parse (Boolean isScope)
ExpressionEvaluator.Parser.BuildTree (System.Linq.Expressions.Expression scopeParam)
ExpressionEvaluator.ExpressionCompiler.BuildTree (System.Linq.Expressions.Expression scopeParam)
ExpressionEvaluator.CompiledExpression.Compile ()
ExpressionEvaluator.CompiledExpression.Eval ()
Relevant registration calls, modified slightly for better copy/paste:
expr.RegisterType("player", Player.Instance);
expr.RegisterType("dialog", Dialog.Instance);
Relevant "Test" method, defined on Player:
public string Test(object p) {
  Debug.Log(p);

  return "";
}
I suppose it is a good time to also mention that Void methods throw an error in this version, so I have to force it to return a string! Not as big of a deal though.

Any thoughts?
May 16, 2015 at 1:40 AM
I'm so sorry for not answering this sooner.

The problem was most probably caused by the fact that you were passing some type into a parameter of type Object. It's given that all types inherit from type Object, but in the CLR, there is actually some type conversion going on so that types actually match. The C# compiler probably automatically does the implicit type conversion to type Object, and in previous versions I was not handling implicit type conversion properly.

The latest version 2.0.3 can do some type conversion, and the above code should work properly like so:
            var player = new Player();
            var dialog = new Dialog();

            var t = new TypeRegistry();
            t.RegisterSymbol("player", player);
            t.RegisterSymbol("dialog", dialog);

            var ce1 = new CompiledExpression() { StringToParse = "player.Test(dialog)", TypeRegistry = t };
            ce1.Eval();
Void methods are also supported, and Test can be declared void, as long as the CompiledExpression is of type object.

Otherwise, in the old version you might have gotten away with casting dialog to type object explicitly in your expression.