Lambda表达式和表达式树

[原文作者]: Timothy Ng

[原文链接]: Lambda Expressions and Expression Trees

 

大家好,我是Tim, VB编译器组的组长。最近Amanda极力劝说我到VB组的博客上而不是我自己的博客上发表文章。所以我现在就在这里写了。我现在的计划是将与VB有关的文章贴在这,更多关于功能实现/技术/有趣的东西放到我自己的博客上 (比如,那些和VB语言/特性 无关的东西)

最近我的关于Lambda表达式的文章被发表在MSDN杂志上。在此篇文章中,我将那篇文章中的某些理念做一个拓展。如果你们对这篇文章中有什么不理解的,尽可以参考那篇文章。

 

Lambda表达式非常cool不但是因为那篇文章中所说的原因,而且我们还可以从可读性很强的表格中获取Lambda表达式的内容,就像是在看数据一样,而不是可执行代码。比如,下面这行代码将一个lambda表达式转换为一个可调用委托: 

Dim f As Func(Of Integer, Integer) = function(x) x * 2

Dim r = f(10)

 这个示例的第一行生成一个Lambda表达式,并将其奇迹般地赋给一个可调用委托f,第二行调用f, 并返回值20.

 

这非常酷,我的文章将说明,为什么我认为它很酷。其实有更酷的,那就是事实上你可以将Lambda表达式赋给特殊变量类型,而编译器会帮你做很神奇的处理: 

Dim e As Expression(Of Func(Of Integer, Integer)) = function(x) x * 2

 在这个代码示例中,e不是一个可调用委托,而是表达式树。表达式树是lambda表达式的一种数据表示形式,它能使你更方便地读取和推断Lambda表达式。

如果你深入探究调试器里的e的值,你会很容易地发现表达式是整型变量x与整型常量2的乘积操作。

默认情况下,拓展了Ienumerable接口的表达式能被赋给Lambda表达式;而拓展了Iqueryable接口的查询表达式只能被表达式树赋值。因此,当你生成一个带IQueryable类型查询的时候,编译器将生成一个表达式树而不是Lambda表达式。 

 

 在这个问题上,我组里的一个开发人员,Scott,曾经写过一篇很好的文章。他在那篇文章里用了非常好的图表来表现说明一些Lambda树的表达式树表示形式。

 

你能用表达式树做些什么呢?

 

大致上,你可以做两件事:

 

1.        推断表达式树内数据,并对它做自定义处理。你也能将表达式树中的数据转换到其他的域的数据形式(XML).

 

2.        .Compile() 方法去将一个表达式树转换为一个委托,然后你可以执行它。

 

3.        编译包含动态条件的查询:参考Jonathan’s的文章,写的非常好的。他举出了大量的例子告诉你如何巧妙地处理那些表达式树和编译你的带自定义条件的lambda表达式。 

 

其中第二条是很有趣的,因为它意味着你能将一个lambda表达式复制进一个表达式树,推断它,并将它转换为一个可调用委托。

 

Dim e As Expression(Of Func(Of Integer, Integer)) = function(x) x * 2

Dim f = e.Compile

Dim r = f(10)

 

 在这个示例中,变量r的值是20,和我们之前举的将lambda表达式直接赋给一个委托类型得到的结果一样。

 

 这个为什么说它有趣呢?

 

没有表达式树的话,我们是不可能用描述格式来表示一个表达式的。他们唯一的表示方式是IL (中间语言), 这种语言对于重新表述用户的意图来说太低层次了。然后,表达式树对一个表达式提供了一个高级的树表示方式来表现表达式,这样你就能很容易地理解用户该表达式的意图。

 

如下是一些可能比较有趣的表达式树的用法:

 

1.        推断表达式,然后将他们转换为委托并调用他们;

2.        将表达式转换为SQL, 这样他们就能被服务器执行了 (这是linqsql所做的工作)

3.        将表达式转换为XML并将他们写到磁盘上;

4.        将表达式转换为自定义形式并将他们通过某种网络协议发送到能将之通过某种格式重编译为表达式树,重新生成表达式分析并执行他们的服务器上。

 在后面的几篇文章中,我将特别讲述关于VB编译器生成的表达式树,以及VB树与C#之间的区别以支持VB同语义学。

我也将对你们能做的事情给出一些小技巧,这样任何你们所写的用到表达式树的类库将为VB开发程序员提供最好的体验。

Visual Studio 2008中数据工具的新特性

[原文作者]: Young Joo

[原文链接]: New Data Tools Features in Visual Studio Orcas

