Lambda, λ 表达式,xilazimu

Lambda表达式实际上是一个匿名函数。它包含表达式和语句,常用于创建委托或表达式目录树类型。所有Lambda表达式都是用Lambda运算符---------- =>,该运算符读为“goesto”。Lambda运算符的左边是输入参数(可能没有),右边是表达式或语句块。Lambda表达式返回右边表达式的结果。其基本格式如下:

(input paramenters)=>expression

其中,parameters是一个参数列表,在Lambda只有一个输入参数时可以不适用括号,否则括号是必须的。两个或更多输入参数由括在括号中的逗号分隔,如以下代码所示,包括两个参数x和y。

(x,y)=> x==y

通常Lambda表达式的参数都是可变类型的,由编译器自动确定它的具体类型。但有时编译器难于或无法推断输入类型,就需要为参数显示指定类型,既在参数之前添加参数类型。如下所示的Lambda表达式包括连个参数x和s。其中x是int类型,而s则是string类型。

(int x, string s) =>s.Length > x

当Lanbda表达式没有参数时,需要使用空的括号表示,如下所示。其中,“()”表示没有参数,而Amethod()是一个具体的方法,该方法的返回值就是Lambda表达式的结果。

() => AMethod()

由于Lambda表达式实际是匿名函数,它可以赋值到一个委托,而在IEnumerable<T>的方法中很多都通过函数委托来实现自定义的运算、条件等操作,所以Lambda表达式在Linq中被广泛使用。


.NET 3.x新特性之Lambda表达式

lambda 表达式格式为:
(参数列表) => 表达式或者语句块
分为三个步骤
1、(参数列表):
2、=>符号可以理解为从
3、表达式或者语句块

可以有多个参数,一个参数,或者无参数。参数类型可以隐失或者显示。例如:
(x,y) => x * y    //多参数,隐式类型=>表达式
x => x * 10    //单参数,隐式类型=>表达式
x => {return x * 10;}   //单参数,隐失类型=>语句块
(int x) => x * 10   //单参数,显示类型=>表达式
(int x) => {return x * 10} //单参数,显示类型=>语句块
() => Console.WriteLing() //无参数

 

Lambda表达式其实是一个委托类型实例,编译器会根据参数的类型建立一个同类型的同参数的委托:
比如
x => x * 10 
相当于是下面一个委托类型的实例
delegate int MyDeg(int i);//这个是由编译器根据推断出的类型而建立的
只不过这些工作由编译器帮我们做了

 

Lambda 表达式格式要点
- Lambda表达式的参数类型可以忽略,因为可以根据使用的上下文进行推断。
- Lambda表达式的主体(body)可以是表达式,也可以是语句块。
- Lambda表达式传入的实参将参与类型推断,以及方法重载辨析。
- Lambda表达式和表达式体可以被转换为表达式树。

 

Lambda 表达式与委托类型
Lambda 表达式L可以被转换为委托类型D,需要满足以下条件:
- L和D拥有相同的参数个数。
- L的参数类型要与D的的参数类型相同。注意隐式类型要参与类型辨析。
- D的返回类型与L相同,无论L是表达式,还是语句块。

下面我们来看一下编译器到底都做了些什么?
比如在程序中有下面Lambda表达式:
delegate bool Mydelegate(string s);
class jh
{
    public static Process(Mydelegate myd)
        { 
            myd("wo shi jhxz");
        }
}
jh.Process(s => s.Indexof("jhxz") > 0) //Process方法接受一个Mydelegate的委托

编译其实有Lambda表达式那条语句编译为以下这样的代码:
Mydelegate md=new Mydelegate(IsValidXXXX);//编译器生成
jh.Process(md1)
public static bool IsValidXXXX(string s)//编译器生成
{
  return s.Indexof("jhxz") > 0;
}

 

 

