WPF-MVVM Mode Learning Note 4--LAMBDA expression learning

Source: Internet
Author: User

In the course of learning MVVM, a superclass notificationobject is customized, as follows

    Public abstract class Notificationobject:inotifypropertychanged {public event PropertyChangedEventHandler        propertychanged;  protected virtual void raisePropertyChanged (String propertyname) {PropertyChangedEventHandler handler = This.            propertychanged;            if (handler! = null) {Handler (this, new PropertyChangedEventArgs (PropertyName));  }} protected void raisePropertyChanged (params string[] propertynames) {if (propertynames            = = null) throw new ArgumentNullException ("PropertyNames"); foreach (var name in propertynames) {this.            raisePropertyChanged (name);        }} protected void Raisepropertychanged<t> (expression<func<t>> propertyexpression)            {var propertyname = Extractpropertyname (propertyexpression); This.        raisePropertyChanged (PropertyName); } public staticString extractpropertyname<t> (expression<func<t>> propertyexpression) {if (propertyEx            pression = = null) {throw new ArgumentNullException ("Propertyexpression");            } var memberexpression = propertyexpression.body as memberexpression; if (memberexpression = = null) {throw new ArgumentException ("propertysupport_notmemberaccessexpr            Ession_exception "," propertyexpression ");            } var property = Memberexpression.member as PropertyInfo; if (property = = null) {throw new ArgumentException ("Propertysupport_expressionnotproperty_excep            tion "," propertyexpression "); } var GetMethod = property.            Getgetmethod (TRUE); if (getmethod.isstatic) {throw new ArgumentException ("Propertysupport_staticexpression_exceptio            N "," propertyexpression "); } return MembereXpression.        Member.name; }    }


Where there is a function protected void raisepropertychanged<t> (expression<func<t>> propertyexpression), Here is a expression<func<t> I do not understand, later check is lambda expression, well, to tell the truth, I see this lambda a bit of egg pain chrysanthemum tight ... Encountered before, did not delve into, this time try to learn to understand, in the Internet to read a lot of information, which has a small partner speaking good, excerpt down, haha. (I suggest to go straight to the original, and then return to see my article, because I am the following example is based on WPF, and like some button commands tied to the use of cheap, worried to see the people look at the circle, click here to read the original )

Introduction to Lambda

The lambda operator simplifies the use of anonymous delegates, makes the code more concise and elegant, and is said to be one of the most important features that Microsoft has added since c#1.0.

Lambda operator: All lambda expressions use the new lambda operator "= =", which you can call the operator "go" or "become". The operator divides the expression into two parts, the left specifies the input parameter, and the right side is the body of the lambda.

Lambda expression:

1. One parameter: param = expression

2. Multiple parameters: (paramlist) = expression

Above these things, first remember, read the following and then turn to see, understand more deeply.

What's so good about lambda?

According to a demo, the analysis is carried out slowly, examples are as follows

