是否可以使用“javascript 点表示法”在带有 Dictionary的 JINT 中;

发布于 2025-01-05 22:55:51 字数 1033 浏览 0 评论 0原文

我有一组 JavaScript 命令,例如 doc.page == 5,并且我正在使用 JINT 在我的 C# 应用程序中执行脚本。

但是,在我的 C# 代码中,doc 是一个 Dictionary。因此,我不能以这种方式使用点表示法。

我当前的解决方案效率非常低:我将 doc 转换为 JSON 字符串,并将其添加到我的脚本中。字典非常大,因此这比执行简单命令的开销要大得多。这是一些示例代码:

// Some example data:
var command = "doc.page < 5 || doc.tax < 10 || doc.efile";
var doc = new Dictionary<string, object>(){
    {"page", 5},
    {"tax", 10},
    {"efile", true},
    // ... etc ...
};

// Execute the command:

// Convert Dictionary to JSON:
var jsonDoc = new StringBuilder();
jsonDoc.Append("var doc = {");
var first = true;
foreach (var kv in doc) {
    if (!first) {
        jsonDoc.Append(",");
    }
    first = false;

    jsonDoc.AppendFormat("{0}: {1}", kv.Key, kv.Value);
}
jsonDoc.Append("};");

var je = new JintEngine();
je.Run(jsonDoc.ToString());

var result = je.Run(command);
return result;

有什么方法可以更有效地做到这一点吗?

I have a set of JavaScript commands, such as doc.page == 5, and I'm using JINT to execute the scripts within my C# application.

However, in my C# code, doc is a Dictionary<string, object>. Therefore, I cannot use dot-notation in this way.

My current solution is terribly inefficient: I convert doc into a JSON string, and add that to my script. The Dictionary is very large, so this has WAY more overhead than executing the simple command. Here's some example code:

// Some example data:
var command = "doc.page < 5 || doc.tax < 10 || doc.efile";
var doc = new Dictionary<string, object>(){
    {"page", 5},
    {"tax", 10},
    {"efile", true},
    // ... etc ...
};

// Execute the command:

// Convert Dictionary to JSON:
var jsonDoc = new StringBuilder();
jsonDoc.Append("var doc = {");
var first = true;
foreach (var kv in doc) {
    if (!first) {
        jsonDoc.Append(",");
    }
    first = false;

    jsonDoc.AppendFormat("{0}: {1}", kv.Key, kv.Value);
}
jsonDoc.Append("};");

var je = new JintEngine();
je.Run(jsonDoc.ToString());

var result = je.Run(command);
return result;

Is there any way to do this more efficiently?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

东京女 2025-01-12 22:55:51

也许您可以利用dynamic来允许点符号语法进入字典。我还没有用 JINT 进行过测试,但我认为它会起作用。

下面是一个基于 DynamicObject 包装字典的示例(忽略了某些类型安全性,但您了解了总体思路:-))。您应该能够调整它以与 JINT 一起使用。

void Main()
{
    var values = new Dictionary<string,object> { 
        { "x", 5 }, { "Foo", "Bar" }
    };

    dynamic expando = new ExpandoDictionary(values);

    // We can lookup members in the dictionary by using dot notation on the dynamic expando
    Console.WriteLine(expando.x);
    // And assign new "members"
    expando.y = 42;
    expando.Bar = DateTime.Now;
    // The value set is in the dictionary
    Console.WriteLine(values["Bar"]);
}

public class ExpandoDictionary : DynamicObject 
{
    private readonly Dictionary<string,object> inner;

    public ExpandoDictionary(Dictionary<string,object> inner)
    {
        this.inner = inner;
    }

    public override bool TrySetMember(SetMemberBinder binder, object value) 
    {
        inner[binder.Name] = value;
        return true;
    }

    public override bool TryGetMember(GetMemberBinder binder, out object value) 
    {
        return inner.TryGetValue(binder.Name, out value);
    }
}

Perhaps you could utilize dynamic to allow the dot notation syntax into the dictionary. I haven't tested with JINT, but I think it would work.

Here is an example of wrapping a Dictionary based on DynamicObject (some type safety ignored, but you get the general idea :-)). You should be able to adapt this to work with JINT.

void Main()
{
    var values = new Dictionary<string,object> { 
        { "x", 5 }, { "Foo", "Bar" }
    };

    dynamic expando = new ExpandoDictionary(values);

    // We can lookup members in the dictionary by using dot notation on the dynamic expando
    Console.WriteLine(expando.x);
    // And assign new "members"
    expando.y = 42;
    expando.Bar = DateTime.Now;
    // The value set is in the dictionary
    Console.WriteLine(values["Bar"]);
}

public class ExpandoDictionary : DynamicObject 
{
    private readonly Dictionary<string,object> inner;

    public ExpandoDictionary(Dictionary<string,object> inner)
    {
        this.inner = inner;
    }

    public override bool TrySetMember(SetMemberBinder binder, object value) 
    {
        inner[binder.Name] = value;
        return true;
    }

    public override bool TryGetMember(GetMemberBinder binder, out object value) 
    {
        return inner.TryGetValue(binder.Name, out value);
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文