您的位置:知识库 »

C# 3.0新语言特性和改进(下篇)

作者: 李永京  来源: 博客园  发布时间: 2008-09-23 16:40  阅读: 6356 次  推荐: 0   原文链接   [收藏]  
摘要:总体来说,Visual Studio 2008和.NET 3.5是建立在.NET2.0核心的基础之上,C# 3.0新语言特性在.NET2.0基础上进行了改进,这些改进的功能可以大大简化我们编写程序。
[1] 扩展方法
[2] Lambda表达式和Lambda表达式树

Lambda表达式和Lambda表达式树 (Lambda Expression and Lambda Expression Trees)

Lambda表达式

我们从“所有字符串查找包含YJingLee子字符串”说起。在C# 2.0中,匿名方法允许我们以内联的方式来实现委托实例,它提供强大的函数式编程语言,但是标记显得相当的冗长和带有强制性。我们使用C# 2.0 中的匿名方法查找,代码如下:

var inString = list.FindAll(delegate(string s)
{ return s.Indexof("YJingLee") >= 0; });

现在可以使用C# 3.0带来的Lambda表达式允许我们使用一种更接近人的思维、更自然的方式来实现类似于匿名方法同样的效果,看下面的代码多么简洁:

var inString = list.FindAll(s => s.Indexof("YJingLee") >= 0);

Lambda表达式格式:(参数列表)=>表达式或语句块
具体意义:定义Lambda接受参数列表,运行表达式或语句块返回表达式或语句块的值传给这个参数列表。

Lambda表达式参数类型可以是隐式类型或显式类型。在显式列表中,每个参数的类型是显式指定的,在隐式列表中,参数的类型由Lambda表达式出现的语境自动推断类型。
Lambda表达式的参数列表可以有一个或多个参数,或者无参数。在有单一的隐型参数的lambda表达式中,圆括号可以从参数列表中省略。
例如:

(x, y) => x * y;//多参数,隐式类型=>表达式
x => x * 10;//单参数,隐式类型=>表达式
x => { return x * 10; }; //单参数,隐式类型=>语句块
(int x) => x * 10;//单参数,显式类型=>表达式
(int x) => { return x * 10; };//单参数,显式类型=>语句块
() => Console.WriteLine(); //无参数

下面看这个例子:
在前面的帖子中,我们写了一个User类及增加了2个人,接下来,我们使用由LINQ提供的新的Where和Average方法来返回集合中的人的一个子集,以及计算这个集合中的人的平均年龄:

List<User> user = new List<User>{
    new User{Id=1,Name="YJingLee",Age=22},
    new User{Id=2,Name="XieQing",Age=25},
};
//获取特定人时所用的过滤条件,p参数属于User类型
var results = user.Where(p => p.Name == "YJingLee").ToList();
//用User对象的Age值计算平均年龄
var average = user.Average(p => p.Age);

效果图如下:

Lambda表达式

对这个Lambda表达式做个简要分析:

var resultsdelegate = user.Where(delegate(User p)
{
    return p.Name == "YJingLee";// 返回一个布尔值
});
var averagedelegate = user.Average(delegate(User p)
{
    return p.Age;
});

Lambda表达式简要分析

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

Lambda表达式树

Lambda表达式树允许我们像处理数据(比如读取,修改)一样来处理Lambda表达式。我以一个例子简单说明:

Expression<Func<int, bool>> filter = n => (n * 3) < 5;
BinaryExpression lt = (BinaryExpression)filter.Body;
BinaryExpression mult = (BinaryExpression)lt.Left;
ParameterExpression en = (ParameterExpression)mult.Left;
ConstantExpression three = (ConstantExpression)mult.Right;
ConstantExpression five = (ConstantExpression)lt.Right;
var One = filter.Compile();
Console.WriteLine("Result: {0},{1}", One(5), One(1));
Console.WriteLine("({0} ({1} {2} {3}) {4})", lt.NodeType,
         mult.NodeType, en.Name, three.Value, five.Value);

效果图如下:

Lambda表达式树

Lambda表达式和Lambda表达式树要点

  1. Lambda表达式的参数类型可以忽略,因为可以根据使用的上下文进行推断。
  2. Lambda表达式的主体(body)可以是表达式,也可以是语句块。
  3. Lambda表达式传入的实参将参与类型推断,以及方法重载辨析。
  4. Lambda表达式和表达式体可以被转换为表达式树。
  5. 表达式树允许lambda表达式能够代表数据结构替代表示为执行代码。
[第1页][第2页]
0
0
标签:C#

热门文章

    最新文章

      最新新闻

        热门新闻