本笔记摘抄自:https://www.cnblogs.com/leslies2/archive/2012/03/22/2389318.html,记录一下学习过程以备后续查用。

    一、Lambda 的意义

在Framework 2.0 以前,声明委托的唯一方法是通过方法命名,从Framework 2.0 起,系统开始支持匿名方法。通过匿名方法,可以直接把一段代码绑定

给事件,因此减少了实例化委托所需的编码系统开销。而在 Framework 3.0 开始,Lambda表达式开始逐渐取代了匿名方法,作为编写内联代码的首选方式。

总体来说,Lambda 表达式的作用是为了使用更简单的方式来编写匿名方法,彻底简化委托的使用方式。

二、回顾匿名方法的使用

匿名方法的使用在C#委托与事件学习笔记中有简单介绍过,在此回顾一下:

        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<T>

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

public T Find ( Predicate<T> match)

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

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

public delegate bool Predicate<T>(T obj)

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

    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(, "Hello", );
personList.Add(person);
person = new Person(, "World", );
personList.Add(person);
return personList;
} /// <summary>
/// 查询条件
/// </summary>
/// <param name="person"></param>
/// <returns></returns>
static bool Match(Person person)
{
return person.Age <= ;
}
#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<T> 的使用方式与 Predicate<T> 相似,不同之处在于 Predicate<T> 返回值为 bool ,  Action<T> 的返回值为 void。

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

public delegate void Action()

public delegate void Action<T1> (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 泛型委托 Action
static void ShowMessage(string message)
{
Console.WriteLine(message);
}
#endregion static void Main(string[] args)
{
#region 泛型委托 Action
Action<string> action = ShowMessage;
action("Hello World");
Console.ReadKey();
#endregion
}
}

运行结果如下:

    3.3 泛型委托 Func

委托Func与Action相似,同样支持0~16个参数,不同之处在于Func必须具有返回值。

public delegate TResult Func<TResult>()

public delegate TResult Func<T1,TResult>(T1 obj1)

public delegate TResult Func<T1,T2,TResult>(T1 obj1,T2 obj2)

public delegate TResult Func<T1,T2,T3,TResult>(T1 obj1,T2 obj2,T3 obj3)

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

public delegate TResult Func<T1,T2,T3,......,T16,TResult>(T1 obj1,T2 obj2,T3 obj3,......,T16 obj16)

下面代码演示泛型委托Func:

    class Program
{
#region 泛型委托 Func
static double Account(double a, bool condition)
{
if (condition)
return a * 1.5;
else
return a * ;
}
#endregion static void Main(string[] args)
{
#region 泛型委托 Func
Func<double, bool, double> func = Account;
double result = func(, 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 = ;
Action action = () => x = x + ;
action.Invoke(); Console.WriteLine($"Result is : {x}");
Console.Read();
#endregion
}
}

运行结果如下:

例子二:通过Action<int>把表达式定义x=x+500,到最后输入参数1000,得到的结果与例子一相同。

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

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

运行结果如下:

例子三:定义一个Predicate<int>,当输入值大约等于1000则返回true,否则返回false。与3.1的例子相比,Predicate<T>的绑定不需要显式建立一个方法,

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

    class Program
{
static void Main(string[] args)
{
#region Lambda例子三
Predicate<int> predicate = (x) =>
{
if (x >= )
return true;
else
return false;
};
bool result = predicate.Invoke();
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 >= )
return price * 0.9;
else
return price;
};
double totalPrice = func(200.0, );
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<Person>的FindAll方法中直接使用Lambda表达式。相比之下,使用Lambda表达式,不需要定义Predicate<T>对象,也

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

    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(, "Hello", );
personList.Add(person);
person = new Person(, "World", );
personList.Add(person);
return personList;
} /// <summary>
/// 查询条件
/// </summary>
/// <param name="person"></param>
/// <returns></returns>
static bool Match(Person person)
{
return person.Age <= ;
}
#endregion static void Main(string[] args)
{
#region Lambda例子六
List<Person> personList = GetList();
//查找年龄少于30年的人
List<Person> result = personList.FindAll((person) => person.Age <= );
Console.WriteLine("Person count is : " + result.Count);
Console.Read();
#endregion
}
}

运行结果如下:

当在使用LINQ技术的时候,到处都会弥漫着Lambda的身影,此时更能体现Lambda的长处。但LINQ涉及到分部类、分部方法、IEnumerable<T>、迭代器等

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

