Running List ForEach using script

Jan 5, 2014 at 11:31 AM
Edited Jan 5, 2014 at 11:33 AM
I have an existing List<string> which is passed into the engine as an object.
engine.AddObject("Datas", datas);
This is the script that i want to execute
Datas.ForEach(function(d){
//read the string here
});
When i try to execute the it using a function, it throws an error "The best overloaded match for List<string>.ForEach(System.Action<string>) has some invalid arguments".

I guess that the javascript function is not transform into C# Action?
Coordinator
Jan 5, 2014 at 1:42 PM
Greetings!

I guess that the javascript function is not transform into C# Action?

Not automatically. ClearScript provides C#-like type inference, where method overloads are selected according to the argument types. Script functions are not strongly typed, and that presents a problem. To create a callback into script code, you must therefore specify the callback type:
engine.AddHostObject("Datas", new List<string> { "foo", "bar", "baz" });
engine.AddHostType("Callback", typeof(Action<string>));
engine.AddHostType("Console", typeof(Console));
engine.Execute(@"
    Datas.ForEach(new Callback(function(d) {
        Console.WriteLine(d);
    }))
");
Good luck!
Coordinator
Jan 5, 2014 at 1:58 PM
By the way, for a more generic and transparent solution, you could expose a helper class that provides script-specific list extensions:
public static class ListExtensions {
    public static void ForEach<T>(this List<T> list, dynamic function) {
        list.ForEach(item => function(item));
    }
}
and then:
engine.AddHostType("ListExtensions", typeof(ListExtensions));
engine.AddHostType("Console", typeof(Console));
engine.AddHostObject("Datas", new List<string> { "foo", "bar", "baz" });
engine.Execute(@"
    Datas.ForEach(function(d) {
        Console.WriteLine(d);
    })
");
Cheers!
Marked as answer by ravetam on 1/5/2014 at 7:51 AM
Jan 5, 2014 at 3:57 PM
Thank a lot! The extension method works!
Apr 28, 2014 at 11:49 AM
Edited Apr 28, 2014 at 11:50 AM
Based on your ListExtensions class I've created a slightly modified one:
public static class ListExtensions
{
    public static void forEach<T>(this IEnumerable<T> list, dynamic function)
    {
        list.ToList().ForEach(item => function(item));
    }
}
This mimics the JavaScript forEach function for native arrays (at least to some degree) and in addition works both for .NET lists and .NET arrays.
May 3, 2014 at 6:56 AM
This is what i come out with in the end
public static void forEach(this IEnumerable collection, dynamic action)
        {
            int i = 0;
            foreach (var item in collection)
            {
                action(item, i, collection);
                i++;
            }
        }