C# 初学Lambda表达式

抄自:https://www.cnblogs.com/leslies2/archive/2012/03/22/2389318.html

一、Lambda 的意义

在Framework 2.0 以前,声明委托的唯一方法是通过方法命名,从Framework 2.0 起,系统开始支持匿名方法。通过匿名方法,可以直接把一段代码绑定给事件,因此减少了实例化委托所需的编码系统开销。而在 Framework 3.0 开始,Lambda表达式开始逐渐取代了匿名方法,作为编写内联代码的首选方式。
总体来说,Lambda 表达式的作用是为了使用更简单的方式来编写匿名方法,彻底简化委托的使用方式。

二、回顾匿名方法的使用

简单回顾一下

static void Main(string[] args)
        {
            #region 事件的使用及方法绑定
            PersonManager personManager = new PersonManager();
            //绑定事件处理方法方式一
            personManager.MyEvent += new MyDelegate(GetName);
            //绑定事件处理方法方式二
            personManager.MyEvent += GetName;
            //绑定事件处理方法方式三(匿名方法)
            personManager.MyEvent += delegate (string name) { Console.WriteLine("My name is " + name); };
            personManager.Execute("Atomy");
            Console.Read();
            #endregion
        }

总是使用 delegate(){…} 的方式建立匿名方法,令人不禁感觉郁闷。于是从Framework 3.0起,Lambda表达式开始出现。

三、简单介绍泛型委托

在介绍Lambda表达式前,先介绍一下常用的几个泛型委托。

3.1 泛型委托 Predicate

早在Framework 2.0的时候,微软就为List类添加了Find、FindAll、ForEach等方法用作数据的查找。

public T Find ( Predicate<T> match)
public List<T> FindAll(Predicate<T>  match)

在这些方法中存在一个Predicate 表达式,它是一个返回bool的泛型委托,能接受一个任意类型的对象作为参数。

public delegate bool Predicate<T>T obj)

在下面例子中,Predicate委托绑定了参数为Person类的方法Match作为查询条件,然后使用FindAll方法查找到合适条件的List集合。

class Program
    {
        #region 泛型委托 Predicate<T>
        /// <summary>
        /// Person类
        /// </summary>
        class Person
        {
            public int Id { get; set; }
            public string Name { get; set; }
            public int Age { get; set; }

            public Person(int id, string name, int age)
            {
                Id = id;
                Name = name;
                Age = age;
            }
        }

        /// <summary>
        /// 数据源
        /// </summary>
        /// <returns></returns>
        static List<Person> GetList()
        {
            var personList = new List<Person>();
            var person = new Person(1, "Hello", 29);
            personList.Add(person);
            person = new Person(1, "World", 31);
            personList.Add(person);
            return personList;
        }

        /// <summary>
        /// 查询条件
        /// </summary>
        /// <param name="person"></param>
        /// <returns></returns>
        static bool Match(Person person)
        {
            return person.Age <= 30;
        }
        #endregion

        static void Main(string[] args)
        {
            #region 泛型委托 Predicate<T>
            List<Person> list = GetList();
            //绑定查询条件
            Predicate<Person> predicate = new Predicate<Person>(Match);
            List<Person> result = list.FindAll(predicate);
            Console.WriteLine($"Person count is : {result.Count}");
            Console.Read();
            #endregion
        }
    }

运行结果如下:
在这里插入图片描述

3.2 泛型委托 Action

Action 的使用方式与 Predicate 相似,不同之处在于 Predicate 返回值为 bool , Action 的返回值为 void。

Action 支持0~16个参数,可以按需求任意使用。

public delegate void Action()

public delegate void Action (T1 obj1)

public delegate void Action<T1,T2> (T1 obj1, T2 obj2)

public delegate void Action<T1,T2,T3> (T1 obj1, T2 obj2,T3 obj3)

............

public delegate void Action<T1,T2,T3,…,T16> (T1 obj1, T2 obj2,T3 obj3,…,T16 obj16)

下面代码演示泛型委托Action:
class Program
    {
        #region 泛型委托 Func
        static double Account(double a, bool condition)
        {
            if (condition)
                return a * 1.5;
            else
                return a * 2;
        }
        #endregion

        static void Main(string[] args)
        {
            #region 泛型委托 Func
            Func<double, bool, double> func = Account;
            double result = func(1000, true);
            Console.WriteLine($"Result is : {result}");
            Console.Read();
            #endregion
        }
    }

运行结果如下:
在这里插入图片描述

四、揭开 Lambda 神秘的面纱

Lambda的表达式的编写格式如下:x=> x * 1.5

