diff --git a/System.Linq.Dynamic.Core.sln b/System.Linq.Dynamic.Core.sln
index 1cabb9fa..3e56b2bb 100644
--- a/System.Linq.Dynamic.Core.sln
+++ b/System.Linq.Dynamic.Core.sln
@@ -145,6 +145,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Linq.Dynamic.Core.Te
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WasmDynamicLinq", "src-blazor\WasmDynamicLinq\WasmDynamicLinq.csproj", "{2DE2052F-0A50-40C7-B6FF-52B52386BF9A}"
EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SldcTrimmer", "src-examples\SldcTrimmer\SldcTrimmer.csproj", "{7A31366C-DD98-41A3-A0C1-A97068BD9658}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -913,6 +915,22 @@ Global
{2DE2052F-0A50-40C7-B6FF-52B52386BF9A}.Release|x64.Build.0 = Release|Any CPU
{2DE2052F-0A50-40C7-B6FF-52B52386BF9A}.Release|x86.ActiveCfg = Release|Any CPU
{2DE2052F-0A50-40C7-B6FF-52B52386BF9A}.Release|x86.Build.0 = Release|Any CPU
+ {7A31366C-DD98-41A3-A0C1-A97068BD9658}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {7A31366C-DD98-41A3-A0C1-A97068BD9658}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {7A31366C-DD98-41A3-A0C1-A97068BD9658}.Debug|ARM.ActiveCfg = Debug|Any CPU
+ {7A31366C-DD98-41A3-A0C1-A97068BD9658}.Debug|ARM.Build.0 = Debug|Any CPU
+ {7A31366C-DD98-41A3-A0C1-A97068BD9658}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {7A31366C-DD98-41A3-A0C1-A97068BD9658}.Debug|x64.Build.0 = Debug|Any CPU
+ {7A31366C-DD98-41A3-A0C1-A97068BD9658}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {7A31366C-DD98-41A3-A0C1-A97068BD9658}.Debug|x86.Build.0 = Debug|Any CPU
+ {7A31366C-DD98-41A3-A0C1-A97068BD9658}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {7A31366C-DD98-41A3-A0C1-A97068BD9658}.Release|Any CPU.Build.0 = Release|Any CPU
+ {7A31366C-DD98-41A3-A0C1-A97068BD9658}.Release|ARM.ActiveCfg = Release|Any CPU
+ {7A31366C-DD98-41A3-A0C1-A97068BD9658}.Release|ARM.Build.0 = Release|Any CPU
+ {7A31366C-DD98-41A3-A0C1-A97068BD9658}.Release|x64.ActiveCfg = Release|Any CPU
+ {7A31366C-DD98-41A3-A0C1-A97068BD9658}.Release|x64.Build.0 = Release|Any CPU
+ {7A31366C-DD98-41A3-A0C1-A97068BD9658}.Release|x86.ActiveCfg = Release|Any CPU
+ {7A31366C-DD98-41A3-A0C1-A97068BD9658}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -965,6 +983,7 @@ Global
{B01B327C-FC68-49B6-BDE3-A13D0C66DF5C} = {7971CAEB-B9F2-416B-966D-2D697C4C1E62}
{7AFC2836-0F6E-4B0D-8BB3-13317A3B6616} = {8463ED7E-69FB-49AE-85CF-0791AFD98E38}
{2DE2052F-0A50-40C7-B6FF-52B52386BF9A} = {122BC4FA-7563-4E35-9D17-077F16F1629F}
+ {7A31366C-DD98-41A3-A0C1-A97068BD9658} = {BCA2A024-9032-4E56-A6C4-17A15D921728}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {94C56722-194E-4B8B-BC23-B3F754E89A20}
diff --git a/System.Linq.Dynamic.Core.sln.DotSettings b/System.Linq.Dynamic.Core.sln.DotSettings
index d5856118..766d5f30 100644
--- a/System.Linq.Dynamic.Core.sln.DotSettings
+++ b/System.Linq.Dynamic.Core.sln.DotSettings
@@ -3,6 +3,7 @@
IL
UTC
WASM
+ True
True
True
True
diff --git a/src-examples/SldcTrimmer/Color.cs b/src-examples/SldcTrimmer/Color.cs
new file mode 100644
index 00000000..19539daf
--- /dev/null
+++ b/src-examples/SldcTrimmer/Color.cs
@@ -0,0 +1,13 @@
+namespace SldcTrimmer
+{
+ internal class Color
+ {
+ public byte Alpha { get; set; }
+ public byte Red { get; set; }
+ public byte Green { get; set; }
+ public byte Blue { get; set; }
+ public float Hue { get; set; }
+ public float Saturation { get; set; }
+ public float Brightness { get; set; }
+ }
+}
diff --git a/src-examples/SldcTrimmer/LambdaExtensions.cs b/src-examples/SldcTrimmer/LambdaExtensions.cs
new file mode 100644
index 00000000..94e2f31f
--- /dev/null
+++ b/src-examples/SldcTrimmer/LambdaExtensions.cs
@@ -0,0 +1,13 @@
+using System;
+using System.Linq.Dynamic.Core;
+
+namespace SldcTrimmer
+{
+ internal static class LambdaExtensions
+ {
+ public static Func ParseLambda(this string expression)
+ {
+ return DynamicExpressionParser.ParseLambda(null, false, expression).Compile();
+ }
+ }
+}
diff --git a/src-examples/SldcTrimmer/Program.cs b/src-examples/SldcTrimmer/Program.cs
new file mode 100644
index 00000000..22870d18
--- /dev/null
+++ b/src-examples/SldcTrimmer/Program.cs
@@ -0,0 +1,32 @@
+using System;
+
+namespace SldcTrimmer
+{
+ class Program
+ {
+ static void Main(string[] args)
+ {
+ try
+ {
+ const string filterStr = "Alpha == 255";
+ Console.WriteLine(filterStr);
+
+ var filter = filterStr.ParseLambda();
+
+ var color1 = new Color { Alpha = 255 };
+ var value1 = filter(color1);
+ Console.WriteLine($"{color1.Alpha} -> {value1}");
+
+ var color2 = new Color { Alpha = 128 };
+ var value2 = filter(color2);
+ Console.WriteLine($"{color2.Alpha} -> {value2}");
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine(e.GetType());
+ Console.WriteLine(e.Message);
+ Console.WriteLine(e.StackTrace);
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src-examples/SldcTrimmer/Properties/PublishProfiles/FolderProfile.pubxml b/src-examples/SldcTrimmer/Properties/PublishProfiles/FolderProfile.pubxml
new file mode 100644
index 00000000..56392783
--- /dev/null
+++ b/src-examples/SldcTrimmer/Properties/PublishProfiles/FolderProfile.pubxml
@@ -0,0 +1,18 @@
+
+
+
+
+ Release
+ Any CPU
+ C:\temp\x
+ FileSystem
+ <_TargetId>Folder
+ net8.0
+ win-x64
+ true
+ true
+ true
+
+
\ No newline at end of file
diff --git a/src-examples/SldcTrimmer/SldcTrimmer.csproj b/src-examples/SldcTrimmer/SldcTrimmer.csproj
new file mode 100644
index 00000000..f50182f0
--- /dev/null
+++ b/src-examples/SldcTrimmer/SldcTrimmer.csproj
@@ -0,0 +1,22 @@
+
+
+
+ Exe
+ net8.0
+
+
+
+ true
+ full
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/System.Linq.Dynamic.Core/AnyOfTypes/AnyOfTypes.g.cs b/src/System.Linq.Dynamic.Core/AnyOfTypes/AnyOfTypes.g.cs
index 840b4ddd..62400494 100644
--- a/src/System.Linq.Dynamic.Core/AnyOfTypes/AnyOfTypes.g.cs
+++ b/src/System.Linq.Dynamic.Core/AnyOfTypes/AnyOfTypes.g.cs
@@ -11,6 +11,6 @@ namespace AnyOfTypes
{
internal enum AnyOfType
{
- Undefined = 0, First, Second, Third, Fourth, Fifth, Sixth, Seventh, Eighth, Ninth, Tenth
+ Undefined = 0, First, Second
}
}
\ No newline at end of file
diff --git a/src/System.Linq.Dynamic.Core/Compatibility/CodeAnalysis/DynamicallyAccessedMemberTypes.cs b/src/System.Linq.Dynamic.Core/Compatibility/CodeAnalysis/DynamicallyAccessedMemberTypes.cs
new file mode 100644
index 00000000..5b689575
--- /dev/null
+++ b/src/System.Linq.Dynamic.Core/Compatibility/CodeAnalysis/DynamicallyAccessedMemberTypes.cs
@@ -0,0 +1,79 @@
+#if !NET6_0_OR_GREATER
+
+// ReSharper disable once CheckNamespace
+namespace System.Diagnostics.CodeAnalysis;
+
+//
+// Summary:
+// Specifies the types of members that are dynamically accessed. This enumeration
+// has a System.FlagsAttribute attribute that allows a bitwise combination of its
+// member values.
+[Flags]
+internal enum DynamicallyAccessedMemberTypes
+{
+ //
+ // Summary:
+ // Specifies all members.
+ All = -1,
+ //
+ // Summary:
+ // Specifies no members.
+ None = 0,
+ //
+ // Summary:
+ // Specifies the default, parameterless public constructor.
+ PublicParameterlessConstructor = 1,
+ //
+ // Summary:
+ // Specifies all public constructors.
+ PublicConstructors = 3,
+ //
+ // Summary:
+ // Specifies all non-public constructors.
+ NonPublicConstructors = 4,
+ //
+ // Summary:
+ // Specifies all public methods.
+ PublicMethods = 8,
+ //
+ // Summary:
+ // Specifies all non-public methods.
+ NonPublicMethods = 16,
+ //
+ // Summary:
+ // Specifies all public fields.
+ PublicFields = 32,
+ //
+ // Summary:
+ // Specifies all non-public fields.
+ NonPublicFields = 64,
+ //
+ // Summary:
+ // Specifies all public nested types.
+ PublicNestedTypes = 128,
+ //
+ // Summary:
+ // Specifies all non-public nested types.
+ NonPublicNestedTypes = 256,
+ //
+ // Summary:
+ // Specifies all public properties.
+ PublicProperties = 512,
+ //
+ // Summary:
+ // Specifies all non-public properties.
+ NonPublicProperties = 1024,
+ //
+ // Summary:
+ // Specifies all public events.
+ PublicEvents = 2048,
+ //
+ // Summary:
+ // Specifies all non-public events.
+ NonPublicEvents = 4096,
+ //
+ // Summary:
+ // Specifies all interfaces implemented by the type.
+ Interfaces = 8192
+}
+#endif
\ No newline at end of file
diff --git a/src/System.Linq.Dynamic.Core/Compatibility/CodeAnalysis/DynamicallyAccessedMembersAttribute.cs b/src/System.Linq.Dynamic.Core/Compatibility/CodeAnalysis/DynamicallyAccessedMembersAttribute.cs
new file mode 100644
index 00000000..77d9f97a
--- /dev/null
+++ b/src/System.Linq.Dynamic.Core/Compatibility/CodeAnalysis/DynamicallyAccessedMembersAttribute.cs
@@ -0,0 +1,16 @@
+#if !NET6_0_OR_GREATER
+
+// ReSharper disable once CheckNamespace
+namespace System.Diagnostics.CodeAnalysis;
+
+[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Interface | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, Inherited = false)]
+internal sealed class DynamicallyAccessedMembersAttribute : Attribute
+{
+ public DynamicallyAccessedMembersAttribute(DynamicallyAccessedMemberTypes memberTypes)
+ {
+ MemberTypes = memberTypes;
+ }
+
+ public DynamicallyAccessedMemberTypes MemberTypes { get; }
+}
+#endif
\ No newline at end of file
diff --git a/src/System.Linq.Dynamic.Core/Compatibility/Nullable/NotNullWhenAttribute.cs b/src/System.Linq.Dynamic.Core/Compatibility/CodeAnalysis/NotNullWhenAttribute.cs
similarity index 100%
rename from src/System.Linq.Dynamic.Core/Compatibility/Nullable/NotNullWhenAttribute.cs
rename to src/System.Linq.Dynamic.Core/Compatibility/CodeAnalysis/NotNullWhenAttribute.cs
diff --git a/src/System.Linq.Dynamic.Core/Compatibility/ExpressionVisitor.cs b/src/System.Linq.Dynamic.Core/Compatibility/ExpressionVisitor.cs
index 3f1cd563..bf063e1f 100644
--- a/src/System.Linq.Dynamic.Core/Compatibility/ExpressionVisitor.cs
+++ b/src/System.Linq.Dynamic.Core/Compatibility/ExpressionVisitor.cs
@@ -1,398 +1,389 @@
#if NET35
using System.Collections.Generic;
using System.Collections.ObjectModel;
+using System.Linq.Dynamic.Core.Validation;
-namespace System.Linq.Expressions
+// ReSharper disable once CheckNamespace
+namespace System.Linq.Expressions;
+
+///
+/// Code copied from https://blogs.msdn.microsoft.com/mattwar/2007/07/31/linq-building-an-iqueryable-provider-part-ii/
+///
+internal abstract class ExpressionVisitor
{
- ///
- /// Code copied from https://blogs.msdn.microsoft.com/mattwar/2007/07/31/linq-building-an-iqueryable-provider-part-ii/
- ///
- internal abstract class ExpressionVisitor
+ protected virtual Expression Visit(Expression exp)
{
- ///
- /// Initializes a new instance of the class.
- ///
- protected ExpressionVisitor()
+ Check.NotNull(exp);
+
+ switch (exp.NodeType)
{
+ case ExpressionType.Negate:
+ case ExpressionType.NegateChecked:
+ case ExpressionType.Not:
+ case ExpressionType.Convert:
+ case ExpressionType.ConvertChecked:
+ case ExpressionType.ArrayLength:
+ case ExpressionType.Quote:
+ case ExpressionType.TypeAs:
+ return VisitUnary((UnaryExpression)exp);
+ case ExpressionType.Add:
+ case ExpressionType.AddChecked:
+ case ExpressionType.Subtract:
+ case ExpressionType.SubtractChecked:
+ case ExpressionType.Multiply:
+ case ExpressionType.MultiplyChecked:
+ case ExpressionType.Divide:
+ case ExpressionType.Modulo:
+ case ExpressionType.And:
+ case ExpressionType.AndAlso:
+ case ExpressionType.Or:
+ case ExpressionType.OrElse:
+ case ExpressionType.LessThan:
+ case ExpressionType.LessThanOrEqual:
+ case ExpressionType.GreaterThan:
+ case ExpressionType.GreaterThanOrEqual:
+ case ExpressionType.Equal:
+ case ExpressionType.NotEqual:
+ case ExpressionType.Coalesce:
+ case ExpressionType.ArrayIndex:
+ case ExpressionType.RightShift:
+ case ExpressionType.LeftShift:
+ case ExpressionType.ExclusiveOr:
+ return VisitBinary((BinaryExpression)exp);
+ case ExpressionType.TypeIs:
+ return VisitTypeIs((TypeBinaryExpression)exp);
+ case ExpressionType.Conditional:
+ return VisitConditional((ConditionalExpression)exp);
+ case ExpressionType.Constant:
+ return VisitConstant((ConstantExpression)exp);
+ case ExpressionType.Parameter:
+ return VisitParameter((ParameterExpression)exp);
+ case ExpressionType.MemberAccess:
+ return VisitMemberAccess((MemberExpression)exp);
+ case ExpressionType.Call:
+ return VisitMethodCall((MethodCallExpression)exp);
+ case ExpressionType.Lambda:
+ return VisitLambda((LambdaExpression)exp);
+ case ExpressionType.New:
+ return VisitNew((NewExpression)exp);
+ case ExpressionType.NewArrayInit:
+ case ExpressionType.NewArrayBounds:
+ return VisitNewArray((NewArrayExpression)exp);
+ case ExpressionType.Invoke:
+ return VisitInvocation((InvocationExpression)exp);
+ case ExpressionType.MemberInit:
+ return VisitMemberInit((MemberInitExpression)exp);
+ case ExpressionType.ListInit:
+ return VisitListInit((ListInitExpression)exp);
+ default:
+ throw new Exception($"Unhandled expression type: '{exp.NodeType}'");
}
+ }
- protected virtual Expression Visit(Expression exp)
+ protected virtual MemberBinding VisitBinding(MemberBinding binding)
+ {
+ switch (binding.BindingType)
{
- if (exp == null)
- {
- return exp;
- }
-
- switch (exp.NodeType)
- {
- case ExpressionType.Negate:
- case ExpressionType.NegateChecked:
- case ExpressionType.Not:
- case ExpressionType.Convert:
- case ExpressionType.ConvertChecked:
- case ExpressionType.ArrayLength:
- case ExpressionType.Quote:
- case ExpressionType.TypeAs:
- return VisitUnary((UnaryExpression)exp);
- case ExpressionType.Add:
- case ExpressionType.AddChecked:
- case ExpressionType.Subtract:
- case ExpressionType.SubtractChecked:
- case ExpressionType.Multiply:
- case ExpressionType.MultiplyChecked:
- case ExpressionType.Divide:
- case ExpressionType.Modulo:
- case ExpressionType.And:
- case ExpressionType.AndAlso:
- case ExpressionType.Or:
- case ExpressionType.OrElse:
- case ExpressionType.LessThan:
- case ExpressionType.LessThanOrEqual:
- case ExpressionType.GreaterThan:
- case ExpressionType.GreaterThanOrEqual:
- case ExpressionType.Equal:
- case ExpressionType.NotEqual:
- case ExpressionType.Coalesce:
- case ExpressionType.ArrayIndex:
- case ExpressionType.RightShift:
- case ExpressionType.LeftShift:
- case ExpressionType.ExclusiveOr:
- return VisitBinary((BinaryExpression)exp);
- case ExpressionType.TypeIs:
- return VisitTypeIs((TypeBinaryExpression)exp);
- case ExpressionType.Conditional:
- return VisitConditional((ConditionalExpression)exp);
- case ExpressionType.Constant:
- return VisitConstant((ConstantExpression)exp);
- case ExpressionType.Parameter:
- return VisitParameter((ParameterExpression)exp);
- case ExpressionType.MemberAccess:
- return VisitMemberAccess((MemberExpression)exp);
- case ExpressionType.Call:
- return VisitMethodCall((MethodCallExpression)exp);
- case ExpressionType.Lambda:
- return VisitLambda((LambdaExpression)exp);
- case ExpressionType.New:
- return VisitNew((NewExpression)exp);
- case ExpressionType.NewArrayInit:
- case ExpressionType.NewArrayBounds:
- return VisitNewArray((NewArrayExpression)exp);
- case ExpressionType.Invoke:
- return VisitInvocation((InvocationExpression)exp);
- case ExpressionType.MemberInit:
- return VisitMemberInit((MemberInitExpression)exp);
- case ExpressionType.ListInit:
- return VisitListInit((ListInitExpression)exp);
- default:
- throw new Exception(string.Format("Unhandled expression type: '{0}'", exp.NodeType));
- }
+ case MemberBindingType.Assignment:
+ return VisitMemberAssignment((MemberAssignment)binding);
+ case MemberBindingType.MemberBinding:
+ return VisitMemberMemberBinding((MemberMemberBinding)binding);
+ case MemberBindingType.ListBinding:
+ return VisitMemberListBinding((MemberListBinding)binding);
+ default:
+ throw new Exception($"Unhandled binding type '{binding.BindingType}'");
}
+ }
- protected virtual MemberBinding VisitBinding(MemberBinding binding)
+ protected virtual ElementInit VisitElementInitializer(ElementInit initializer)
+ {
+ var arguments = VisitExpressionList(initializer.Arguments);
+ if (arguments != initializer.Arguments)
{
- switch (binding.BindingType)
- {
- case MemberBindingType.Assignment:
- return VisitMemberAssignment((MemberAssignment)binding);
- case MemberBindingType.MemberBinding:
- return VisitMemberMemberBinding((MemberMemberBinding)binding);
- case MemberBindingType.ListBinding:
- return VisitMemberListBinding((MemberListBinding)binding);
- default:
- throw new Exception(string.Format("Unhandled binding type '{0}'", binding.BindingType));
- }
+ return Expression.ElementInit(initializer.AddMethod, arguments);
}
- protected virtual ElementInit VisitElementInitializer(ElementInit initializer)
- {
- ReadOnlyCollection arguments = VisitExpressionList(initializer.Arguments);
- if (arguments != initializer.Arguments)
- {
- return Expression.ElementInit(initializer.AddMethod, arguments);
- }
+ return initializer;
+ }
- return initializer;
+ protected virtual Expression VisitUnary(UnaryExpression u)
+ {
+ Expression operand = Visit(u.Operand);
+ if (operand != u.Operand)
+ {
+ return Expression.MakeUnary(u.NodeType, operand, u.Type, u.Method);
}
- protected virtual Expression VisitUnary(UnaryExpression u)
+ return u;
+ }
+
+ protected virtual Expression VisitBinary(BinaryExpression b)
+ {
+ Expression left = Visit(b.Left);
+ Expression right = Visit(b.Right);
+ Expression conversion = Visit(b.Conversion!);
+ if (left != b.Left || right != b.Right || conversion != b.Conversion)
{
- Expression operand = Visit(u.Operand);
- if (operand != u.Operand)
+ if (b.NodeType == ExpressionType.Coalesce && b.Conversion != null)
{
- return Expression.MakeUnary(u.NodeType, operand, u.Type, u.Method);
+ return Expression.Coalesce(left, right, conversion as LambdaExpression);
}
- return u;
+ return Expression.MakeBinary(b.NodeType, left, right, b.IsLiftedToNull, b.Method);
}
- protected virtual Expression VisitBinary(BinaryExpression b)
- {
- Expression left = Visit(b.Left);
- Expression right = Visit(b.Right);
- Expression conversion = Visit(b.Conversion!);
- if (left != b.Left || right != b.Right || conversion != b.Conversion)
- {
- if (b.NodeType == ExpressionType.Coalesce && b.Conversion != null)
- {
- return Expression.Coalesce(left, right, conversion as LambdaExpression);
- }
-
- return Expression.MakeBinary(b.NodeType, left, right, b.IsLiftedToNull, b.Method);
- }
+ return b;
+ }
- return b;
+ protected virtual Expression VisitTypeIs(TypeBinaryExpression b)
+ {
+ Expression expr = Visit(b.Expression);
+ if (expr != b.Expression)
+ {
+ return Expression.TypeIs(expr, b.TypeOperand);
}
- protected virtual Expression VisitTypeIs(TypeBinaryExpression b)
- {
- Expression expr = Visit(b.Expression);
- if (expr != b.Expression)
- {
- return Expression.TypeIs(expr, b.TypeOperand);
- }
+ return b;
+ }
- return b;
- }
+ protected virtual Expression VisitConstant(ConstantExpression c)
+ {
+ return c;
+ }
- protected virtual Expression VisitConstant(ConstantExpression c)
+ protected virtual Expression VisitConditional(ConditionalExpression c)
+ {
+ Expression test = Visit(c.Test);
+ Expression ifTrue = Visit(c.IfTrue);
+ Expression ifFalse = Visit(c.IfFalse);
+ if (test != c.Test || ifTrue != c.IfTrue || ifFalse != c.IfFalse)
{
- return c;
+ return Expression.Condition(test, ifTrue, ifFalse);
}
- protected virtual Expression VisitConditional(ConditionalExpression c)
- {
- Expression test = Visit(c.Test);
- Expression ifTrue = Visit(c.IfTrue);
- Expression ifFalse = Visit(c.IfFalse);
- if (test != c.Test || ifTrue != c.IfTrue || ifFalse != c.IfFalse)
- {
- return Expression.Condition(test, ifTrue, ifFalse);
- }
+ return c;
+ }
- return c;
- }
+ protected virtual Expression VisitParameter(ParameterExpression p)
+ {
+ return p;
+ }
- protected virtual Expression VisitParameter(ParameterExpression p)
+ protected virtual Expression VisitMemberAccess(MemberExpression m)
+ {
+ Expression exp = Visit(m.Expression);
+ if (exp != m.Expression)
{
- return p;
+ return Expression.MakeMemberAccess(exp, m.Member);
}
- protected virtual Expression VisitMemberAccess(MemberExpression m)
- {
- Expression exp = Visit(m.Expression);
- if (exp != m.Expression)
- {
- return Expression.MakeMemberAccess(exp, m.Member);
- }
+ return m;
+ }
- return m;
+ protected virtual Expression VisitMethodCall(MethodCallExpression m)
+ {
+ Expression obj = Visit(m.Object!);
+ IEnumerable args = VisitExpressionList(m.Arguments);
+ if (obj != m.Object || args != m.Arguments)
+ {
+ return Expression.Call(obj, m.Method, args);
}
- protected virtual Expression VisitMethodCall(MethodCallExpression m)
+ return m;
+ }
+
+ protected virtual ReadOnlyCollection VisitExpressionList(ReadOnlyCollection original)
+ {
+ List? list = null;
+ for (int i = 0, n = original.Count; i < n; i++)
{
- Expression obj = Visit(m.Object!);
- IEnumerable args = VisitExpressionList(m.Arguments);
- if (obj != m.Object || args != m.Arguments)
+ Expression p = Visit(original[i]);
+ if (list != null)
{
- return Expression.Call(obj, m.Method, args);
+ list.Add(p);
}
-
- return m;
- }
-
- protected virtual ReadOnlyCollection VisitExpressionList(ReadOnlyCollection original)
- {
- List? list = null;
- for (int i = 0, n = original.Count; i < n; i++)
+ else if (p != original[i])
{
- Expression p = Visit(original[i]);
- if (list != null)
- {
- list.Add(p);
- }
- else if (p != original[i])
+ list = new List(n);
+ for (int j = 0; j < i; j++)
{
- list = new List(n);
- for (int j = 0; j < i; j++)
- {
- list.Add(original[j]);
- }
-
- list.Add(p);
+ list.Add(original[j]);
}
- }
- if (list != null)
- {
- return list.AsReadOnly();
+ list.Add(p);
}
-
- return original;
}
- protected virtual MemberAssignment VisitMemberAssignment(MemberAssignment assignment)
+ if (list != null)
{
- Expression e = Visit(assignment.Expression);
- if (e != assignment.Expression)
- {
- return Expression.Bind(assignment.Member, e);
- }
-
- return assignment;
+ return list.AsReadOnly();
}
- protected virtual MemberMemberBinding VisitMemberMemberBinding(MemberMemberBinding binding)
- {
- IEnumerable bindings = VisitBindingList(binding.Bindings);
- if (bindings != binding.Bindings)
- {
- return Expression.MemberBind(binding.Member, bindings);
- }
+ return original;
+ }
- return binding;
+ protected virtual MemberAssignment VisitMemberAssignment(MemberAssignment assignment)
+ {
+ Expression e = Visit(assignment.Expression);
+ if (e != assignment.Expression)
+ {
+ return Expression.Bind(assignment.Member, e);
}
- protected virtual MemberListBinding VisitMemberListBinding(MemberListBinding binding)
+ return assignment;
+ }
+
+ protected virtual MemberMemberBinding VisitMemberMemberBinding(MemberMemberBinding binding)
+ {
+ IEnumerable bindings = VisitBindingList(binding.Bindings);
+ if (bindings != binding.Bindings)
{
- IEnumerable initializers = VisitElementInitializerList(binding.Initializers);
- if (initializers != binding.Initializers)
- {
- return Expression.ListBind(binding.Member, initializers);
- }
+ return Expression.MemberBind(binding.Member, bindings);
+ }
- return binding;
+ return binding;
+ }
+
+ protected virtual MemberListBinding VisitMemberListBinding(MemberListBinding binding)
+ {
+ IEnumerable initializers = VisitElementInitializerList(binding.Initializers);
+ if (initializers != binding.Initializers)
+ {
+ return Expression.ListBind(binding.Member, initializers);
}
- protected virtual IEnumerable VisitBindingList(ReadOnlyCollection original)
+ return binding;
+ }
+
+ protected virtual IEnumerable VisitBindingList(ReadOnlyCollection original)
+ {
+ List? list = null;
+ for (int i = 0, n = original.Count; i < n; i++)
{
- List? list = null;
- for (int i = 0, n = original.Count; i < n; i++)
+ MemberBinding b = VisitBinding(original[i]);
+ if (list != null)
+ {
+ list.Add(b);
+ }
+ else if (b != original[i])
{
- MemberBinding b = VisitBinding(original[i]);
- if (list != null)
+ list = new List(n);
+ for (int j = 0; j < i; j++)
{
- list.Add(b);
+ list.Add(original[j]);
}
- else if (b != original[i])
- {
- list = new List(n);
- for (int j = 0; j < i; j++)
- {
- list.Add(original[j]);
- }
- list.Add(b);
- }
+ list.Add(b);
}
-
- if (list != null)
- return list;
- return original;
}
- protected virtual IEnumerable VisitElementInitializerList(ReadOnlyCollection original)
+ if (list != null)
+ return list;
+ return original;
+ }
+
+ protected virtual IEnumerable VisitElementInitializerList(ReadOnlyCollection original)
+ {
+ List? list = null;
+ for (int i = 0, n = original.Count; i < n; i++)
{
- List? list = null;
- for (int i = 0, n = original.Count; i < n; i++)
+ ElementInit init = VisitElementInitializer(original[i]);
+ if (list != null)
{
- ElementInit init = VisitElementInitializer(original[i]);
- if (list != null)
+ list.Add(init);
+ }
+ else if (init != original[i])
+ {
+ list = new List(n);
+ for (int j = 0; j < i; j++)
{
- list.Add(init);
+ list.Add(original[j]);
}
- else if (init != original[i])
- {
- list = new List(n);
- for (int j = 0; j < i; j++)
- {
- list.Add(original[j]);
- }
- list.Add(init);
- }
+ list.Add(init);
}
-
- if (list != null)
- return list;
- return original;
}
- protected virtual Expression VisitLambda(LambdaExpression lambda)
- {
- Expression body = Visit(lambda.Body);
- if (body != lambda.Body)
- {
- return Expression.Lambda(lambda.Type, body, lambda.Parameters);
- }
+ if (list != null)
+ return list;
+ return original;
+ }
- return lambda;
+ protected virtual Expression VisitLambda(LambdaExpression lambda)
+ {
+ Expression body = Visit(lambda.Body);
+ if (body != lambda.Body)
+ {
+ return Expression.Lambda(lambda.Type, body, lambda.Parameters);
}
- protected virtual NewExpression VisitNew(NewExpression nex)
- {
- IEnumerable args = VisitExpressionList(nex.Arguments);
- if (args != nex.Arguments)
- {
- if (nex.Members != null)
- return Expression.New(nex.Constructor, args, nex.Members);
- else
- return Expression.New(nex.Constructor, args);
- }
+ return lambda;
+ }
- return nex;
+ protected virtual NewExpression VisitNew(NewExpression nex)
+ {
+ IEnumerable args = VisitExpressionList(nex.Arguments);
+ if (args != nex.Arguments)
+ {
+ if (nex.Members != null)
+ return Expression.New(nex.Constructor, args, nex.Members);
+ else
+ return Expression.New(nex.Constructor, args);
}
- protected virtual Expression VisitMemberInit(MemberInitExpression init)
- {
- NewExpression n = VisitNew(init.NewExpression);
- IEnumerable bindings = VisitBindingList(init.Bindings);
- if (n != init.NewExpression || bindings != init.Bindings)
- {
- return Expression.MemberInit(n, bindings);
- }
+ return nex;
+ }
- return init;
+ protected virtual Expression VisitMemberInit(MemberInitExpression init)
+ {
+ NewExpression n = VisitNew(init.NewExpression);
+ IEnumerable bindings = VisitBindingList(init.Bindings);
+ if (n != init.NewExpression || bindings != init.Bindings)
+ {
+ return Expression.MemberInit(n, bindings);
}
- protected virtual Expression VisitListInit(ListInitExpression init)
- {
- NewExpression n = VisitNew(init.NewExpression);
- IEnumerable initializers = VisitElementInitializerList(init.Initializers);
- if (n != init.NewExpression || initializers != init.Initializers)
- {
- return Expression.ListInit(n, initializers);
- }
+ return init;
+ }
- return init;
+ protected virtual Expression VisitListInit(ListInitExpression init)
+ {
+ NewExpression n = VisitNew(init.NewExpression);
+ IEnumerable initializers = VisitElementInitializerList(init.Initializers);
+ if (n != init.NewExpression || initializers != init.Initializers)
+ {
+ return Expression.ListInit(n, initializers);
}
- protected virtual Expression VisitNewArray(NewArrayExpression na)
+ return init;
+ }
+
+ protected virtual Expression VisitNewArray(NewArrayExpression na)
+ {
+ IEnumerable exprs = VisitExpressionList(na.Expressions);
+ if (exprs != na.Expressions)
{
- IEnumerable exprs = VisitExpressionList(na.Expressions);
- if (exprs != na.Expressions)
+ if (na.NodeType == ExpressionType.NewArrayInit)
{
- if (na.NodeType == ExpressionType.NewArrayInit)
- {
- return Expression.NewArrayInit(na.Type.GetElementType()!, exprs);
- }
-
- return Expression.NewArrayBounds(na.Type.GetElementType()!, exprs);
+ return Expression.NewArrayInit(na.Type.GetElementType()!, exprs);
}
- return na;
+ return Expression.NewArrayBounds(na.Type.GetElementType()!, exprs);
}
- protected virtual Expression VisitInvocation(InvocationExpression iv)
- {
- IEnumerable args = VisitExpressionList(iv.Arguments);
- Expression expr = Visit(iv.Expression);
- if (args != iv.Arguments || expr != iv.Expression)
- {
- return Expression.Invoke(expr, args);
- }
+ return na;
+ }
- return iv;
+ protected virtual Expression VisitInvocation(InvocationExpression iv)
+ {
+ IEnumerable args = VisitExpressionList(iv.Arguments);
+ Expression expr = Visit(iv.Expression);
+ if (args != iv.Arguments || expr != iv.Expression)
+ {
+ return Expression.Invoke(expr, args);
}
+
+ return iv;
}
}
-#endif
+#endif
\ No newline at end of file
diff --git a/src/System.Linq.Dynamic.Core/DynamicEnumerableExtensions.cs b/src/System.Linq.Dynamic.Core/DynamicEnumerableExtensions.cs
index b669fafe..3ecde061 100644
--- a/src/System.Linq.Dynamic.Core/DynamicEnumerableExtensions.cs
+++ b/src/System.Linq.Dynamic.Core/DynamicEnumerableExtensions.cs
@@ -61,7 +61,7 @@ public static dynamic[] ToDynamicArray(this IEnumerable source, Type type)
Check.NotNull(source);
Check.NotNull(type);
- IEnumerable result = (IEnumerable)ToDynamicArrayGenericMethod.MakeGenericMethod(type).Invoke(source, new object[] { source });
+ var result = (IEnumerable)ToDynamicArrayGenericMethod.MakeGenericMethod(type).Invoke(source, [source])!;
#if NET35
return CastToArray