ExpressionPromoter.Promote Limitations to Detect plausible method matches
Hi,
I am highlighting one constraint/issue which is little annoying and could be improved upon.
When I use String.Join method below are the possible overloads which can be called.
+ [0] {System.String Join(System.String, System.String[])}
+ [1] {System.String Join(System.String, System.Object[])}
+ [2] {System.String Join(System.String, System.Collections.Generic.IEnumerable`1[System.String])}
+ [3] {System.String Join(System.String, System.String[], Int32, Int32)}
+ [4] {System.String Join[T](System.String, System.Collections.Generic.IEnumerable`1[T])}
Now in ExpressionPromoter.Promote class of your lib the type match is exact for IEnumerable types.
For example below are the two types, one for string enumerable and another one is int enumerable obj.
{Name = "IEnumerable`1" FullName = "System.Collections.Generic.IEnumerable`1[[System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]"}
{Name = "IEnumerable`1" FullName = "System.Collections.Generic.IEnumerable`1[[System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]"}
So ExpressionPromoter.Promote returns the expression for string enumerable but for int enumerable it returns null, due to which we get an error saying no method Join found.
Whereas normally(in c#) when we use int enumerable obj with string.Join it works perfectly, probably because it's matching with the below two types.
+ [1] {System.String Join(System.String, System.Object[])}
+ [4] {System.String Join[T](System.String, System.Collections.Generic.IEnumerable`1[T])}
I would like to know if in your lib can you please make your best method search approach to be more wider which can detect generic methods too? String.Join is just an example, this change can be very useful for many methods.
Code to reproduce the issue:
Works
var strArray = new[] { "1","2","3","4"};
var x = new List<ParameterExpression>();
x.Add(Expression.Parameter(strArray.GetType(), "strArray"));
var config = new ParsingConfig();
string query = "string.Join(\",\" , strArray)";
var e = DynamicExpressionParser.ParseLambda(config, x.ToArray(), null, query);
Delegate del = e.Compile();
var result = del.DynamicInvoke(strArray);
Doesn't Work
var intArray = new[] { 1,2,3,4};
var x = new List<ParameterExpression>();
x.Add(Expression.Parameter(intArray.GetType(), "intArray"));
var config = new ParsingConfig();
string query = "string.Join(\",\" , intArray)";
var e = DynamicExpressionParser.ParseLambda(config, x.ToArray(), null, query);
Delegate del = e.Compile();
var result = del.DynamicInvoke(intArray);
Thanks!
Hello @joshidp ,
Thank you for reporting,
We will look at it probably this weekend.
Best Regards,
Jon
Performance Libraries
context.BulkInsert(list, options => options.BatchSize = 1000);
Entity Framework Extensions • Entity Framework Classic • Bulk Operations • Dapper Plus
Runtime Evaluation
Eval.Execute("x + y", new {x = 1, y = 2}); // return 3
C# Eval Function • SQL Eval Function
Hello @joshidp ,
We looked at this issue and in the short term, I don't think we will improve the method overload resolution. Way too much code is involved to make it works or improve it. A major code revamps would be required which will come without a doubt a major version if we do it.
If we want to make it works correctly, we will have to bring back the method overload resolution we did in our other library (C# Eval Expression) which took us weeks to make it works (and still is not 100% perfect but close enough).
So, if you wish a better method resolution, I recommend you to try https://eval-expression.net/ (free for LINQ part). Otherwise, I don't think anything will be done in short term.
Best Regards,
Jon
Performance Libraries
context.BulkInsert(list, options => options.BatchSize = 1000);
Entity Framework Extensions • Entity Framework Classic • Bulk Operations • Dapper Plus
Runtime Evaluation
Eval.Execute("x + y", new {x = 1, y = 2}); // return 3
C# Eval Function • SQL Eval Function
https://github.com/zzzprojects/System.Linq.Dynamic.Core/pull/731