WPF-MVVMパターンの研究ノート4 - ラムダ式学習

    NotificationObjectカスタマイズされたスーパークラスは、次のようにした学習過程でMVVM

    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 static string ExtractPropertyName<T>(Expression<Func<T>> propertyExpression)
        {
            if (propertyExpression == null)
            {
                throw new ArgumentNullException("propertyExpression");
            }

            var memberExpression = propertyExpression.Body as MemberExpression;
            if (memberExpression == null)
            {
                throw new ArgumentException("PropertySupport_NotMemberAccessExpression_Exception", "propertyExpression");
            }

            var property = memberExpression.Member as PropertyInfo;
            if (property == null)
            {
                throw new ArgumentException("PropertySupport_ExpressionNotProperty_Exception", "propertyExpression");
            }

            var getMethod = property.GetGetMethod(true);
            if (getMethod.IsStatic)
            {
                throw new ArgumentException("PropertySupport_StaticExpression_Exception", "propertyExpression");
            }

            return memberExpression.Member.Name;
        }

    }


      空RaisePropertyChanged <T>(式保護機能があります 。<のFunc <T >> propertyExpression)を、 数式がある<のFunc <T>私は本当に理解していない、そして見上げるラムダ式I、まあ、正直に言うと、ですラムダは、のいずれかが良いジュニアパートナー、抜粋ダウンを話す、チュはタイト...遭遇する前に、その下に取得し、ないこの小さな卵の痛みは、このビットを理解することを学ぶためにしようと、インターネット上で多くの情報を読んで見ますハハ。私は、次のですので、(私は安い安い、人々が見て心配していくつかのバインディングのようなコマンドを使用していた説明し、ボタンの例は、WPFに基づいており、私の記事で、元の最初の直接の一見をお勧めします、その後、戻って見てモンゴルサークルを見て、元のテキストを読むにはこちらをクリックしてください

ラムダプロフィール

    ラムダオペレータは、匿名デリゲートの使用を簡素化し、コードをより、シンプルでエレガントな作り、C#1.0の最も重要な新機能以来、マイクロソフトの一つと言われています。

    ラムダ演算子:すべてのラムダ式は、新しいラムダ演算子「=>」、あなたは「行く」またはのためのオペレータを呼び出すことができるとされている「となります。」式の演算子が2つの部分に分割され、左側に指定された入力パラメータは、権利は、ラムダの主題です。

    ラムダ式:

           1.パラメータ:=>式のparam

           パラメータの2.複数:(paramlist)=>式

    これらのものの上に、覚え以下を読み、その後、より深く理解するために、見にオンにします。

ラムダ良いは何ですか?

    デモ、ゆっくりと分析、次の例によると、

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 + "儿子",Age = 8-i};
                persons.Add(p);
            }
            return persons;
        }
        /// <summary>
        /// Btn_LambdaDemo1 Click事件
        /// </summary>
        public void Btn_LambdaDemo1_Click()
        {
            List<Person> persons = PersonsList();

            persons = persons.Where(p => p.Age > 5).ToList(); //所有Age>5的Person的集合

        }
    }

}

   上記のボタン用に設計されたデモプロジェクトは人の5を超える年齢のセットのみを残し、Btn_LambdaDemo1押されます。私のためにこのような直接見て、以下に示すように、この初心者が、私はまだブレークポイントの追跡のような、明らかにされていません


   私は、プログラムを実行し、33行と35行、37行のそれぞれにブレークポイントをヒット


  ボタンBtn_LambdaDemo1、最初のブレークポイントでプログラムの滞在をクリックしてください

  

  この時、人々はすぐに次のブレークポイントF5に実行し、コレクション要素が空で見ることができます


