zoukankan      html  css  js  c++  java
  • C# in Depth Third Edition 学习笔记-- Lambda表达式和表达式树

    • 作为委托的Lambda表达式:

          Func<....>委托类型: 在.Net 3.5中有以下5个

    TResult Func<TResult>()
    TResult Func<T,TResult>(T arg)
    TResult Func<T1,T2,TResult>(T1 arg1, T2 arg2)
    TResult Func<T1,T2,T3,TResult>(T1 arg1, T2 arg2, T3 arg3)
    TResult Func<T1,T2,T3,T4,TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4)

        例如Func<string,double,int> 等价于public delegate int SomeDelegate(string arg1, double arg2)。

        如果感觉4个参数太少不够用,在.Net 4中Action<.......>和Func<....>最多可以拥有16个参数。

        

    // 使用匿名方法创建委托实例
    Func<string,int> returnLength;
    returnLength = delegate (string text) { return text.Length; };
    Console.WriteLine(returnLength("Hello"));
    
    
    // 第一个冗长的Lambda表达式
    Func<string,int> returnLength;
    returnLength = (string text) => { return text.Length; };
    Console.WriteLine(returnLength("Hello"));
    
    // (显示类型的参数列表)=>表达式
    (string text) => text.Length
    
    // (隐式类型的参数列表)=>表达式
      (text) => text.Length
    // 参数名=>表达式
    text => text.Length

    • 使用List<T>和事件的简单例子
    class Film
    {
    public string Name { get; set; }
    public int Year { get; set; }
    }
    ...
    var films = new List<Film>
    {
    new Film { Name = "Jaws", Year = 1975 },
    new Film { Name = "Singing in the Rain", Year = 1952 },
    new Film { Name = "Some like it Hot", Year = 1959 },
    new Film { Name = "The Wizard of Oz", Year = 1939 },
    new Film { Name = "It's a Wonderful Life", Year = 1946 },
    new Film { Name = "American Beauty", Year = 1999 },
    new Film { Name = "High Fidelity", Year = 2000 },
    new Film { Name = "The Usual Suspects", Year = 1995 }
    };
    Action<Film> print =
    film => Console.WriteLine("Name={0}, Year={1}",
    film.Name, film.Year);
    films.ForEach(print);
    films.FindAll(film => film.Year < 1960).ForEach(print); // 被编译成如下方法

    //private static bool SomeAutoGeneratedName(Film film)
    //{
    //return film.Year < 1960;
    //}

    films.Sort((f1, f2) => f1.Name.CompareTo(f2.Name));
    films.ForEach(print);
    • 表达式树Expression trees

         code as data将代码作为数据,JIT将IL代码视为数据,并把它们转换成能在某个cpu上运行的本地代码。

         以编程方式构建表达式树:

         表达式树由对象构成的树,树中每个节点本身就是一个表达式。不同的表达式类型代表能在代码中执行的不同操作:二元操作(例如加法),一元操作(例如获取一个数组的长度),方法调用,构造函数的调用,等等。

         一个简单的表达式树,2和3相加

    Expression firstArg = Expression.Constant(2);
    Expression secondArg = Expression.Constant(3);
    Expression add = Expression.Add(firstArg, secondArg);
    Console.WriteLine(add);

     在表达式树中叶子最先被创建:自下而上构建了这些表达式树。

       将表达式树编译成委托:(下面是类的继承关系)

    Expression firstArg = Expression.Constant(2);
    Expression secondArg = Expression.Constant(3);
    Expression add = Expression.Add(firstArg, secondArg);
    Func<int> compiled = Expression.Lambda<Func<int>>(add).Compile();
    Console.WriteLine(compiled());

    将C#lambda表达式转换成表达式树:(下面两段代码是等价的,第二个代码段是使用代码生成的第一个代码段的表达式)

    Expression<Func<string, string, bool>> expression =
    (x, y) => x.StartsWith(y);
    var compiled = expression.Compile();
    Console.WriteLine(compiled("First", "Second"));
    Console.WriteLine(compiled("First", "Fir"));
    MethodInfo method = typeof(string).GetMethod
    ("StartsWith", new[] { typeof(string) });
    var target = Expression.Parameter(typeof(string), "x");
    var methodArg = Expression.Parameter(typeof(string), "y");
    Expression[] methodArgs = new[] { methodArg };
    Expression call = Expression.Call(target, method, methodArgs);
    var lambdaParameters = new[] { target, methodArg };
    var lambda = Expression.Lambda<Func<string, string, bool>>
    (call, lambdaParameters);
    var compiled = lambda.Compile();
    Console.WriteLine(compiled("First", "Second"));
    Console.WriteLine(compiled("First", "Fir"));

    位于LINQ核心的表达式树:

  • 相关阅读:
    Fiddler抓包2-只抓APP的请求【转载】
    Fiddler抓包1-抓firefox上https请求【转载】
    python笔记-用python解决小学生数学题【转载】
    python笔记-冒泡排序【转载】
    python爬虫搜片利器fmovice【转载】
    httpd: Could not reliably determine the server's fully qualified domain name, using ::1 for ServerName
    linux_硬件信息
    Django rest framework:__str__ returned non-string (type NoneType) 真正原因
    centos如何安装python库?
    linux如何自动获取ip地址
  • 原文地址:https://www.cnblogs.com/aaronday/p/3881006.html
Copyright © 2011-2022 走看看