namespace lambdademo.viewmodel{public    class person    {public        string Name {get; set;}        public int Age {get; set;}    }    public class VMLambdaStudyDemo1    {public        static list<person> personslist ()        {            List<person > persons = new list<person> ();            for (int i = 0; i < 7; i++)            {person                p = new Person () {Name = i + "Son", age = 8-i};                Persons. ADD (P);            }            return persons;        }        <summary>//        Btn_lambdademo1 Click event///        </summary> public        void btn_lambdademo1_ Click ()        {            list<person> persons = Personslist ();            persons = persons. Where (p = p.age > 5). ToList (); The collection of all Age>5 's Person}}}    

The above demo project only retains elements of age greater than 5 in the persons collection after pressing the button btn_lambdademo1. So directly to see, for me this novice is not obvious, I still like to interrupt point tracking, such as


I hit a breakpoint on 33 lines and 35 lines, 37 lines, running the program


Click the button btn_lambdademo1, the program stays at the first breakpoint

You can see that the element in the persons collection is empty, and then F5 runs to the next breakpoint


At this point we find that 7 elements have been added to the collection persons, and then F5 runs to the next breakpoint


This time you will find that only 3 elements are left in the collection persons, and these 3 elements satisfy our filter criteria.

Here, we can see that this lambda expression p + p.age > 5 work, but this does not see the benefits of lambda, we also know that good is relative, then we do not use lambda to implement this filtering function, in another way


For example, I will block 35 lines, with 37 lines-46 lines of code to implement this filtering function, you can interrupt point tracking, and finally to achieve our requirements. Here, the above two ways 22 comparison, we can be like Zhang Tong doctrine, "Lambda is really a chocolate." (this project is relatively simple, if necessary, you can download, click here to download )

Lambda is really good.

In the example above, I used a common method to compare lambda to the benefits of lambda, but it should not be compared in theory. Because I mentioned in the previous lambda introduction that Lambda simplifies the application of anonymous delegates and makes the code more concise , so theoretically I should use an anonymous delegate to foil the Lambda's good. Here's a look at what's going on with this expression (p=>p.age>5), and I'll change the code above to the next

namespace lambdademo.viewmodel{public class Person {public string Name {get; set;}    public int Age {get; set;} } public class VMLambdaStudyDemo1 {//Delegate delegate list<person> Unamedweituo (list<person> p        Ersons);            public static list<person> Personslist () {list<person> persons = new list<person> ();                 for (int i = 0; i < 7; i++) {person p = new person () {Name = i + "Son", age = 8-i}; Persons.            ADD (P);        } return persons;            } public void Btn_lambdademo1_click () {list<person> persons = Personslist ();            Unamedweituo UWT = Weituofunc;           persons = UWT (persons); }//Delegate method public static list<person> Weituofunc (list<person> persons) {LIST&LT ;            person> personstmp = new list<person> (); foreach (Person p in Persons) {if (P.age > 5) {personstmp.                ADD (P);        }} return personstmp; }    }}

In the above code, I define a delegate Unamedweituo (I will not say more about the delegation, please self-brain), using the delegation method to achieve our requirements for the collection of persons. Comparing the above delegate to the lambda expression (p=>p.age>5), we can see the advantages of the expression. It is also possible to see that p in the expression (P=>P.AGE>6) represents a parameter in the delegate method, and the right side of the expression symbol

The p.age>5 represents the return result of the delegate method.

Lambda strike

The following is a more intuitive example of the students directly on the table:

1. Single parameter

Using delegate methods

    public class VMLambdaStudyDemo1    {        //delegate  shopping        delegate int Guangchaoshi (int a);        public void Btn_lambdademo1_click ()        {            Guangchaoshi gwl = Jiezhang;            MessageBox.Show (GWL (10) + ""); The print result is ""           } public        static int Jiezhang (int a)        {            return (A + ten);        }    }

Using lambda expressions

    public class VMLambdaStudyDemo1    {        //delegate  shopping        delegate int Guangchaoshi (int a);        public void Btn_lambdademo1_click ()        {            Guangchaoshi GWL = p = + p + Ten;            MessageBox.Show (GWL (10) + ""); Print result is ""           }    }

Oh My ladygaga,that ' s greatful!, next to a multi-parameter, but the internal operation of the delegate method is relatively simple.

2. Multi-parameter, the main operation is simple

Using delegate methods

    public class VMLambdaStudyDemo1    {        //entrusted to the  supermarket        delegate int Guangchaoshi (int a,int b);        public void Btn_lambdademo1_click ()        {            Guangchaoshi gwl = Jiezhang;            MessageBox.Show (GWL (10,100) + ""); Print result is "" "           }        //Checkout public        static int Jiezhang (int a, int b)        {            return (b-(A +));        }    }


Using lambda expressions

    public class VMLambdaStudyDemo1    {        //entrusted to the  supermarket        delegate int Guangchaoshi (int a,int b);        public void Btn_lambdademo1_click ()        {            Guangchaoshi gwl = (p,z) = Z-(p + +);            MessageBox.Show (GWL (10,100) + ""); Print result is "" "           }    }


Good good, the following is still a multi-parameter, but the internal operation of the delegate method is more complex

3. Multi-parameter, complex topic operation

Using delegate methods

