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

New Post: Cannot use Linq Where and Select Extension Methods

0
0
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 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)));
    }
}
Then you could do this:
engine.AddHostType("ScriptWhere", typeof(ScriptWhere));
engine.Execute(@"
    result = uow.Projects.Where(function (w) { return w.Id == 100; }).ToList();
");
For 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));
    }
}
And then:
engine.AddHostType("ScriptSelect", typeof(ScriptSelect));
engine.AddHostType("Int32", typeof(int));
engine.Execute(@"
    result = uow.Projects.Select(Int32, function (w) { return w.Id; }).ToList();
");
We haven't explored all the possibilities; there are just a few ideas.

Good luck!

Viewing all articles
Browse latest Browse all 2297