C# Lambda表达式学习笔记的更多相关文章

  1. java lambda表达式学习笔记

    lambda是函数式编程(FP,functional program),在java8中引入,而C#很早之前就有了.在java中lambda表达式是'->',在C#中是‘=>’. 杜甫说:射 ...

  2. lambda 表达式学习笔记

    在Java中传递一个代码段并不容易,不能直接传递代码段.Java是一个面向对象语言,所以必须构造一个对象,这个对象的类需要一个方法能包含所需的代码.lambda的出现有效的解决这个问题,让代码变得更加 ...

  3. python函数和lambda表达式学习笔记

    1. python函数 不同于其他语言,python支持函数返回多个值 为函数提供说明文档:help(函数名)或者函数名.__doc__ def str_max(str1, str2): ''' 比较 ...

  4. Lambda表达式学习笔记

    Lambda基础语法 Java8中引入了一个新的操作符" -> ",该操作符被称为箭头操作符或Lambda操作符,箭头操作符将Lambda表达式拆分成两部分: 左侧:Lamb ...

  5. C# Lambda 表达式学习之(三):动态构建类似于 c => c.Age == null || c.Age > 18 的表达式

    可能你还感兴趣: 1. C# Lambda 表达式学习之(一):得到一个类的字段(Field)或属性(Property)名,强类型得到 2. C# Lambda 表达式学习之(二):LambdaExp ...

  6. C# Lambda 表达式学习之(四):动态构建类似于 c => c.Age == 2 || c.Age == 5 || c => c.Age == 17 等等一个或多个 OrElse 的表达式

    可能你还感兴趣: 1. C# Lambda 表达式学习之(一):得到一个类的字段(Field)或属性(Property)名,强类型得到 2. C# Lambda 表达式学习之(二):LambdaExp ...

  7. Lamda表达式学习笔记二

    Lamda表达式学习笔记二 lamda表达式----方法引用 上一篇讲到Lamda体就是对函数式接口方法的实现 ,在方法体中我们可能会引用其他方法实现逻辑,所以在lamda体中我们可以直接引用器方法 ...

  8. Lamda表达式学习笔记一

    Lamda表达式学习笔记一 一.Lamda语法诠释 三傻大闹宝莱坞的主人公兰彻说的一句话让我映像深刻:用简单的语言来表达同样的意 我并不是说书上的定义怎么怎么不对,而是应该理解书本上的定义,并用简单的 ...

  9. java 8 中lambda表达式学习

    转自 http://blog.csdn.net/renfufei/article/details/24600507 http://www.jdon.com/idea/java/10-example-o ...

随机推荐

  1. 二项式反演/minmax容斥初探

    世界是物质的,物质是运动的,运动是有规律的,规律是可以被认识的 二项式反演 \[ g_n=\sum_{i=0}^n \binom{n}if_i\Rightarrow f_n=\sum_{i=0}^n( ...

  2. union和in哪个效率高

    一直都认为是in的效率要高,但是这次确有点蒙圈. SELECT * FROM runinfo WHERE status in (0,2,1,3,4,7,9,10); 这个查询的效率是,经常是1秒多. ...

  3. java线程的方便调用方式

    一直用java的线程,总感觉写起来阅读或书写起来不是方便,改进之. 实现类: public class Task<R> { private ExecutorService executor ...

  4. 怎样使用 v-html 指令?

    v-html 可以在目标节点位置内部插入 html 子节点, 跟节点的 .innerHTML 属性类似, 使用方法如下: <!DOCTYPE html> <html lang=&qu ...

  5. jsp其实是一个java类

    我们打开tomcat的D:\Program_Files\apache-tomcat-8.0.32\work\Catalina\localhost\venus\org\apache\jsp, 当我们访问 ...

  6. c#连接Java后台,处理返回的数据

    首先定义共通文件,根据url连接Java后台 class ConntectUtil { public JObject ConsoleApplication(string appID, CustomDa ...

  7. webmagic学习之路-3:采集安居客经纪人详情页

    这里希望安居客的同行的轻喷!!单纯的做测试,玩玩. 就这么糟践你们的服务器了!!!sorry! 这次学会了webmagic 设置处理的访问HTML返回代码,因为之前一直404的页面process根本都 ...

  8. NSIS MUI 的内置向导页面

    MUI 的内置向导页面和安装程序有关的向导页面MUI_PAGE_WELCOME 该向导页面显示欢迎信息MUI_PAGE_LICENSE text/rtf_file 该向导页面显示软件授权申明MUI_P ...

  9. bus事件总线传值

    import Vue from 'vue'   var bus = new Vue()   export default bus 监听事件: // header组件 <template> ...

  10. MYSQL 创建数据库以及表

    创建数据库,表 创建一个数据库,再在数据库下创建一个或多个表,不难,记不住的同学可以直接copy,慢慢的用会即刻,懂的同学请看代码,没有太多基础的同学,除了看代码,请看最下方的知识点 创建数据库: C ...