• 匿名方法与Lambda表达式


    1.匿名方法

    在学习委托时,我们知道委托实例至少要绑定一个方法才能使用,而调用委托实际上是调用了它所关联地方法。一般来说,需要定义一个与委托签名相符的方法,并使之与委托变量关联。如以下代码:

    Action deleg=new Action(CallMethod);//声明并实例化委托变量

    private static void CallMethod()//与委托关联的方法

    {.........}

    会发现以上写法并不简洁,因此引入了“匿名方法”,它不需要命名,用一个delegate关键字代表方法的名字,没有访问修饰符,也不需要返回类型。

    例如上面的例子可以简写如下:

    Action deleg=delegate()

    {........};

    当委托既有参数又有返回值的时候,匿名方法中就也要相应定义参数,如果委托的签名中有返回值,则在匿名方法中就直接使用return返回即可,如下实例:

    Func<int,int,int> f=delegate(int x,int y)

    { return x+y;};

    int result=f(1+2);//调用委托

    其实上例所用的委托的原型如下:delegate TResult Func<in T1,in T2,out TResult>(T1 x,T2 y);

    如果委托要关联地方法在代码中没有重复使用,使用匿名方法会非常方便,当方法在代码中多个地方都用到,就不应该在使用匿名方法。

    2.Lambda表达式

    Lambda表达式其实就是更为简洁的匿名方法表示法,以“=>”作为分隔符,其左边为匿名方法的参数列表,右边为匿名方法的语句,即:(参数列表)=><语句>

    对于没有参数的委托,Lambda表达式如下:()=><语句>

         2.1 Lambda表达式用于给委托变量赋值

         (1)对于没有参数,返回值为void类型的委托

          Action a=()=>{/*........*/};

          如果“=>”右边只有一句代码,则可以省略大括号,写出:Action a=()=>Console.WriteLine("");

         (2)对于有参数的委托

         Action<string,int> a=(string name,int age)=>Console.WriteLine("");

         由于Lambda表达式可以根据委托来识别参数类型,所以可以省略(string name,int age)中的参数类型。

         (3)对于有返回值的委托(非void类型),则直接用return 返回即可。

         Func<int,int ,int> a=(a,b)=>{return a*b;};

         如果“=>”后边只有一句代码,可以吧return和大括号省略,如下所示:

         Func<double, string> a=(n)=>n.ToString("C2");

         2.2 Lambda表达式用于参数传递

         比如.NET类库的许多扩展方法以及LINQ表达式都可以使用Lambda表达式传递参数。示例代码:

         

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace Test
    {
        #region 定义类型
        public class Student
        {
            public string Name { get; set; }
            public int Age { get; set; }
            public DateTime Date { get; set; }
        }
        #endregion
    
        class Program
        {
            static void Main(string[] args)
            {
                List<Student> stus = new List<Student>();
                stus.Add(new Student { Name = "小王", Age = 22, Date = new DateTime(2012, 9, 22) });
                stus.Add(new Student { Name = "小刘", Age = 23, Date = new DateTime(2013, 1, 10) });
                stus.Add(new Student { Name = "小红", Age = 21, Date = new DateTime(2012, 3, 2) });
                
                // 将学员的入学日期按升序排序
                var res = stus.OrderBy(stu => stu.Date);
                Console.WriteLine("学员的入学日期按升序排序:");
                foreach (Student s in res)
                {
                    Console.WriteLine("姓名:{0},年龄:{1},入学日期:{2:yyyy-M-d}", s.Name, s.Age, s.Date);
                }
                Console.ReadKey();
            }
        }
    }

    以上代码使用了OrderBy扩展方法的以下重载:

    public static IOrderedEnumerble<TSource> OrderBy<TSource,TKey>(this IEnumerble<TSource> source,Func<TSource,TKey> keySelector);

    在调用时,主要关注keySelector参数,因为第一个参数是要扩展的类型,由编译器调用。keySelector参数是Func<TSource,TKey>,输入类型为TSource,TKey是要返回的值,OrderBy方法将根据TKey来进行排序。实例中,stu会自动识别为Student类型,“=>”右边直接将stu的Date属性值返回,OrderBy方法通过调用传递给keySelector参数的委托来获取每个Student实例的Date属性值,以便进行排序。

  • 相关阅读:
    程序员之痛:几千行代码能搞定的为什么要写几万行?
    python基础===新式类与经典类
    python基础===装饰器@property 的扩展
    java===java基础学习(16)---final
    java===java基础学习(15)---抽象,接口
    python基础===继承和多继承
    python基础===类的私有属性(伪私有)
    python基础===创建大量对象是节省内存方法
    java===java习题---Josephu问题
    java===java基础学习(14)---封装
  • 原文地址:https://www.cnblogs.com/czx1/p/4892672.html
Copyright © 2020-2023  润新知