Hi again,
Unfortunately ambiguity prevents automatic conversion of script functions to delegates, especially when generics are involved.
For example, examining a JavaScript function gets us, at best, a parameter count, and while that might be enough to select the correct overload of
However, there are things you can do to make LINQ easier for script code to use. For example, instead of exposing the standard
Then you could do this:
For
And then:
We haven't explored all the possibilities; there are just a few ideas.
Good luck!
Unfortunately ambiguity prevents automatic conversion of script functions to delegates, especially when generics are involved.
For example, examining a JavaScript function gets us, at best, a parameter count, and while that might be enough to select the correct overload of
Where()
, it can't help us bind to the intended specialization of something like Select()
, where the delegate's return type plays a critical role in finding the right method. To invoke Select()
successfully we must either have explicit type arguments or a strongly-typed delegate; lacking both it's just not possible.However, there are things you can do to make LINQ easier for script code to use. For example, instead of exposing the standard
Enumerable
class, consider exposing your own extensions that are specifically designed for script code:publicstaticclass ScriptWhere { publicstatic IEnumerable<T> Where<T>(this IEnumerable<T> source, dynamic predicate) { return source.Where(item => Convert.ToBoolean(predicate(item))); } }
engine.AddHostType("ScriptWhere", typeof(ScriptWhere)); engine.Execute(@" result = uow.Projects.Where(function (w) { return w.Id == 100; }).ToList(); ");
Select()
you can't get around having to specify the target type, but you could still make script code a bit happier:publicstaticclass ScriptSelect { publicstatic IEnumerable<T> Select<T>(this IEnumerable<object> source, dynamic selector) { return source.Select(item => (T)selector(item)); } }
engine.AddHostType("ScriptSelect", typeof(ScriptSelect)); engine.AddHostType("Int32", typeof(int)); engine.Execute(@" result = uow.Projects.Select(Int32, function (w) { return w.Id; }).ToList(); ");
Good luck!