当中 “ => ”是Lambda表达式的操作符,在左边用作定义一个参数列表,右边可以操作这些参数。

例子一:先把int x设置1000,通过Action把表达式定义为x=x+500,最后通过Invoke激发委托。

class Program
    {
        static void Main(string[] args)
        {
            #region Lambda例子一
            int x = 1000;
            Action action = () => x = x + 500;
            action.Invoke();

            Console.WriteLine($"Result is : {x}");
            Console.Read();
            #endregion
        }
    }

运行结果如下:在这里插入图片描述
例子二:通过Action把表达式定义x=x+500,到最后输入参数1000,得到的结果与例子一相同。

注意,此处Lambda表达式定义的操作使用{ }括弧包括在一起,里面可以包含一系列的操作。

class Program
    {
        static void Main(string[] args)
        {
            #region Lambda例子二
            Action<int> action = (x) =>
            {
                x = x + 500;
                Console.WriteLine($"Result is : {x}");
            };
            action.Invoke(1000);
            Console.Read();
            #endregion
        }
    }

运行结果如下:在这里插入图片描述
例子三:定义一个Predicate,当输入值大约等于1000则返回true,否则返回false。与3.1的例子相比,Predicate的绑定不需要显式建立一个方法,

而是直接在Lambda表达式里完成,简洁方便了不少。


    class Program
    {
        static void Main(string[] args)
        {
            #region Lambda例子三
            Predicate<int> predicate = (x) =>
            {
                if (x >= 1000)
                    return true;
                else
                    return false;
            };
            bool result = predicate.Invoke(500);
            Console.WriteLine($"Result={result}");
            Console.Read();
            #endregion
        }
    }

运行结果如下:

在这里插入图片描述

例子四:在计算商品的价格时,当商品重量超过30kg则打9折,其他按原价处理。此时可以使用Func<double,int,double>,参数1为商品原价,参数2为商品

重量,最后返回值为 double 类型。

class Program
    {
        static void Main(string[] args)
        {
            #region Lambda例子四
            Func<double, int, double> func = (price, weight) =>
            {
                if (weight >= 30)
                    return price * 0.9;
                else
                    return price;
            };
            double totalPrice = func(200.0, 40);
            Console.WriteLine($"TotalPrice={totalPrice}");
            Console.Read();
            #endregion
        }
    }

运行结果如下
在这里插入图片描述
例子五:使用Lambda为Button定义Click事件的处理方法,使用Lambda比使用匿名方法更加简单。

public partial class Main : Form
    {
        public Main()
        {
            InitializeComponent();
        }

        private void Main_Load(object sender, EventArgs e)
        {
            #region Lambda例子五
            btnEvent.Click += (obj,arg)=>
            {
                MessageBox.Show("Hello World");
            };
            #endregion
        }
    }

运行结果如下:
在这里插入图片描述
例子六:此处使用3.1的例子,在List的FindAll方法中直接使用Lambda表达式。相比之下,使用Lambda表达式,不需要定义Predicate对象,也

不需要显式设定绑定方法,简化了不工序。

class Program
    {
        #region 泛型委托 Predicate<T>
        /// <summary>
        /// Person类
        /// </summary>
        class Person
        {
            public int Id { get; set; }
            public string Name { get; set; }
            public int Age { get; set; }

            public Person(int id, string name, int age)
            {
                Id = id;
                Name = name;
                Age = age;
            }
        }

        /// <summary>
        /// 数据源
        /// </summary>
        /// <returns></returns>
        static List<Person> GetList()
        {
            var personList = new List<Person>();
            var person = new Person(1, "Hello", 29);
            personList.Add(person);
            person = new Person(1, "World", 31);
            personList.Add(person);
            return personList;
        }

        /// <summary>
        /// 查询条件
        /// </summary>
        /// <param name="person"></param>
        /// <returns></returns>
        static bool Match(Person person)
        {
            return person.Age <= 30;
        }
        #endregion

        static void Main(string[] args)
        {
            #region Lambda例子六
            List<Person> personList = GetList();
            //查找年龄少于30年的人
            List<Person> result = personList.FindAll((person) => person.Age <= 30);
            Console.WriteLine("Person count is : " + result.Count);
            Console.Read();
            #endregion
        }
    }

运行结果如下:在这里插入图片描述
在使用LINQ技术的时候,到处都会弥漫着Lambda的身影,此时更能体现Lambda的长处。但LINQ涉及到分部类、分部方法、IEnumerable、迭代器等

多方面的知识,这些已经超出本章的介绍范围。通过这一节的介绍,希望能够帮助大家更深入地了解Lambda的使用。

转载自:https://www.cnblogs.com/atomy/p/12080368.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值