    public class VMLambdaStudyDemo1 {//<summary>///entrusted to supermarket///        </summary>        // <param name= "A" > Spend </param>//        <param name= "B" > Pay </param>//        <returns> Change </returns>        delegate int Guangchaoshi (int a,int b);        public void Btn_lambdademo1_click ()        {            Guangchaoshi gwl = Jiezhang;            MessageBox.Show (GWL (20,100) + ""); Print result is "" "           }        //Checkout public        static int Jiezhang (int a, int b)        {            int zuidixiaofei = ten;            if (b < Zuidixiaofei)            {                return;            }            else            {                return (b-a-Zuidixiaofei);            }        }    }


Using lambda expressions

    public class VMLambdaStudyDemo1 {//<summary>///entrusted to supermarket///        </summary>        // <param name= "A" > Spend </param>//        <param name= "B" > Pay </param>//        <returns> Change </returns>        delegate int Guangchaoshi (int a,int b);        public void Btn_lambdademo1_click ()        {            Guangchaoshi gwl = (p, z) + =                {                    int zuidixiaofei = ten;                    if (P < Zuidixiaofei)                    {                        return;                    }                    else                    {                        return (z-p-Zuidixiaofei);                    }                };            MessageBox.Show (GWL (20,100) + ""); Print result is "" "           }    }


Yes, well, as I wrote here, I was suddenly enlightened by the lambda expression.

The above examples, well understand, below I continue to excerpt Zhang classmate, introduce a system designated Func<t> delegate.

Func<t> delegate

T is a generic type of argument, which is a generic kind of delegate, which is convenient to use.

The first example

    public class VMLambdaStudyDemo1    {public                void Btn_lambdademo1_click ()        {            Func<int, string> GWL = p = + p + 10 + "--return type is string";            MessageBox.Show (GWL (10)); The print result is "20--return type is String type"           }    

Description, as you can see here, p is the int type parameter, but the lambda body returns a string type, and you see my MessageBox.Show () does not have to add "".

I'm going to take a walk, so easy to say.

And then the last example

        public void Btn_lambdademo1_click ()        {            func<int, int, bool> GWL = (p, j) +                {                    if ((p + j) = =) 
   {                        return true;                    }                    return false;                };            MessageBox.Show (GWL (5,5) + ""); The print result is "True"           }

Note: From this example, we can see that p is of type int, j is an int type and the return value is type bool.

After reading the above two examples, I believe you should understand the use of func<t>: Multiple parameters, the previous argument for the delegate method, and the last parameter is the return type of the delegate method . Have to say, this Zhang classmate's ideas speak really clear ah!

Lambda expression Summary

① "lambda expression" is an anonymous function that can contain expressions and statements, and can be used to create delegates.

②LAMBDA expression format is: (argument list) = = Expression or statement block

③ Frankly, lambda expressions and anonymous methods are actually one thing, and they all work: generating methods. That is, inline methods.

④lambda can be used not only to create delegates, but also to create an expression tree. the next section is about the lambda expression tree!

Lambda expression tree

Note that the above title is "lambda expression tree", not "lambda expression"!

Expressions Tree Concept

① expression trees, also known as expression trees, represent language-level code in the form of data. All data is stored in a tree structure, and each node represents an expression.

The ②LAMBDA expression tree allows us to process lambda expressions like data (such as reading, modifying). (Note that the relationship between the lambda expression tree and the lambda expression can be seen here!) )

The type of expression (this can be understood here first, as the experiment goes back in depth to see deeper understanding)

① parameter expression: parameterexpression. is a parameter in a method, such as a key in search (string key) as a parameter expression, and n in a lambda expression (n = = n * 3) can also be seen as a parameter expression.

② Two-dimensional expression: binaryexpression. For example A + B or (n * 3) < 5 and so on.

③ method Invocation Expressions: Methodcallexpression, such as the custom LINQ provider, to implement an operation by itself.

④ constant expression: constantexpression. For example, the value 5

⑤ an expression with conditional arithmetic: conditionexpression

There are many more that can go to see MSDN, not explained.

Let's take a simple example, or use a breakpoint to track

