As a more in-depth evolution of Delegate, Lambda makes our code more concise and elegant, but it also faces a problem: how to dynamically construct a Lambda expression based on external conditions. Maybe you will wonder how this requirement is created ...... First, Lambda assumes part of the role of the previous T-SQL in dlinq; secondly, in database design, we often need to query data based on the combination of external unknown dynamic conditions. The problem is that, as a static language, we obviously cannot use dynamic syntax or concatenate strings to create a delegate/Lambda statement. How can we achieve a similar goal? Codedom? Emit? Perhaps the best choice is system. LINQ. Expressions. expression.
First, let's look at the composition of a simple Lambda expression.
i => i > 5
In this expression ,"I"Called parameter ,"I> 5"Is body. We can further break down the body, so"I> 5"Contains parameters (I), operators (>), and a constant (5 ). All of these are combined in a specific order to build a complete Lambda expression.
We use some examples to learn how to dynamically construct these expressions.
Example 1
VaR ints = new int [] {1, 2, 3, 4, 5, 6, 7, 8, 9}; // var r = ints. where (I => I> 5); // expression to be implemented // create the parameter Ivar parameter = expression. parameter (typeof (INT), "I"); // create the constant 5var constant = expression. constant (5); // create a comparison expression I> 5var bin = expression. greaterthan (parameter, constant); // obtain the lambda expression var Lambda = expression. lambda <func <int, bool> (bin, parameter); // use the compile method to obtain delegatevar _ r = ints. where (lambda. compile ());
When you set a breakpoint in the code, we can see the expression information displayed in the debugger.
. Net FX 3.5 adds some Delegate types for Lambda.
(1) It is used to process actions without returned data.
public delegate void Action()public delegate void Action<T> (T arg)public delegate void Action<T1, T2> (T1 arg1, T2 arg2)public delegate void Action<T1, T2, T3> (T1 arg1, T2 arg2, T3 arg3)public delegate void Action<T1, T2, T3, T4> (T1 arg1, T2 arg2, T3 arg3, T4 arg4)
(2) It is used to process func with returned data.
public delegate TResult Func<TResult> ()public delegate TResult Func<T, TResult> (T arg)public delegate TResult Func<T1, T2, TResult> (T1 arg1, T2 arg2)public delegate TResult Func<T1, T2, T3, TResult> (T1 arg1, T2 arg2, T3 arg3)public delegate TResult Func<T1, T2, T3, T4, TResult> (T1 arg1, T2 arg2, T3 arg3, T4 arg4)
We can also make more complex combinations.
Example 2
VaR ints = new int [] {1, 2, 3, 4, 5, 6, 7, 8, 9}; // var r = ints. where (I => I> 5 & I <= 7); // The expression to be implemented // create the parameter Ivar parameter = expression. parameter (typeof (INT), "I"); // create an expression I> 5 var con1 = expression. constant (5); var bin1 = expression. greaterthan (parameter, con1); // create the expression I <= 7var con2 = expression. constant (7); var bin2 = expression. lessthanorequal (parameter, con2); // combine two expressions var body = expression. and (bin1, bin2); // obtain the lambda expression var Lambda = expression. lambda <func <int, bool> (body, parameter); VaR _ r = ints. where (lambda. compile ());
In Example 2, we break down complex expressions and use and to assemble multiple expressions. Therefore, we can create more complex logical combinations, such as example 3.
Example 3
VaR ints = new int [] {1, 2, 3, 4, 5, 6, 7, 8, 9}; // var r = ints. where (I => (I> 5 & I <= 7) | (I = 3 )); // expression to be implemented // create the parameter Ivar parameter = expression. parameter (typeof (INT), "I"); // create an expression I> 5var con1 = expression. constant (5); var bin1 = expression. greaterthan (parameter, con1); // create the expression I <7var con2 = expression. constant (7); var bin2 = expression. lessthanorequal (parameter, con2); // create an expression I = 3var con3 = expression. constant (3); var bin3 = expression. equal (parameter, con3); // composite I> 5 & I <= 7var body = expression. and (bin1, bin2); // combination (I> 5 & I <= 7) or (I = 3) Body = expression. or (body, bin3); var Lambda = expression. lambda <func <int, bool> (body, parameter); VaR _ r = ints. where (lambda. compile ());
Let's continue to look at several common examples.
Example 4
VaR ints = new int [] {1, 2, 3, 4, 5, 6, 7, 8, 9}; // var r = ints. select (I => I % 2 = 0? I: 0); // The expression to be implemented // create the parameter Ivar parameter = expression. parameter (typeof (INT), "I"); // create the expression I % 2var con1 = expression. constant (2); var bin1 = expression. modulo (parameter, con1); // create an expression (I % 2) = 0var con2 = expression. constant (0); var bin2 = expression. equal (bin1, con2); // create the expression IIF (I % 2) = 0), I, 0) var bin3 = expression. condition (bin2, parameter, expression. constant (0); var Lambda = expression. lambda <func <int, int> (bin3, parameter); VaR _ r = ints. select (lambda. compile ());
Example 5
VaR ints = new int [] {1, 2, 3, 4, 5, 6, 7, 8, 9}; // array. foreach <int> (ints, I => console. writeline (I); // The expression to be implemented // create the parameter Ivar parameter = expression. parameter (typeof (INT), "I"); // obtain the console. writeline methodinfomethodinfo method = typeof (console ). getmethod ("writeline", new type [] {typeof (INT)}); // create an expression var call = expression. call (method, parameter); var Lambda = expression. lambda <action <int> (call, parameter); array. foreach <int> (ints, lambda. compile ());
It's time to study system. LINQ. Expressions namespace.