【问题标题】:DynamicExpresso.SetFunction not working with method overloadDynamicExpresso.SetFunction 不适用于方法重载
【发布时间】:2018-06-21 11:53:50
【问题描述】:

我正在使用Dynamic Expresso 进行表达式评估,并且工作起来就像一个魅力。实际设置自定义函数,但方法重载似乎有问题。

我实际上有两个Round 方法:

第一个有一个参数:

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

第二个有两个参数:

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

代表已被声明,Interpreter.SetFunction 也被正确调用:

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);

变量被正确传递,我已经检查了很多次,我传递的参数实际上是decimal

我通过的求值表达式,最后包含如下字符串,因为Interpreter.SetVariable(property.Key, property.Value)插入了"ImporteTotal"666.66,所以没有错:

ROUND(ImporteTotal)

所以,评估完成后我得到的异常是:

参数列表与委托表达式不兼容(在索引 0 处)。

请注意,我实际上设置了很多函数,它们甚至使用DateTimes、intstrings 等等,甚至组合起来,重载也是如此!它们都工作得很好,但似乎删除任何这些重载有助于它工作。如果它们都在 Dynamic Expresso 上“导入”,它会抱怨。

有什么想法吗?

非常感谢。

更新编辑:

我查看了 UnitTesting Davide provided through pastebin 并似乎失败了。

这个单元测试似乎失败了。

[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);
}

【问题讨论】:

  • 能否也提供异常的堆栈跟踪?最终,您能否尝试创建一个单元测试,其中包含在“干净”环境中重现此错误的步骤?谢谢
  • 我试图重现您的问题,但没有成功。这是我的代码:pastebin。我建议您尝试编写类似的代码来重现您的问题。
  • @DavideIcardi 很抱歉耽搁了。疯狂的日子在这里。我没有忘记这一点,但我想给你一个适当的回应。非常感谢,我会试一试,并在查看您的代码后用更多信息 evwn 更新问题。谢谢大卫。
  • 感谢您的信息。我创建了一个issue on Github。我会尽快对其进行调查...对不起这个问题。

标签: c# expression-evaluation dynamic-expresso


【解决方案1】:

DynamicExpresso 2.5.0开始,可以注册多个同名的方法(即重载):

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)"));

【讨论】:

  • 令人惊讶!非常感谢您的 PR,干得好!
猜你喜欢
  • 2013-03-26
  • 1970-01-01
  • 1970-01-01
  • 2015-06-21
  • 2016-05-05
  • 1970-01-01
  • 1970-01-01
  • 2017-10-04
  • 1970-01-01
相关资源
最近更新 更多