Можно ли использовать «javascript точка нотации» в JINT со словарем <строка, объект> - PullRequest
1 голос
/ 15 февраля 2012

У меня есть набор команд JavaScript, таких как doc.page == 5, и я использую JINT для выполнения скриптов в моем приложении C #.

Однако в моем коде C # doc - это Dictionary<string, object>.Поэтому я не могу использовать точечную нотацию таким образом.

Мое текущее решение ужасно неэффективно: я конвертирую doc в строку JSON и добавляю это в свой скрипт.Dictionary очень большой, так что это НАМНОГО больше, чем выполнение простой команды.Вот пример кода:

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

Есть ли способ сделать это более эффективно?

1 Ответ

1 голос
/ 15 февраля 2012

Возможно, вы могли бы использовать 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);
    }
}
...