Quantcast
Channel: ClearScript
Viewing all articles
Browse latest Browse all 2297

New Post: access indexer of a hosted object

0
0
Hi krisoye,

How about something like this:
publicclass Map : DynamicObject, IEnumerable {
    privatereadonly IDictionary<string, object> dict = new Dictionary<string, object>();
    private IList list;
    publicvoid Add(string key, object value) {
        dict.Add(key, value);
        list = null;
    }
    publicoverride IEnumerable<string> GetDynamicMemberNames() {
        foreach (var name in dict.Keys) {
            yieldreturn name;
        }
        foreach (var index in Enumerable.Range(0, dict.Count())) {
            yieldreturn index.ToString(CultureInfo.InvariantCulture);
        }
    }
    publicoverridebool TryGetMember(GetMemberBinder binder, outobject result) {
        var name = binder.Name;
        var found = dict.TryGetValue(name, out result);
        if (!found) {
            int index;
            if (int.TryParse(name, out index) && (index >= 0) && (index < dict.Count())) {
                if (list == null) {
                    list = dict.ToList();
                }
                result = list[index];
                found = true;
            }
        }
        return found;
    }
    public IEnumerator GetEnumerator() {
        return dict.GetEnumerator();
    }
}
Here's a usage sample:
engine.Script.map = new Map { { "foo", 123 }, { "bar", 456 }, { "baz", 789 } };
engine.AddHostType("Console", typeof(Console));
engine.Execute(@"
    Console.WriteLine(map[0].Key);  // foo
    Console.WriteLine(map[1].Key);  // bar
    Console.WriteLine(map[2].Key);  // baz
    Console.WriteLine(map['foo']);  // 123
    Console.WriteLine(map['bar']);  // 456
    Console.WriteLine(map['baz']);  // 789
");
The trick is to expose the indices as property names.

Good luck!

Viewing all articles
Browse latest Browse all 2297