下面是 Visual Studio 2008中数据工具方面新特性的列表。 首先让我们了解一些术语。

O/R Designer——对象—关系设计器

LINQ——语言集成查询

Hierarchical Update——级联更新

N –Tier——多层架构

SQL Compact Edition/ SQL CE——SQL精简版

DataSet——数据集

Typed DataSet——强类型数据集

Local Data Cache——本地数据缓存


对象—关系设计器(O/R Designer)

对象—关系映射技术允许您将关系数据库映射为对象。 一旦完成映射,您就可以将他们当成普通对象来处理,无需编写复杂的数据访问逻辑就可以轻松地将更改提交回数据库。对于这种增强型的数据访问技术,目前已有许多不同的实现机制。 但是,综观目前O/R 映射实现工具,并未带有易于创建和修改映射的图形设计器。

Visual Studio 中的对象关系设计器正是Microsoft处理对象—关系到底应该如何映射的回答。 图形设计器它允许您轻松地将数据库对象,如表和存储过程映射为 LINQSQL的类和方法。只需将数据库对象从数据库管理器拖放到设计器。 设计器就会自动创建映射并生成正确的 LINQSQL的代码。您还可通过设计器修改映射的不同方面的配置,设计器会自动更新代码。关联和继承关系也很容易地创建。支持存储过程这一特性也很独特。对于INSERTUPDATEDELETE操作,您可以基于存储过程作为对象映射的方法来替代默认的操作。

如果您已经体验过三月份的LINQCTP版本,您可能记得那时我们提供的对象—关系设计器叫做DLinq 设计器。这就是下一代对象关系设计器的预览版,目前更名为O/R设计器。

 

强类型DataSet的级联更新

持续跟踪跨多个相关的datatable的所有插入、更新和删除操作,并将更改以正确顺序提交回服务器,这在向来不是一个简单的任务。如何在确保客户的新订单被正确地添加到系统中,同时更新该客户的送货地址并删除其中一个已被取消的旧订单?

具有级联更新支持的强类型DataSet中,您只需调用我们新添加的TableAdapterManager组件的UpdateAll() 方法即可自动完成所有操作。它负责收集所有更改并将它们按正确顺序提交给服务器。当然,所有工作都会放在一个事务中。

我们相信这将极大的提高使用强类型DataSet来创建数据应用程序开发人员的工作效率。 您可以在三月份的 Visual Studio Orcas CTP版本中尝试这一新特性.

 

 

强类型DataSet中多层架构(N-tier)的支持

我承认,Visual Studio 2005 中生成强类型DataSet的代码并未对多层架构提供很好的支持。如果您打开强类型DataSet的代码文件,您会注意到我们已经很好的将类型从数据访问逻辑分开。DataSet和强类型的datatables是在一个强类型DataSet中声明的,而所有 TableAdapter 类则是在单独的命名空间中声明的。但是我们将它们放在了一个代码文件中。这对于大多数应用程序来说没有多大问题。但在构建多层架构的应用程序时, 将他们放在一个文件中并没有多少帮助。对该问题更细节方面的讨论请参考Steve LaskerSplitting Typed Datasets from TableAdapters一文。他在该文中提出的解决方案是打开生成的代码并手动的将类型声明拷贝到一个新的类文件中。尽管这的确使得您可以在 N 层架构中使用强类型的DataSet。但是这个方案最大的缺憾就是由于需要您手动修改生成的代码,任何时候您在设计器中对强类型DataSet进行了更改,您就不得不再次拷贝类型声明部分的代码,很是繁琐。

Visual Studio 2008中,您可以指示设计器将DataSet代码生成的解决方案中的另一个项目中而无须手动的拷贝。并确保您在设计器中的进行的更改可以自动更新到指定的项目中去。同时您仍可选择保持现有的2层架构模型,设计器仍将所有内容生成到单个文件中。当您已准备好将2层变为 N 层时,只需告诉设计器哪个项目用来存放DataSet即可。简单吧!此特性的预览版在三月份的CTP of Visual Studio Orcas中就有,Beta 1版本中的该特性更加的完善。

 

 

使用SQL精简版的本地数据缓存

SQL精简版为开发人员带来了许多激动人心的方案。最有意思的情况是使用SQL 精简版数据库文件作为不经常更改的数据的本地缓存。例如,您的应用程序可能会在与远程服务器交换订单信息时,将产品列表保留在本地缓存中。在需要的时候,您可以将产品列表与远程服务器进行同步,但是大多数情况下,使用的还是还是本地缓存。

