1

I'm using Dynamic Expresso for expression evaluation and works like a charm. Actually setting up custom functions, but seems like there is a something wrong with a method overload.

I've actually got two Round methods:

First one with one argument:

public static decimal Round(decimal userNumber)
{
    return Math.Round(userNumber);
}

Second one with two arguments:

public static decimal Round(decimal userNumber, int decimals)
{
    return Math.Round(userNumber, decimals);
}

Delegates got declared and Interpreter.SetFunction is called with no errors as well:

Func<decimal, decimal> roundFunction1 = (userNumber) => Round(userNumber);
Func<decimal, int, decimal> roundFunction2 = (userNumber, decimals) => Round(userNumber, decimals);

interpreter.SetFunction("ROUND", roundFunction1);
interpreter.SetFunction("ROUND", roundFunction2);

Variables are correctly passed and I've checked many times already that the parameter I'm passing is, in fact, a decimal.

The evaluation expression I pass, finally contains the following string, which has nothing wrong since the Interpreter.SetVariable(property.Key, property.Value) is inserting an "ImporteTotal" and a 666.66:

ROUND(ImporteTotal)

So, the exception I get when the evaluation gets done is:

Argument list incompatible with delegate expression (at index 0).

Note that I'm actually setting lots of functions which uses even DateTimes, int, strings and so on even combined, overloads as well! All of them work perfectly, but seems that deleting any of those overloads helps it working. In case both of them are "imported" on Dynamic Expresso, it complains.

Any ideas?

Many thanks.

UPDATE-EDIT:

I reviewed the UnitTesting Davide provided through pastebin and seems I got it failing.

This unit testing seems that is failing.

[Test]
public static void TestInterpreter()
{
    var interpreter = new Interpreter();

    Func<decimal, decimal> roundFunction1 = (userNumber) => Round(userNumber);
    Func<decimal, int, decimal> roundFunction2 = (userNumber, decimals) => Round(userNumber, decimals);
    Func<string, string, int> charindexFunction1 = (toFind, userString) => Charindex(toFind, userString);
    Func<string, string, int, int> charindexFunction2 = (toFind, userString, offset) => Charindex(toFind, userString, offset);

    interpreter.SetFunction("ROUND", roundFunction1);
    interpreter.SetFunction("ROUND", roundFunction2);
    interpreter.SetFunction("CHARINDEX", charindexFunction1);
    interpreter.SetFunction("CHARINDEX", charindexFunction2);

    var importe = 666.66M;
    interpreter.SetVariable("ImporteTotal", importe);

    var textoAlbaran = "ALBARAN-01";
    interpreter.SetVariable("Albaran", textoAlbaran);

    Assert.AreEqual(Round(importe), interpreter.Eval("ROUND(ImporteTotal)"));
    Assert.AreEqual(Round(importe, 1), interpreter.Eval("ROUND(ImporteTotal, 1)"));
    Assert.AreEqual(Charindex("BARAN", textoAlbaran), interpreter.Eval("CHARINDEX(\"BARAN\", Albaran"));
    Assert.AreEqual(Charindex("BARAN", textoAlbaran, 2), interpreter.Eval("CHARINDEX(\"BARAN\", Albaran, 2)"));
}

public static decimal Round(decimal userNumber)
{
    return Math.Round(userNumber);
}

public static decimal Round(decimal userNumber, int decimals)
{
    return Math.Round(userNumber, decimals);
}

public static int Charindex(string toFind, string userString)
{
    return userString.IndexOf(toFind);
}

public static int Charindex(string toFind, string userString, int offset)
{
    return userString.IndexOf(toFind, offset);
}
Gonzo345
  • 1,133
  • 3
  • 20
  • 42
  • 1
    Can you also provide the stack trace of the exception? Eventually can you try to create an unit test with steps to reproduce this error in a "clean" environment? thanks – Davide Icardi Jun 22 '18 at 14:40
  • 1
    I have tried to reproduce your problem without success. Here my code: [pastebin](https://pastebin.com/pgDbZS7K). I suggest you to try to write a similar code to reproduce your issue. – Davide Icardi Jun 29 '18 at 20:52
  • @DavideIcardi I’m so sorry for the delay. Crazy days here. I haven’t forget about this but I wanted to give you a proper response. Thank you so much, I will give it a try and will update the question with more info evwn after looking at your code. Thank you Davide. – Gonzo345 Jun 29 '18 at 20:54
  • @DavideIcardi I've updated the question with the UnitTesting I'm applying where it fails. Hope it helps. Curiously I've detected something weird happening with the `Charindex` methods as well. Maybe it's too foggy for me at this point, but I can't handle to see what's really happening here. Thank you so much in advance and congratulations for the engine. – Gonzo345 Jul 02 '18 at 12:48
  • 1
    Thanks for the info. I have created an [issue on Github](https://github.com/davideicardi/DynamicExpresso/issues/81). I will try to investigate it soon ... Sorry for the problem. – Davide Icardi Jul 03 '18 at 10:10
  • Sorry? No way! Thank you for caring! – Gonzo345 Jul 03 '18 at 10:17
  • 1
    See https://github.com/davideicardi/DynamicExpresso/issues/81#issuecomment-402571682 – Davide Icardi Jul 04 '18 at 23:32

1 Answers1

1

Starting with DynamicExpresso 2.5.0, it's possible to register multiple methods with the same name (ie. overloads):

Func<decimal, decimal> roundFunction1 = (userNumber) => Math.Round(userNumber);
Func<decimal, int, decimal> roundFunction2 = (userNumber, decimals) => Math.Round(userNumber, decimals);

var interpreter = new Interpreter();
interpreter.SetFunction("ROUND", roundFunction1);
interpreter.SetFunction("ROUND", roundFunction2);

Assert.AreEqual(3.13M, interpreter.Eval("ROUND(3.12789M, 2)"));
Assert.AreEqual(3M, interpreter.Eval("ROUND(3.12789M)"));
Métoule
  • 13,062
  • 2
  • 56
  • 84