If you are a C# developer, learning to use Expression will bring some benefits to writing some functions. For example, when we develop a paging function, we will have many query conditions. For novices, the code of these query conditions may be processed by splicing the where conditions of sql. When you learn to use Expression, This will be a very simple function.
The sample code in this post comes from my asp.net Realize the code extracted when the server automatically verifies the legitimacy of the submitted form data, because one of its functions is to perform ">", "<", "=", "> =", "< =", "! =" operations according to the custom attributes added to the form control to verify whether the value of the control is legal. This is the best case of using Expression. Of course, if it is ASP.NET Core We can also use Expression to achieve very useful functions.
1 error in constructing Expression call string Contains
Expression call string Contains
Recently, a requirement was encountered in the project. It is necessary to dynamically use the Expression to call the Contains method of the string to record an error made by C# constructing the Expression to call the string Contains. In the initially written code, some time was wasted looking for the reason because there was a problem with the parameter writing, but it was finally found. Therefore, record the error.
Here is my original code.
class Program { static void Main(string[] args) { var method = typeof(string).GetMethod("Contains", new[] { typeof(string) }); var par1 = Expression.Parameter(typeof(string), "x"); var par2 = Expression.Parameter(typeof(string), "y"); var body = Expression.Call(par1, method, par2); var r = Expression.Lambda<Func<string, string, bool>>(body, par2).Compile()("jhrs.com is my blog or my blog address is https://jhrs.com", "jhrs.com"); Console.WriteLine(r); } }
Running the program will get the following error.
The error content is:
Unhandled exception. System.ArgumentException: Incorrect number of parameters supplied for lambda declaration
at System.Linq.Expressions.Expression.ValidateLambdaArgs(Type delegateType, Expression& body, ReadOnlyCollection`1 parameters, String paramName)
at System.Linq.Expressions.Expression.Lambda[TDelegate](Expression body, String name, Boolean tailCall, IEnumerable`1 parameters)
at System.Linq.Expressions.Expression.Lambda[TDelegate](Expression body, Boolean tailCall, IEnumerable`1 parameters)
at System.Linq.Expressions.Expression.Lambda[TDelegate](Expression body, ParameterExpression[] parameters)
at ConsoleApp1.Program.Main(String[] args) in F:\jhrs.crawler\ConsoleApp1\Program.cs:line 17
What is the reason for the error
When I see the error shown in the figure above, I waste some time looking for the cause of the error. The final cause is the parameter transmission error. When I write the correct code, I can clearly find the difference from the original code.
The following shows you the correct way of writing:
class Program { static void Main(string[] args) { var method = typeof(string).GetMethod("Contains", new[] { typeof(string) }); var par1 = Expression.Parameter(typeof(string), "x"); var par2 = Expression.Parameter(typeof(string), "y"); var body = Expression.Call(par1, method, par2); var r = Expression.Lambda<Func<string, string, bool>>(body, new ParameterExpression[] { par1, par2 }).Compile()("jhrs.com is my blog or my blog address is https://jhrs.com", "jhrs.com"); Console.WriteLine(r); } }
Well, let's compare the differences:
Record 1 error made by C# constructing Expression calling string Contains 5
class Program { static void Main(string[] args) { //Wrong for the first time, an error will be reported here var method = typeof(string).GetMethod("Contains", new[] { typeof(string) }); var par1 = Expression.Parameter(typeof(string), "x"); var par2 = Expression.Parameter(typeof(string), "y"); var body = Expression.Call(par1, method, par2); var r = Expression.Lambda<Func<string, string, bool>>(body, par2).Compile()("jhrs.com is my blog or my blog address is https://jhrs.com", "jhrs.com"); Console.WriteLine(r); //Here is the right code //var method = typeof(string).GetMethod("Contains", new[] { typeof(string) }); //var par1 = Expression.Parameter(typeof(string), "x"); //var par2 = Expression.Parameter(typeof(string), "y"); //var body = Expression.Call(par1, method, par2 ); //var r = Expression.Lambda<Func<string, string, bool>>(body, new ParameterExpression[] {par1, par2 }).Compile()("jhrs.com is my blog or my blog address is https://jhrs.com", "jhrs.com"); //Console.WriteLine(r); } }
The reason for the error is that the wrong parameter is given, as I used the red mark in the above figure.
conclusion
When I solve this problem, I will redo the problem and find that I have made a low-level mistake. In fact, in the process of writing code, if you are Visual Studio 2019 The program written only needs to use the shortcut key CTRL+SHIFT+SPACE to get the prompt as shown in the figure below.
Original text: Expression call string Contains A mistake made