由于SQL精简版是系统开销很少的轻量级数据库,因此作为本地数据缓存正合适。可以使用 ADO.NET的同步服务来同步远程数据库服务器和本地 SQL精简版数据库文件之间的数据。不错吧?但是该如何设置呢?

Visual Studio 2008包含了一个新的项目模板,叫做“本地数据缓存”。将“本地数据缓存”添加到您的项目中将会创建.syncXML文件,该文件用于描述什么数据将被同步。此文件带有设计器以便您可以轻松地进行同步配置。设计器还会创建 SQL精简版数据库文件作为本地数据缓存,并生成与同步服务进行交互的代码。此特性的预览版在三月份的CTP of Visual Studio Orcas中就有,Beta 1版本中的该特性更加的完善。

 

数据工具在其他方面的增强

上面四个是在 Visual Studio 2008中最主要的数据工具的新特性。但同时我们也大量的增强了现有的数据工具的功能。如果有机会,我单独写一篇文章描述我们所做的这些工作。

如何实现IQueryable (Kevin Halverson)

[原文作者]: Kevin Halverson

[原文链接]: How to implement IQueryable

 

我刚写了一篇关于如何实现IQueryable的文章(创建一个自己的Linq provider)。

http://blogs.msdn.com/kevin_halverson/archive/2007/07/10/how-to-implement-iqueryable.aspx (http://blog.joycode.com/vbcti/archive/2007/10/19/109501.aspx)

 

通过实现定制的Linq provider,你就能用下面这种方式查询Windows Vista (Desktop) Search engine得到你系统里的文件信息:

        Dim index As New WDSQueryObject

        Dim cutoffDate = #6/28/2007#

 

        Dim r = From file In index _

                Where file.CreationTime > cutoffDate And _

                file.Name Like “%.exe” _

                Select file.FullName, file.CreationTime

在微软我们怎样开发软件:一名准项目经理的视角(之一)

[原文作者]

[原文链接]How do we write software at Microsoft: a PM intern’s perspective #1

现在对于我们的团队来说,是时候干点实际的了,我们在这里开发软件,所以让我们来谈谈软件。我答应过要把这里最新的东西展示给大家,我决定以”在微软我们怎么开发软件:一名准项目经理的视角” 为题发表一系列博客, 期望能尽可能的迎合开发以及测试人员的口味。
虽然我们的团队很小并且项目生命周期可能也会相对较短(仅3个月),我相信经过这一系列,你将会对发布一个产品需要投入多少精力有个概念,还有为及时发布正确的产品这里的人又投入了多少激情。
好吧, 让我告诉你一些更多的细节,关于近几周让我一直忙碌的事情来开始这个系列吧

 项目生命周期  
对于每一个项目来说,都会经历一些标准的过程,每个阶段都从前一阶段收益,并且为项目增加价值。毫不奇怪 ,项目要从分析阶段开始,其基本思路是确定项目的范围,确定我们该做哪些,而哪些应该放到下一个版本。 紧接而来的就是规划阶段,项目的发展线路应该如何,(重要里程碑)将会被确定以及划分 这将基本上告诉我们现在项目进行到哪儿了,并且可以在我们和计划的进度不符合的时候,迅速地让我们作出反应。再后来,项目将进入开发等等的阶段。
从最初的两个阶段得到的最重要的两样东西就是项目规格书和项目计划。 没有确定项目范围而进行项目计划是一件很难的事情,所以对于一个项目经理来说首先并且最重要的事情就是确定项目规格书。 因此,这次我将着重介绍项目规格书,并且在以后我将逐渐介绍如何做项目计划。

 分析阶段
如果你没有多少写项目规格书的经验,你可能会惊讶与整个团队会为了完成项目规格书花费如此多的精力。 没错,整个团队-写规范是一个团队的努力,如果你认为这是一件只项目经理做的,那么请试着考虑下列各点:

  • 开发团队需要项目规格书以便于开始开发,这样他们才能知道要开发什么,他们最终的劳动成果看上去应该是个什么样子 
  • 测试团队需要项目规格书告诉他们所期望的行为是什么,以至于他们可以开始测试
  • 整个团队需要项目规格书用以界定任务,优先级,阶段划分,以及项目的发展蓝图,并且估计出该项目交付的时间
  • 各有关方面要规格书以了解哪些功能将在什么时候交付

正如你看到的,一个项目经理能是不可能独立完成项目规格书的(任何在微软工作的项目经理)。 原因有太多的人参与,你不能独自一个人完成项目规格书,然后希望其他人全都同意。所以,如何在微软写出适当的项目规格书 ? 这里是我的基本步骤。

 第1步.  做足功课
