C# 3.5 DLR Expression.Dynamic 问题

标签 c# .net-3.5 lambda dynamic-language-runtime

我继承了一种小型脚本语言,我正在尝试将其移植到 DLR,以便更易于管理。到目前为止,一切都相当简单。我在尝试动态调用变量成员时遇到了问题。当前的语言在 .NET 上运行并使用解析循环和反射来执行此操作,但我希望摆脱它。这是脚本语言的示例:

string $system1RemoteUri;
string $dbconnection = $config.GetDBConnection ("somedb");
float $minBad = 0.998;
float $minGood = 0.2;

$systen1RemoteURI、$minBad 和 $minGood 是将在脚本中设置的变量,以及 $dbconnection。但是 $dbconnection 将从传入的名为 $config 的变量中获取其值。这 4 个变量需要对调用者可用,因此它们被传递到 lambda 中,最初为 null。这是生成的 Lambda IL(调试 View ):

.Lambda #Lambda1<Delegate6$1>(
    System.String& $$system1RemoteUri,
    System.String& $$dbconnection,
    System.Double& $$minBad,
    System.Double& $$minGood
    System.Object $$config) {
    .Block() {
        $$minBad = 0.998D;
        $$minGood = 0.2D
    }

    //Some assignment similar to...
    //.Dynamic Call GetDBConnection($config, "somedb");
}

我想弄清楚的是如何使用 Expression.Dynamic 发出 $config.GetDBConnection("somedb")。通过查看 Sympl 库中的示例,我相信发出的 IL 应该如下所示: .Dynamic Call GetdbConnection($config, "somedb") 但我不知道如何从 Expression.Dynamic 实际发出它。

它似乎想要一个我无法正确创建的 CallSiteBinder,而且我不明白 Expression.Dynamic 的参数顺序是什么,因为它似乎只想要调用“成员”,而不是基础。

我不知道 $config 的运行时类型,它只是一些实现名为 GetDBConnection(string) 的函数的对象。这不是由接口(interface)或基类提供的。

如有任何帮助,我们将不胜感激。

最佳答案

您可以将其转换为 InvokeMemberBinder 或将“$config.GetDBConnection”转换为 GetMember,然后对将 $someDb 作为参数传递的结果执行调用。

要实现您的 GetMemberBinder 和 InvokeMemberBinder,您可以使用 DLR 外层 DefaultBinder 类。在最新的 IronPython/IronRuby 源代码中,您可以凭空创建一个新的 DefaultBinder 实例。然后在您的 FallbackGetMember/FallbackInvoke 中,您可以调用 defaultBinder.GetMember(...) 和 defaultBinder.Call(应重命名为 Invoke)。这将为您处理大多数 .NET 类型。此外,所有实现 IDynamicMetaObjectProvider 的对象也将使用它。对于其他动态操作,您可以在默认 Binder 上使用其他方法。如果你想开始自定义你的重载解决方案和绑定(bind)规则,它有很多你可以转动的旋钮。

不幸的是,默认绑定(bind)器现在没有 InvokeMemberBinder 实现,因此您最好使用 GetMember/Invoke。

关于C# 3.5 DLR Expression.Dynamic 问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2135533/

相关文章:

c# - &lt;script&gt;...&lt;/script&gt; 在转发器控制代码中未显示在页面呈现的源代码中

c# - 使用 C# 和 .NET 从集会下载附件

c# - onClick 和 onClientClick 事件一起使用。不适用于 Internet Explorer

c# - 将数组拆分为大小有限的 CSV 字符串

c# - 有没有办法限制谁可以继承类或接口(interface)?

lambda - 柯里化(Currying)只是 "optional parameters"?

java - NullPointerException 而不是 null(JVM 错误?)

c# - 通过任务取消窗口关闭。如何检测任务是否同步返回?

.net-3.5 - 支持 .Net 3.5 的 StructureMap 最新版本是什么?

c++ - 在 C++ 中推断 lambda 的模板类型