16. C # Lambda expressions and Expression Tree (chapter 9, 9.1-9.3 ),
Before explaining Lambda related knowledge, we need to know that Lambda expressions are commonly used in LINQ, so let's talk about LINQ.
The basic function of LINQ is to create an Operation pipeline and any status required for these operations. These operations represent various data logic: How to filter, how to sort, and how to connect different data sources. Execution delegation is only one of the many capabilities of LINQ. To use databases and other query engines efficiently, we need to express the operations in the pipeline in a different way. Lambda expressions can be used for different expressions. The following uses a delegate (using an anonymous function) and a Lambda expression to perform the same thing: returns the total number of days a person has lived.
1 class Person 2 {3 public DateTime BirthDay {get; set;} 4} 5 6 public delegate int GetLifeDays (Person p ); // declare a delegate type 7 static void Main (string [] args) 8 {9 Person p = new Person () {BirthDay = new DateTime (1900, 12, 17 )}; 10 11 GetLifeDays gfd = delegate (Person x) {// instantiate a delegate
12 return (DateTime. now-x. birthDay ). days; 13}; 14 Console. writeLine (gfd (p); 15 16 GetLifeDays gfd1 = (Person x) => {return (DateTime. now-x. birthDay ). days ;}; 17 Console. writeLine (gfd1 (p); 18 19 GetLifeDays gfd2 = (Person x) => (DateTime. now-x. birthDay ). days; // remove the braces that follow. ";" indicates the end of the expression, not the end of Lambda. 20 Console. writeLine (gfd2 (p); 21 22 GetLifeDays gfd3 = (x) => {return (DateTime. now-x. birthDay ). days ;}; // Let the compiler infer the parameter type 23 Console. writeLine (gfd3 (p); 24 25 GetLifeDays gfd4 = (x) => (DateTime. now-x. birthDay ). days; // save both the parameter type and braces 26 Console. writeLine (gfd4 (p); 27 28 GetLifeDays gfd5 = x => (DateTime. now-x. birthDay ). days; // further, the parameter list is left empty. writeLine (gfd5 (p); 30 31 Console. readKey (); 32}
The above is a single parameter. For two or more parameters, the effect is "the number of days from birth to a certain day ", one day must be later than the day of birth.
1 public delegate int GetDaysTo (Person p, DateTime d); 2 static void Main (string [] args) 3 {4 Person p = new Person () {BirthDay = new DateTime (1900, 12, 17)}; 5 6 DateTime d = new DateTime (2100, 12, 12 ); 7 // use the anonymous method 8 GetDaysTo gdt = delegate (Person x, DateTime y) 9 {10 return (y-x. birthDay ). days; 11}; 12 Console. writeLine (gdt (p, d); 13 14 GetDaysTo gdt1 = (Person x, DateTime y) => {return (y-x. birthDay ). days ;}; 15 Console. writeLine (gdt1 (p, d); 16 17 GetDaysTo gdt2 = (Person x, DateTime y) => (y-x. birthDay ). days; 18 Console. writeLine (gdt2 (p, d); 19 20 GetDaysTo gdt3 = (x, y) => (y-x. birthDay ). days; 21 Console. writeLine (gdt3 (p, d); 22 23 // GetDaysTo gdt4 = x, y => (y-x. birthDay ). days; Error24 // Console. writeLine (gdt4 (p, d); 25 26 Console. readKey (); 27}
It can be seen that when the parameter is two or more parameters, the brackets in the parameter list cannot be omitted. It can also be imagined that the braces cannot be omitted when two or more parameters are in the statement.
The following uses the previous knowledge to operate a list using ampersand expressions.
1 // use the set initiator 2 List <Person> l = new List <Person> {3 new Person {BirthDay = new DateTime (, 11 )}, 4 new Person {BirthDay = new DateTime (1890,12, 12)}, 5 new Person {BirthDay = new DateTime (1891,12, 12 )}, 6 new Person {BirthDay = new DateTime (1892,12, 12)}, 7 new Person () {BirthDay = new DateTime (1870,12, 12)} 8 }; 9 10 // find people greater than new DateTime (1890,1, 1) 11 var result0 = l. findAll (x => x. birthDay> new DateT Ime (1890, 1, 1); 12 13 // Sort by age from small to large 14 l. Sort (x, y) => x. BirthDay> y. BirthDay? -1: 1); 15 foreach (var e in l) 16 {17 Console. writeLine (DateTime. now-e. birthDay ). days); 18} 19 20 // print the birth Days of each person in a loop, with the same effect as the foreach above 21 l. forEach (x => Console. writeLine (DateTime. now-x. birthDay ). days); 22 23 // find the person with BirthDay = new DateTime (1890,12, 12) 24 var result1 = l. find (x => x. birthDay = new DateTime (1890, 12, 12 ));
Next, let's look at the expression tree. The. NET3.5 expression provides an abstract way to represent some code as an object tree. The Expression Tree is mainly used for LINQ. System. linq. the Expressions namespace contains classes that represent Expressions. They all inherit from Expressions. An abstract mainly contains classes of static factory methods, which are used to create instances of other Expression classes.
The Expression class contains two attributes:
1 Expression first = Expression.Constant(5);2 Expression result = Expression.Add(first, first);3 Console.WriteLine(result);
Resumable Object Attributes
Each attribute value of the first object and result object.
- Compile the expression tree into a delegate
LambdaExpression is one of the types derived from Expression. The generic Expression <TDelegate> is derived from LambdaExpression. The difference between Expression and Expression <TDelegate> is that a generic class identifies the expressions of a static class, that is, it determines the return type and parameters. Obviously, this is represented by the TDelegate type parameter and must be a delegate type. LambdaExpression has a Compile method that can create appropriate types of delegates. Expression <TDelegate> also has a method of the same name, but it returns the TDelegate type delegate statically. For example:
1 Expression first = Expression.Constant(5);2 Expression result = Expression.Add(first, first);3 Func<int> add = Expression.Lambda<Func<int>>(result).Compile();4 Console.WriteLine(add()); //10
- Convert a C # Lambda expression to an Expression Tree
Lambda expressions can be explicitly or implicitly converted to an appropriate delegate instance. However, these are not the only conversions that can be performed. You can also ask the compiler to build an expression tree using your Lambda expressions, create an instance of Expression <TDelegate> during execution. For example
1 Expression<Func<int>> re = () => 5;2 Func<int> add0 = re.Compile();3 Console.WriteLine(add0());
The content below is really too complicated to be understood by myself, and I have never used it in daily use. I have no confidence in this topic. If I want to know more about it, I can go into depth, let's do it here.
Please make an axe.