我一开始将对该领域做一些研究。 我尝试不同的东西;分析各种可能性,验证项目中的概念等等。我花了相当一段时间扮演一个潜在用户的角色,看到底我需要什么,我期待的产品是什么样的。 所以,我要说第一步是通过实验我们要了解项目看上去应该怎样,探索未知的区域。 这个阶段是纯理论的研究,此时你只需要尝试该领域的一些东西并取得一些经验。 我在做Visual Studio系统的项目中学到了很多,所有那些不同的东西你都需要做扩展,VB运行时包括什么,它是如何实现的,还有许多令人兴奋的事情。 事实证明了当我做为项目的项目经理的时候,我学到了多新东西!
 第2步.  多和别人交流
我跟很多人交谈过。 在过去几个星期里,我几乎每天都开几个小会议,为了使项目规格书更加完善,我每天要送出数十份电子邮件。 我已花了不少时间与开发人员,测试人员,项目经理以及其他这个项目相关的人。当我需要一些我自己并不在行的技术方面的支持的时候,我也会和VB组之外的很多人进行交流。 我认为这是一个整个项目最酷的部分-实际了解了不同人对于项目的感受,什么是技术上的可行性,等等
这个阶段很有趣,但并不是写文档本身让我感到高兴。 当然我乐于看到一份文档变得越来越充实,更多细节以及内容被充实进去。 更令人振奋的是,事实上在你完成项目规格书的同时,你真正明白了整个项目在做什么。 你将知道每一个功能细节,因为这是你的工作。 这是不是不可思议? 你其实有责任了解这一切,所以,当有人有问题时,你知道答案。 我不知道别人怎么想,但我确实喜欢这种感觉。 在某些点上,你对整件事是如何工作有个完整的理解,如何将不同的模块整合在一起,他们将如何互动,有什么潜在的问题,等等。我想让我开始参与软件开发的想最重要的原因,是有机会去创造,建立,创新。
 第3步.  让所有人快乐
好了,我花了一段时间写项目规格书,我终于完成了一个说明项目是做什么的文档。。 最好的部分来了-让所有的人同意我写的东西。
基本上,为了使所有人同意,你可以做两件事:

  • 要么用枪瞄准他们的头:)
  • 或和他们进行会议,这样你就能看到是什么困扰他们,并整理每一个你得到的评论,这样你就能另大家都对产品满意,并且相信项目规格书包含了可使他们开始工作所需要的所有信息。

在微软我们很人性化,所以我们偏向于第二种办法。 我们进行了一系列对项目规格书草案的校阅,这些基本上都是和同事们在项目规格书会议上面进行的。 人们给出他们的意见,对不同的问题进行讨论,并最终得到一个由多数人同意的方案来指引我们将走向何方。
让所有人幸福的最后一步就是来一次项目规格书的总校阅。 这是一次所有同事都会参加,在此你的项目规格书将得到正式批准。 大家都坐着看项目规格书,并且如果你把你的工作已经做的足够好,人在本次会议上不应该有太多的反馈,因为他们应该已经在非正式的时候提出过了。 我们的正式项目规格书校阅是周一,祝我们好运吧!
有趣的是在我来到这里之前,我以为微软(作为一个大公司) 有着大量文档和繁琐的流程,怪异模板等。这不能责怪我,其实许多即使小于微软的公司也有那些流程。 所以当我问: “那么我应该遵循什么样的模板? “得到的答案是”好了,这些就是你要去做的”时, 我是真的感到很吃惊。当然,基本准则还是有的,但你不一定非要遵照他们不可。 虽然他们是真的很有用,我从它们学到了很多新东西…但事实证明,每一步都严格遵守规范并不比只遵守其中正确的部分好多少。 不错,得到正确的东西,是不是太容易了–对于每一个特性的开发你必须付出很多精力以确保安全性,本地化,性能等,因为人们对这些东西是非常谨慎的。 但只要你有那些,并且大家都同意这里有那些就足够了,你就可以用你喜欢的布局或风格。 我不知道别人怎样,但我真的很喜欢这种自由!
 第4步.  不断完善项目规格书
经过对项目规格书的审查,项目规格书将被打印并且文档将被标记为只读的,从此它永远不能改变… …这你只是期望罢了!  🙂 规格书是一个动态的文件,并随着时间的推移,要不断改变和更新,项目经理的工作就是让其不断完善。 项目经理有责任了解每一个变化及其影响,让项目组做出正确的决定,这个是否应该改变
哇,这次已经说了很多,有那么多东西写… … 所以我想我为大家开了个头,如果大家有什么问题,不要犹豫! 下周见!