Open RonAmihai opened 9 months ago
Currently, as a temporary solution (until implementing proper dynamic LINQ support), I've solved that using LINQ extension methods for object
.
Then, by using the extensions below, one can define the interpreter as follows to enable dynamic LINQ functionality:
var interpreter = new Interpreter(InterpreterOptions.LateBindObject | InterpreterOptions.LambdaExpressions)
.Reference(typeof(DynamicLinqExtensions));
Notes:
LateBindObject
is required for nested dynamic fields support, not for the LINQ functionality.Cast
/ OfType
extensions (they are not mandatory for basic functionality since every operation performs cast to IEnumerable<object?>
internally).ThenBy
/ ThenByDescending
extensions, they are not mandatory. I've added them to avoid needing an additional typeof(Enumerable)
interpreter reference.data.nested.list.Where(...).ToHashSet().SetEquals(new T[] { ... } )
will require adding .AsEnumerable()
to the SetEquals
method parameter initialization (SetEquals
in that example is an instance method, not an extension method, and we cannot re-define it's behavior)Implementation:
It's worth noting that the C# compiler doesn't allow it either:
dynamic dynamicData = new ExpandoObject();
dynamicData.Some = new List<string> { "one", "two", "two", "three" };
var result = dynamicData.Some.Any(x => x == "two");
raises compiler error
error CS1977: Cannot use a lambda expression as an argument to a dynamically dispatched operation
without first casting it to a delegate or expression tree type.
If C# compiler doesn't allow this scenario, I think we can ignore it. @RonAmihai using ExpandoObject really necessary in your scenario? Maybe you can create some custom type. This will also improve performance and type safety.
@davideicardi I've ended up implementing an optimized custom expression tree compiler for my exact scenario (object with nested Dictionary<string, object>
).
I agree that ExpandoObject should be avoided in general. However, in cases where it can't be avoided, LINQ support can be an optional feature—not that mandatory, though.
LINQ extensions within expressions do not work when applied to properties of
ExpandoObject
. (For comparison - ExpressionEvaluator does support that with OptionInstanceMethodsCallActive)Given the following code:
The following exception is thrown: