一般我们学习C#说到匿名函数的时候,都会谈到Lambda表达式。其实Lambda表达式就是匿名函数更为简洁的一种写法,这个概念是来自函数式编程,很多语言都加入了这个功能。 通俗点讲,你需要写一个函数,但是懒得给它起名字,而且懒得写那么多封装和类,并且可能就这个地方调用,其他地方几乎不调用这段代码,那么我就可以用这个来搞定。 注:在C#2.0中,通过匿名方法,使委托的实现得到了极大的简化。但是匿名方法仍然有些臃肿,而且当代码中充满了匿名方法的时候,可读性就会受到影响。C#3.0中出现的Lambda表达式在不牺牲可读性的前提下,进一步简化了委托。 Lambda运算符: “=>”运算符将表达式分为两部分,左边指定输入参数,右边是Lambda的主体,表达式或语句块。 Lambda表达式: 一个参数:param =>expr 多个参数:(param-list)=> expr Lambda的应用: using System.Collections.Generic; using System.Linq; using System; namespace LambdaSample01 { internal class Person { public string Name { get; set; } public int Age { get; set; } public override stringToString() { returnstring.Format("Name:{0},Age{1}",Name, Age); } } class Program { privatestatic List<Person> GetPersonList() { List<Person> lst = newList<Person>(); for(int i = 0; i < 7; i++) { Personp; if(i%2 == 0) p = new Person() {Name = i + "儿子", Age = 8 - i}; else p = new Person() {Name = i + "女儿", Age = 8 - i}; lst.Add(p); } returnlst; } static void Main(string[]args) { List<Person> persons = GetPersonList(); Action<Person> printer = person => Console.WriteLine(person.ToString()); persons.ForEach(printer); Console.WriteLine("-------------------"); //所有Age>6的Person的集合 List<Person> person1 = persons.Where(delegate(Person p){ return p.Age > 6; }).ToList(); person1.ForEach(printer); Console.WriteLine("-------------------"); List<Person> person2 = persons.Where(p => p.Age> 6).ToList(); person2.ForEach(printer); Console.WriteLine("-------------------"); //所有Name包含儿子的Person的集合 List<Person> person3 = persons.Where(p =>p.Name.Contains("儿子")).ToList(); person3.ForEach(printer); Console.WriteLine("-------------------"); //Age = 4的单个People Personper = persons.SingleOrDefault(p => p.Age == 4); Console.WriteLine(per); Console.WriteLine("-------------------"); //使用Lambda表达式对List<T>进行排序 persons.Sort((per1, per2) =>per1.Age.CompareTo(per2.Age)); persons.ForEach(printer); } } } 见代码:LambdaSample01.cs 看了上面的例子,相信你能看出它确实是个甜枣,Lambda表达式是由.Net2.0演化而来,也是LINQ的基础,熟练地掌握Lambda表达式能够快速上手LINQ应用开发(LINQ的基本功能就是创建操作管道,以及这些操作需要的任何状态。这些操作表示了各种关于数据的逻辑,例如数据筛选,数据排序等等。通常这些操作都是用委托来表示。Lambda表达式是对LINQ数据操作的一种符合语言习惯的表示方式。),下面我们来看看(p => p.Age > 6)这样的表达式,到底是怎么回事。 注: List<Person> person1= persons.Where(delegate(Person p) { returnp.Age > 6; }).ToList(); List<Person> person2= persons.Where(p => p.Age > 6).ToList(); 从这里可以看出Lambda表达式在编写的格式上和匿名方法非常相似。其实,当编译器开始编译并运行时,Lambda表达式最终也表现为匿名方法。使用匿名方法并不是创建了没有名称的方法,实际上编译器会创建一个方法,这个方法对开发人员来说是不可见的,该方法会将Person类的对象返回并填充到集合中。相同地,使用Lambda表达式,当编译器编译时,Lambda表达式同样会被编译成一个匿名方法进行响应的操作,但是与匿名方法相比,Lambda表达式更容易阅读。 首先,我们要看下委托: using System; namespace LambdaSample02 { delegate int Algorithm1(int a); delegate void Algorithm2(int a, int b); class Program { static void Main(string[]args) { //普通委托 Algorithm1zw1 = JieZhang; //利用委托来写匿名函数 Algorithm2zw2 = delegate(inta, int b) { Console.WriteLine("{0}*{1}={2}", a, b, a*b); }; Console.WriteLine(zw1(10)); zw2(10, 20); } privatestatic intJieZhang(int a) { returna + 10; } } } 见代码:LambdaSample02.cs 再看表达式: using System; namespace LambdaSample03 { delegate int Algorithm1(int a); delegate void Algorithm2(int a, int b); class Program { static void Main(string[]args) { //利用Lambda表达式来写一模一样的功能 Algorithm1zw1 = p => p + 10; Algorithm2zw2 = (p, q) => Console.WriteLine("{0}*{1}={2}", p, q, p*q); Console.WriteLine(zw1(10)); zw2(10, 20); } } } 见代码:LambdaSample03.cs 委托跟表达式的两段代码,我们可以看出,可以将Lambda表达式分配给委托,表达式(p => p+10;)中的p就是代表委托方法中的参数,而表达式符号右边的p+10,就是委托方法中的返回结果。 下面再上两个稍微复杂点的理解一下: 1.Lambda主体运算复杂 using System; namespace LambdaSample05 { class Program { privatedelegate int GuangChaoShi(inta, int b); static void Main(string[]args) { GuangChaoShizw1 = (p, q) => { constint min = 10; if(p < min) return 100; else return q - p - 10; }; Console.WriteLine(zw1(10,100)); } } } 见代码:LambdaSample05.cs 注意:匿名函数的参数和返回值必须要和委托一样。 2.综合例子 using System; using System.Collections.Generic; namespace LambdaSample04 { class Program { static void Main(string[]args) { Console.WriteLine("传统的委托代码示例:"); FindListDelegate(); Console.WriteLine("使用匿名方法代码示例:"); FindAnonymousMethod(); Console.WriteLine("使用Lambda表达式代码示例:"); FindLambdaExpression(); } privatestatic voidFindListDelegate() { List<string> list = newList<string>(); list.AddRange(new string[] {"ASP.NET课程", "J2EE课程","PHP课程","数据结构与算法"}); Predicate<string> findPredicate = IsBookCategory; List<string> bookCategory =list.FindAll(findPredicate); foreach(string str inbookCategory) { Console.WriteLine("{0}\t", str); } } privatestatic boolIsBookCategory(string str) { returnstr.EndsWith("课程") ? true : false; } privatestatic voidFindAnonymousMethod() { List<string> list = newList<string>(); list.AddRange(new string[] { "ASP.NET课程", "J2EE课程", "PHP课程", "数据结构与算法" }); List<string> bookCategory = list.FindAll( delegate(string str) { return str.EndsWith("课程") ? true : false; }); foreach(string str inbookCategory) { Console.WriteLine("{0}\t", str); } } privatestatic voidFindLambdaExpression() { List<string> list = newList<string>(); list.AddRange(new string[] { "ASP.NET课程", "J2EE课程", "PHP课程", "数据结构与算法" }); List<string> bookCategory = list.FindAll( p => p.EndsWith("课程") ? true: false); foreach(string str inbookCategory) { Console.WriteLine("{0}\t", str); } } } } 见代码:LambdaSample04.cs Func<TResult>委托: TResult是参数类型,这是一个泛型类型的委托。 先上例子: using System; namespace LambdaSample06 { class Program { static void Main(string[]args) { //使用C# 2.0中的匿名方法获取字符串长度 Func<string, int>strLength = delegate(stringstr) { returnstr.Length; }; Console.WriteLine(strLength("Hello World")); //使用Lambda表达式 //(显示类型参数列表) => {语句},Lambda表达式最冗长版本 strLength = (string str) => { returnstr.Length; }; Console.WriteLine(strLength("Hello World")); //单一表达式作为主体 //(显示类型参数列表) => 表达式 strLength = (string str) => str.Length; Console.WriteLine(strLength("Hello World")); //隐式类型的参数列表 //(隐式类型参数列表) => 表达式 strLength = (str) => str.Length; Console.WriteLine(strLength("Hello World")); //单一参数的快捷语法 //参数名 => 表达式 strLength = str => str.Length; Console.WriteLine(strLength("Hello World")); Func<int, string> zw1 =p => p + 10 + "--返回类型为string."; Console.WriteLine(zw1(10)); } } } 见代码:LambdaSample06.cs 说明:我们可以看到,这里的p为int类型参数,然而Lambda主体返回的是string类型的。 再上一个例子: using System; namespace LambdaSample07 { class Program { static void Main(string[]args) { Func<int, int, bool> zw1 = (p, j) => { if(p + j == 10) return true; else return false; }; Console.WriteLine(zw1(5,5)); } } } 见代码:LambdaSample07.cs 说明:从这个例子,我们看到,p为int类型,j为int类型,返回值bool类型。 Func<T>的用法:多个参数,前面的为委托方法的参数,最后一个参数,为委托方法的返回类型。 通过微信学习的知识只能是碎片化的知识,作为新时代的我们希望能够构建自己的知识结构,使我们的知识体系化,系统化,以后在遇到碎片化的知识,我们做的只是融合到自己的知识结构中,故我们将推出“与LSGO一起学”系列课程,帮助大家来构建知识框架,初步规划有:
如果对这些内容感兴趣,可以一起来学习讨论。 我们的官网: www.lsgogroup.com
|
|