この時点で、私たちは、人々が次のブレークポイントまで実行し、その後7つの要素、F5のセットに追加されていることがわかります


     この時間は、3つの要素のみで人物のコレクションを見つけるだろう、これらの3つの要素は、フィルタリングのために私たちの基準を満たすようにしています。

     ここでは、このラムダ式P => p.Age> 5が有効になりますが、それはまた、ラムダの利点を見ることができない、我々はすべて知っている、良いことは相対的なものであるとして、Nazanはラムダを実現していないことがわかります別の方法については、このスクリーニング機能、


    上記のように、私は37行-46行のコードで、このスクリーニング機能を達成するために、あなたは点追跡ビットを破ることができる、そして最終的に私たちの要求を達成することができ、ライン35をシールドします。二つの方法上記の比較を対毎の張は、学生として言ったようにここで、私たちはすることができ、「ラムダは確かに甘い日付です。」(必要であれば、このプロジェクトは、ダウンロードするには、比較的簡単でダウンロードするにはここをクリックしてください

ラムダは本当に良いです

    上記の例では、私はラムダの利点を説明するために、一般的な方法でラムダと比較するために使用されるが、実際にこの理論を比較すべきではありません。私は以前、ラムダ冒頭で述べたので、ラムダの簡素化アプリケーションの匿名デリゲート、コードより簡潔を作るので、理論的には、私はラムダの良いもたらすに匿名手数料を使用する必要があります。ここではそれがどのように最終的に(P => p.Age> 5)この式を見てだ、私は下に上記のコードを変更します

namespace LambdaDemo.ViewModel
{
    public class Person
    {
        public string Name { get; set; }
        public int Age { get; set; }
    }

    public class VMLambdaStudyDemo1
    {
        //委托
        delegate List<Person> UNamedWeiTuo(List<Person> persons);

        public static List<Person> PersonsList()
        {
            List<Person> persons = new List<Person>();

            for (int i = 0; i < 7; i++)
            {
                Person p = new Person() {Name = i + "儿子",Age = 8-i};
                persons.Add(p);
            }
            return persons;
        }

        public void Btn_LambdaDemo1_Click()
        {
            List<Person> persons = PersonsList();

            UNamedWeiTuo uwt = WeiTuoFunc;

            persons = uwt(persons);
   
        }

        //委托方法
        public static List<Person> WeiTuoFunc(List<Person> persons)
        {
            List<Person> personstmp = new List<Person>();
            foreach (Person p in persons)
            {
                if (p.Age > 5)
                {
                    personstmp.Add(p);
                }
            }

            return personstmp;
        }
    }

}

   上記のコードでは、私は人々の私たちのコレクションを達成するために削除オプションを使用する方法が委託し、(私はより多くの信頼、ハァッ、あなた自身の脳のサプリメントについて言うことはありません)手数料UNamedWeiTuoの要件を定義しました。上述のラムダ式とデリゲート(P => p.Age> 5)比較、我々はそれが効果の発現であることがわかります。また見ることができる。実際には、式(P => p.Age> 6)pは、右側の式の符号をパラメータデリゲートメソッドを表します 

p.Age> 5つの返す結果はデリゲートメソッドを表します。

進捗上のラムダのビルド

   直接シートより直感的な例で、次の学生:

   1.単一のパラメータ

   デリゲートメソッドを使用します

    

    public class VMLambdaStudyDemo1
    {
        //委托  逛超市
        delegate int GuangChaoShi(int a);
        public void Btn_LambdaDemo1_Click()
        {
            GuangChaoShi gwl = JieZhang;
            MessageBox.Show(gwl(10) + ""); //打印结果为 "20"
   
        }

        public static int JieZhang(int a)
        {
            return (a + 10);
        }
    }

   ラムダ式を使用します

    public class VMLambdaStudyDemo1
    {
        //委托  逛超市
        delegate int GuangChaoShi(int a);
        public void Btn_LambdaDemo1_Click()
        {
            GuangChaoShi gwl = p => p + 10;
            MessageBox.Show(gwl(10) + ""); //打印结果为 "20"
   
        }

    }
   

   オーマイLadyGaGaは、それは再びここで、マルチパラメータGREATFUL!ですが、比較的単純な内部演算方式を委任します。

   2.マルチパラメータ、簡単な操作体

   デリゲートメソッドを使用します

    public class VMLambdaStudyDemo1
    {
        //委托  逛超市
        delegate int GuangChaoShi(int a,int b);
        public void Btn_LambdaDemo1_Click()
        {
            GuangChaoShi gwl = JieZhang;
            MessageBox.Show(gwl(10,100) + ""); //打印结果为 "80"
   
        }

        //结账
        public static int JieZhang(int a, int b )
        {
            return (b - (a + 10));
        }
    }


   ラムダ式を使用します

    public class VMLambdaStudyDemo1
    {
        //委托  逛超市
        delegate int GuangChaoShi(int a,int b);
        public void Btn_LambdaDemo1_Click()
        {
            GuangChaoShi gwl = (p,z) => z - (p + 10);
            MessageBox.Show(gwl(10,100) + ""); //打印结果为 "80"
   
        }

    }


   以下またはマルチパラメータに、悪いが、デリゲートメソッド内部操作より複雑ではありません

  3.マルチパラメータ、テーマ計算の複雑

  デリゲートメソッドを使用します

    public class VMLambdaStudyDemo1
    {
        
        /// <summary>
        ///委托  逛超市
        /// </summary>
        /// <param name="a">花费</param>
        /// <param name="b">付钱</param>
        /// <returns>找零</returns>
        delegate int GuangChaoShi(int a,int b);
        public void Btn_LambdaDemo1_Click()
        {
            GuangChaoShi gwl = JieZhang;
            MessageBox.Show(gwl(20,100) + ""); //打印结果为 "70"
   
        }

        //结账
        public static int JieZhang(int a, int b )
        {
            int zuidixiaofei = 10;
            if (b < zuidixiaofei)
            {
                return 100;
            }
            else
            {
                return (b - a - zuidixiaofei);
            }

        }
    }


  ラムダ式を使用します

    public class VMLambdaStudyDemo1
    {
        
        /// <summary>
        ///委托  逛超市
        /// </summary>
        /// <param name="a">花费</param>
        /// <param name="b">付钱</param>
        /// <returns>找零</returns>
        delegate int GuangChaoShi(int a,int b);
        public void Btn_LambdaDemo1_Click()
        {
            GuangChaoShi gwl = (p, z) =>
                {
                    int zuidixiaofei = 10;
                    if (p < zuidixiaofei)
                    {
                        return 100;
                    }
                    else
                    {
                        return (z - p - zuidixiaofei);
                    }
                };

            MessageBox.Show(gwl(20,100) + ""); //打印结果为 "70"
   
        }

    }


  はいはい、私は突然、ラムダ式を開き、あなたに書き込みます。

  これらの例をよく理解の下で、私は次の抜粋張の学生を続け、システムの導入のFunc <T>デリゲートを指定し、上記の。

Func <T>デリゲート

   Tは、デリゲートのジェネリック型であるジェネリック型のパラメータであり、それはに簡単でした

   最初の例

    public class VMLambdaStudyDemo1
    {
        
        public void Btn_LambdaDemo1_Click()
        {
            Func<int, string> gwl = p => p + 10 + "--返回类型为string类型";
            MessageBox.Show(gwl(10)); //打印结果为 "20--返回类型为string类型"
   
        }

    }

   「」追加しない説明、あなたはここで見ることができ、pはint型の引数は、しかしラムダ本体返す文字列型である、あなたは(私のMessageBox.Showを参照してください)。

   ル私はそう簡単に、行きます。

   そして、前の例

        public void Btn_LambdaDemo1_Click()
        {
            Func<int, int, bool> gwl = (p, j) =>
                {
                    if ((p + j) == 10)
                    {
                        return true;
                    }
                    return false;
                };
            MessageBox.Show(gwl(5,5) + ""); //打印结果为 "True"
   
        }

   注:この例から、我々が見ることができ、pはintで、jはint型、ブール戻り値の型です。

   二つの例を超える読んだ後、私たちは理解しておくべきと考えているのFunc <T>使用法:複数のパラメータ、手数料、デリゲートメソッドの戻り値の型のための最後の引数のパラメータの以前の方法言っている、張さんは本当に明確なああ話して学生のこのアイデア!

ラムダ式の概要

      ①「ラムダ式は、」式や文を含めることができ、匿名関数であり、手数料を作成するために使用することができます。

      パラメータリスト:()=>式またはステートメントブロックの②ラムダ式のフォーマット

      メソッドを生成します。③はっきりそれを置くために、ラムダ式と実際に匿名メソッドは、その役割はであり、一つのことです。すなわち、インラインメソッド。

      ④ラムダだけでなく、手数料を作成するために使用され、それはまた、式ツリーを作成するために使用することができます。次のセクションでは、ラムダ式の木について話します!

ラムダ式ツリー

   注上記の名称「ラムダ式ツリー」の代わりに「ラムダ式」こと!

   ●式ツリーの概念

       ①式ツリーはまた、式ツリーとして知られており、データ形式言語レベルのコードを表します。全てのデータは、各ノードは、発現を表す、ツリー構造に格納されます。

        ②木のようなラムダ式は、私たちは(そのような読み取りと変更)データを処理し、同じラムダ式に対処することができます。(ここでは、ラムダ式の木とラムダ式の関係を見ることができることに注意してください!)

   タイプの●表現(私はあなたが知ってもらおう、実験の深化に戻って来ることは、より深い理解を見ていきます)

        ①パラメータ式:ParameterExpressionは、検索などの処理パラメータ(文字列キー)であり、キー表現をパラメータとして見ることができ、また、ラムダ式(N => N * 3)の他の例、N。これは、パラメータの表現として見ることができます。

        ②第2の要素の式:BinaryExpressionを例えばA + Bまたは(N * 3)<5等が挙げられます。

        ③メソッド呼出し式:MethodCallExpression、例えば、カスタムアクションORDERBY LINQプロバイダの実装を。

        ④定数式:ConstantExpression例えば5つの値。

        条件式と⑤の操作:ConditionExpression

   多くは、私たちが説明していない、MSDNを見ることができる、があります。

   以下は簡単な例、またはトラックへのブレークポイントの道の使用を与えます 

    

        public void Btn_LambdaDemo1_Click()
        {
            Func<int, bool> test = n => (n * 3) < 5;

            Expression<Func<int, bool>> filter = n => (n * 3) < 5;        
                      
        }
    プログラムから見ることができ、フィルタはテストラムダ式で使用されたN =>(N * 3)<5が、ラムダ式は、ツリーデータ構造として表される式フィルタを使用して、我々は、以下のプログラムを実行し違いが何であるかを最終的にこれらの2を見てください。

    最初のブレークポイントまで実行されるプログラム


   この時点で試験フィルタは、第三のブレークポイントまでプログラム移動回F5空であり、そして以下に示すように、試験フィルターを展開します


  両方の大きな違いの内容は、前記ラムダ式を多く含むフィルタ(N =>(N * 3)<5)は、ボディ本体は(n * 3)などの情報、、、上の図から分かるように<図5は、戻り値の型は、1つのパラメータがあり、BoolenがReturnTypeタイプです。図のように、フィルタ本体を展開します。


   あなたがn * 3、ボディ5、あるノードタイプ<LessThanなど、情報量に大きな発言権の右側としての体を見ることができます左の内側に体を見ることができます。

   直感的なプレゼンテーション機能の式ツリーによって、以下の内部情報

   

    public class VMLambdaStudyDemo1
    {
        
        public void Btn_LambdaDemo1_Click()
        {
            Func<int, bool> 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);
                      
        }

    }
     ブレークポイントは、それを追跡し、自分自身を見ることができ、私は彼が言った良いトラブルのスクリーンショットを示すものではありません。ここでは、プログラムの結果があります


    上記の例では、視覚的にこの文、再びたとえば、深い印象「木のようなラムダ式は、私たちは(そのような読み取りと変更)データを処理するようにラムダ式に対処することができます」と表示することができます。

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"); //创建一个表达式树中的参数,作为一个节点,这里是最下层的节点
            ParameterExpression b = Expression.Parameter(typeof(int), "j");
            BinaryExpression be = Expression.Multiply(a, b);  //这里i*j,生成表达式树中的一个节点,比上面节点高一级

            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);   //运算两个中级节点,产生终结点

            Expression<Func<int, int, int, int, int>> lambda = Expression.Lambda<Func<int, int, int, int, int>>(su, a, b, c, d);

            Func<int, int, int, int, int> f = lambda.Compile();  //将表达式树描述的lambda表达式,编译为可执行代码,并生成该lambda表达式的委托;

            System.Windows.MessageBox.Show("lambda:" + lambda + "Result:" + f(1, 1, 1, 1));
        }

    }

}

実行結果


コードのセクションの図ラムダ式のツリー構造、学生張の直接使用


この絵と一緒にコードを見て、慎重な理解の下で、より徹底的に理解することができるはずです。

エピローグ

   ルは、私は、行く限り、ノックコードよりも疲れて多くをノック、ここでノック、私のラムダは比較的理解ですが、考えて、それを使用するのでしょうか?答:いいえ!

   保護された無効RaisePropertyChanged <T>(式<のFunc <T >> propertyExpression)の次のNotificationObject見てしかし、すべての権利、学習しながら、準備ができて


公開された143元の記事 ウォンの賞賛161 ビュー121万+

おすすめ

転載: blog.csdn.net/mybelief321/article/details/44465845