        public void Btn_lambdademo1_click ()        {            func<int, bool> test = n = (n * 3) < 5;            Expression<func<int, bool>> filter = n = = (n * 3) < 5;                                      }
As you can see from the program, the lambda expression n = (n * 3) < 5 used by test and filter, but filter uses expression to represent the lambda expression as a data structure in the form of a directory tree, let's Run the program, See what the difference is between the two.

The program runs at the first breakpoint


At this point the test and filter are empty, two times F5, the program runs to the 3rd breakpoint, expand Test and filter, as


As you can see, the content of the two is very different, where filter contains a lot of lambda expression (n = (n*3) <5) information, such as Body Body is (n*3) <5, return type returntype to Boolen type, There are 1 parameters. Expand the body of the filter, as


You can see the body inside can also see the main body to the left is n * 3, the right side of the main body is 5, the node type is < that is LessThan, and so on, the information is very big said.

The following is a visual representation of the internal information of an expression tree through functions

public class VMLambdaStudyDemo1 {public void Btn_lambdademo1_click () {func<int, b            Ool> test = n = (n * 3) < 5;            Expression<func<int, bool>> filter = n = = (n * 3) < 5; Binaryexpression lt = (binaryexpression) filter.            Body; Binaryexpression mult = (binaryexpression) Lt.            Left; ParameterExpression en = (parameterexpression) mult.            Left; ConstantExpression three = (constantexpression) mult.            right; ConstantExpression five = (constantexpression) Lt.            right;            var one = Filter.compile ();                         MessageBox.Show (One (5) + "| |" + ONE (1) + "| |" + Lt. NodeType + "| |" + mult. NodeType + "| |" + en. Name + "| |" + three. Value + "| |" + FIVE.                              Value); }    }
Can be self-breakpoint tracking to see, I will not demonstrate, good trouble to say. The following is the result of running the program


The example above can visually show that the lambda expression tree allows us to handle lambda expressions as if we were working with data (such as reading, modifying), and then an example to deepen the impression.

Using system;using system.collections.generic;using system.linq;using system.linq.expressions;using System.Text;  Using System.threading.tasks;namespace lambdademo.viewmodel{public class VMLambdaStudyDemo1 {public void Btn_lambdademo1_click () {ParameterExpression a = Expression.parameter (typeof (int), "I");//Create an expression            The parameter in the tree, as a node, here is the lowest node parameterexpression b = Expression.parameter (typeof (int), "J");  Binaryexpression be = Expression.multiply (A, b);            Here i*j, generate a node in the expression tree, higher than the above node parameterexpression C = Expression.parameter (typeof (int), "w");            ParameterExpression d = expression.parameter (typeof (int), "x");            Binaryexpression be1 = Expression.multiply (c, D);   Binaryexpression su = Expression.add (be, BE1); Operations two intermediate nodes, resulting in endpoint expression<func<int, int, int, int, int>> lambda = expression.lambda<func<in            t, int, int, int, int>> (su, a, B, C, D); Func<int, int, int, int, int> f = lambda.compile (); The lambda expression described by the expression tree is compiled into executable code and the delegate of the lambda expression is generated; System.Windows.MessageBox.Show ("Lambda:" + lambda + "Result:" +        F (1, 1, 1, 1)); }    }}

Run the result as


The structure of the lambda expression tree for the previous section of code, directly with the student's


The combination of this picture and look at the code, carefully understood, should be able to understand the more thorough.

Conclusion

I took a go, knocked so long, more tired than knocking the code, knocking here, I am a more understanding of lambda, but reflect on, will use it? Answer Yue: No!

But it's OK, learn to use, next prepare to study the notificationobject protected void raisepropertychanged<t> (expression<func<t> > Propertyexpression)


WPF-MVVM Mode Learning Note 4--LAMBDA expression learning

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.