体验:
1.准备测试数据
static int[] numbers = new int[] { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };
static string[] strings = new string[] { "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine"};
class Person {
public string Name;
public int Level;
}
static Person[] persons = new Person[] {
new Person {Name="Matt", Level=3},
new Person {Name="Luca", Level=3},
new Person {Name="Jomo", Level=5},
new Person {Name="Dinesh", Level=3},
new Person {Name="Charlie", Level=3},
new Person {Name="Mads", Level=3},
new Person {Name="Anders", Level=9}
};
2.过滤数据
public static void Sample1() {
// use Where() to filter out elements matching a particular condition       
        IEnumerable<int> fnums = numbers.Where(n => n < 5);
Console.WriteLine("Numbers < 5");
foreach(int x in fnums) {
Console.WriteLine(x);
}
}
3.匹配首个字母
public static void Sample2() {
// use First() to find the one element matching a particular condition 
        string v = strings.First(s => s[0] == 'o');
Console.WriteLine("string starting with 'o': {0}", v);
}
4.根据numbers排序
public static void Sample3() {
// use Select() to convert each element into a new value
        IEnumerable<string> snums = numbers.Select(n => strings[n]);
Console.WriteLine("Numbers");
foreach(string s in snums) {
Console.WriteLine(s);
}
}
5.匿名类型,注意var关键字
public static void Sample4()
{
// use Anonymous Type constructors to construct multi-valued results on the fly
        var q = strings.Select(s => new {Head = s.Substring(0,1), Tail = s.Substring(1)});
foreach(var p in q) {
Console.WriteLine("Head = {0}, Tail = {1}", p.Head, p.Tail);
}
}
6.联合查询(即使用两个以上的查询条件)
public static void Sample5() {
// Combine Select() and Where() to make a complete query
        var q = numbers.Where(n => n < 5).Select(n => strings[n]);
Console.WriteLine("Numbers < 5");
foreach(var x in q) {
Console.WriteLine(x);
}
}
7.使用ToList方法
public static void Sample6() {
// Sequence operators form first-class queries are not executed until you enumerate them.
        int i = 0;
var q = numbers.Select(n => ++i);
// Note, the local variable 'i' is not incremented until each element is evaluated (as a side-effect).
        foreach(var v in q) {
Console.WriteLine("v = {0}, i = {1}", v, i);
}
Console.WriteLine();
// Methods like ToList() cause the query to be executed immediately, caching the results
        int i2 = 0;
var q2 = numbers.Select(n => ++i2).ToList();
// The local variable i2 has already been fully incremented before we iterate the results
        foreach(var v in q2) {
Console.WriteLine("v = {0}, i2 = {1}", v, i2);
}
}
8.分组查询
public static void Sample7() {
// use GroupBy() to construct group partitions out of similar elements
        var q = strings.GroupBy(s => s[0]); // <- group by first character of each string

foreach(var g in q) {
Console.WriteLine("Group: {0}", g.Key);
foreach(string v in g) {
Console.WriteLine("\tValue: {0}", v);
}
}
}
9.统计聚合
public static void Sample8() {
// use GroupBy() and aggregates such as Count(), Min(), Max(), Sum(), Average() to compute values over a partition
        var q = strings.GroupBy(s => s[0]).Select(g => new {FirstChar = g.Key, Count = g.Count()});
foreach(var v in q) {
Console.WriteLine("There are {0} string(s) starting with the letter {1}", v.Count, v.FirstChar);
}
}
10.排序
// use OrderBy()/OrderByDescending() to give order to your resulting sequence
        var q = strings.OrderBy(s => s); // order the strings by their name

foreach(string s in q) {
Console.WriteLine(s);
}
}
11.二次排序
public static void Sample9a() {
// use ThenBy()/ThenByDescending() to provide additional ordering detail
        var q = persons.OrderBy(p => p.Level).ThenBy(p => p.Name);
foreach(var p in q) {
Console.WriteLine("{0} {1}", p.Level, p.Name);
}
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
编译原理是计算机专业的一门核心课程,旨在介绍编译程序构造的一般原理和基本方法。编译原理不仅是计算机科学理论的重要组成部分,也是实现高效、可靠的计算机程序设计的关键。本文将对编译原理的基本概念、发展历程、主要内容和实际应用进行详细介绍编译原理是计算机专业的一门核心课程,旨在介绍编译程序构造的一般原理和基本方法。编译原理不仅是计算机科学理论的重要组成部分,也是实现高效、可靠的计算机程序设计的关键。本文将对编译原理的基本概念、发展历程、主要内容和实际应用进行详细介绍编译原理是计算机专业的一门核心课程,旨在介绍编译程序构造的一般原理和基本方法。编译原理不仅是计算机科学理论的重要组成部分,也是实现高效、可靠的计算机程序设计的关键。本文将对编译原理的基本概念、发展历程、主要内容和实际应用进行详细介绍编译原理是计算机专业的一门核心课程,旨在介绍编译程序构造的一般原理和基本方法。编译原理不仅是计算机科学理论的重要组成部分,也是实现高效、可靠的计算机程序设计的关键。本文将对编译原理的基本概念、发展历程、主要内容和实际应用进行详细介绍编译原理是计算机专业的一门核心课程,旨在介绍编译程序构造的一般原理和基本

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值