This project has moved and is read-only. For the latest updates, please go here.

Problem with C# enumerables (generic, arrays, whatever) with vbscript

Mar 19, 2014 at 6:59 PM
Edited Mar 19, 2014 at 6:59 PM
I have a List<ISomeInterface> in c# that I am trying to work with in vbscript.

While I can access some methods of the list (Count seems to work), I cannot enumerate it, no matter what I seem to try.

I have attempted For Each, but the list is not seen as a container so that fails.
I have attempted indexing like so
  For i = 0 to someList.Count
     myLog.Info "Name: " & someList.ElementAt(i).Name
  Next
which fails, 'ElementAt' is not recognized "Object doesn't support this property or method"

someList[i] fails with "expected end of statement" (apparently invalid vbscript)
someList(i) fails with the "Object doesnt support this property or method" (not unexpected)

I read the discussion on dealing with arrays in vbscript here https://clearscript.codeplex.com/discussions/539210

and see my comment about ElementAt above. Also, I tried exporting the list as an array instead, and that had simmilar issues.

Here is how I am calling it... Please note that I must use .Execute and not .Evaluate
         using (ScriptEngine engine = new Microsoft.ClearScript.Windows.VBScriptEngine())
         {
            engine.AddHostObject("myLog", Logger.Instance);
            engine.AddHostObject("someList", someList);

            try
            {
               engine.Execute(scriptText_);
            }
            catch (ScriptEngineException sce)
            {
               Log.Error("The Script threw an exception.  Details: {0}", sce.Format());
               return false;
            }
         }
Any help would be appreciated.
Coordinator
Mar 19, 2014 at 7:27 PM
Greetings!

The List class has an indexed property named "Item". This property is exposed as a C# indexer, but you can use it from script in its true form:
engine.AddHostObject("list", new List<string> { "abc", "def", "ghi", "jkl" });
engine.AddHostType("Console", typeof(Console));
engine.Execute(@"
    for i = 0 to list.Count - 1
        Console.WriteLine list.Item(i)
    next
");
The ElementAt method is a LINQ extension. To use it, you must expose LINQ's Enumerable class:
engine.AddHostType("Enumerable", typeof(Enumerable));
engine.Execute(@"
    for i = 0 to list.Count - 1
        Console.WriteLine list.ElementAt(i)
    next
");
Another thing you can do is use a .NET enumerator:
engine.Execute(@"
    e = list.GetEnumerator()
    while e.MoveNext()
        Console.WriteLine e.Current
    wend
");
Good luck!
Mar 19, 2014 at 7:34 PM
Thank you, that has resolved it!