RSS 2.0 Feed
2007-10 Entries
摘要: [原文作者]: Timothy Ng [原文链接]: VB expression trees - string comparisons   上次,我简单的谈了表达式树以及它的用途。对于那些想写LINQ provider的人来说,表达式树很有意思,它能对lambda表达式进行推理从而得到LINQ provider。一般来说,任何想了解lambda表达式的人应该对表达式树也感兴趣。 今天,我打算专门为这些正在写代码实现表达式树的人写点东西。即便你现在没写这些代码,我仍然希望你能看下去,因为无论如何这些内容都是非常有趣的。 在这篇博客里我将讨论一下字符串的比较以及他们在表达式树里的表现。Jonathan(我们的PM)和我曾经写过一个LINQ provider的例子,我们认为这段代码非常有用,现在把它共享出来。 在VB里,通过对option compare的设置就可以用=操作符对区分大小写和不区分大小写的字符串进行比较。 为了实现这些,VB编译器在运行时调用了Microsoft.VisualBasic.CompilerServices.Operators.CompareString,这个方法有三个参数:其中2个是操作数,1个是标志符指示比较类型。 当VB编译器为字符串相等操作符生成表达式树的时候,我们通过构造表达式来调用CompareString方法以保证字符串的正确比较。这是因为在默认的情况下,表达式树中“等于”节点的API负责区分大小写。而且,“等于”节点在VB中并未考虑到特殊字符串及字面上的“Nothing”的比较。 这就意味着如果你想通过VB编译器生成的表达式树来写一个visitor,你就一定会期望这些二元操作符如<, <=, =, >=, 以及 >,它们的左边为CompareString方法,右边为0。当你看到这些,你需要根据CompareString中第三个参数的使用方法来正确拆分它里面的参数。 但是,如果你的provider不进行字符串比较的话(比如LINQ to SQL),那么你只要用下面的代码,把方法调用中的二元运算符转换为方法调用参数中的二元运算符。 然后在你的visitor里调用这个方法进行转换,接着通过方法返回的节点运行visitor,将字符串比较作为二元操作符处理。不过这种方法无法区分大小写。 Friend Shared Function ConvertVBStringCompare(ByVal exp As BinaryExpression) As BinaryExpression     If exp.Left.NodeType = ExpressionType.Call Then         Dim compareStringCall = CType(exp.Left, MethodCallExpression)         If compareStringCall.Method.DeclaringType.FullName = "Microsoft.VisualBasic.CompilerServices.Operators" _             AndAlso compareStringCall.Method.Name = "CompareString" Then             Dim arg1 = compareStringCall.Arguments(0)             Dim arg2 = compareStringCall.Arguments(1)               Select Case exp.NodeType                 Case ExpressionType.LessThan                     Return Expression.LessThan(arg1, arg2)                 Case ExpressionType.LessThanOrEqual                     Return Expression.GreaterThan(arg1, arg2)                 Case ExpressionType.GreaterThan                     Return Expression.GreaterThan(arg1, arg2)                 Case ExpressionType.GreaterThanOrEqual                     Return Expression.GreaterThanOrEqual(arg1, arg2)                 Case Else                     Return Expression.Equal(arg1, arg2)             End Select         End If     End If     Return exp End Function 下面这个例子并未做任何有用的事情,但你可以从中了解到如何使用上面定义的方法。 Sub VisitBinary(ByVal......[阅读全文]

posted @ | Feedback (2) | Filed Under [ VB Team Blog ]

摘要:[原文作者]: 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...[阅读全文]

posted @ | Feedback (2) | Filed Under [ VB Team Blog ]

摘要: [原文作者]: Kevin Halverson [原文链接]: How to implement IQueryable   随着Orcas(Visual Studio 2008的code name)的推出,微软计划为我们经常用到的一些数据应用的场合提供Linq的支持。比如:DLinq用于SQL Server,Xlinq则用于XML相关的处理。事实上还有其他数不清的数据读取的场合,用户也希望能用上Linq这个方便快捷的工具。多数情况下,我们只需要把数据放到CLR Collection里,用Linq基本的支持足以。举个例子来说:要是你想找到“我的文档”里的所有新放进来的.exe文件,可以用下边这句: Dim newExe = From fileName In Directory.GetFiles( _ My.Computer.FileSystem.SpecialDirectories.MyDocuments, _ "*.exe", SearchOption.AllDirectories) _ Where (New FileInfo(fileName)).CreationTime > #6/30/2007# _ Select fileName 很简单,是吧? 这样看起来很好,唯一的缺点是没有涉及到我们这篇文章的主题“实现IQueryable”。下边还是看看怎么通过实现IQueryable达到我们的目的,也就是为Linq提供我们自已的Linq Provider。   在当今的开发领域,已经存在很多的程序接口和对象模型提供对各式各样的数据的读取和操作。比如:Windows Desktop Search (关于它的详细内容参见http://www.microsoft.com/windows/desktopsearch/default.mspx) 它就提供了一个OLE DB Provider让你能查询系统已经建立好的各种文件信息的索引。那么,我们可不可以不用写SQL语句而是使用Linq来访问这些内容呢?答案是:能,但我们要实现Linq Provider。对相关背景知识不太了解而又有兴趣的朋友来说,本文末尾的参考资源很有必要,不妨一看。    写一个自己的Linq provider,首先要做的就是实现IQueryable和IQueryProvider这两个接口。因为我们要操作的是文件对象(FileInfo),所以要实现IQueryable(Of FileInfo),代码如下:   Imports System.IO Public Class WDSQueryObject     Implements IQueryable(Of FileInfo), IQueryProvider End Class 当你在Visual Studio里敲出(估计没有人真的会敲)或是Paste出上面的这些代码,IDE会提示你要实现这两个接口,有几个方法你必须要实现。下面我一一介绍: 注意: l 完整的代码在末尾的给出的链接里能找到,下载下来并调试运行一下,收获更大。 l 我的代码基于Orcas Beta2。IQueryable接口在Beta1版本后有过重构。   CreateQuery IQueryProvider 接口里面定义了两个CreateQuery方法. 一个返回泛型的 IQueryable(Of TElement)。另外一个返回非泛型的 Iqueryable。大多数情况下你可能只需要在非泛型的里面调用泛型的那个。就象下面这样:     Public Function CreateQuery(ByVal expression As Expression) As IQueryable Implements IQueryProvider.CreateQuery         Return CreateQuery1(Of FileInfo)(expression)     End Function 对一个简单查询来说,每一个“Where”子句中的过滤条件都会调用一次CreatQuery,每一个“Select”会调用一次CreatQuery 。像下面这一句:         Dim r = From file In index _                 Where file.Name Like "%.exe" _           Select file.FullName 表达式“file.Name Like "%.exe"”和“file.FullName”分别会调用一次CreateQuery方法。下面是我实现处理这两个语句的代码的框架:     Public Function CreateQuery1(Of TElement)(ByVal expression......[阅读全文]

posted @ | Feedback (1) | Filed Under [ VB Team Blog ]

摘要:[原文作者]:Slavi Marinov [原文链接]:How do we write software at Microsoft: a PM intern’s perspective #1 现在对于我们的团队来说,是时候干点实际的了,我们在这里开发软件,所以让我们来谈谈软件。我答应过要把这里最新的东西展示给大家,我决定以"在微软我们怎么开发软件:一名准项目经理的视角" 为题发表一系列博客, 期望能尽可能的迎合开发以及测试人员的口味。虽然我们的团队很小并且项目生命周期可能也会相对较短(仅3个月),我相信经过这一系列,你将会对发布一个产品需要投入多少精力有个概念,还有为及时发布正确的产品这里的人又投入了多少激情。好吧, 让我告诉你一些更多的细节,关于近几周让我一直忙碌的事情来开始这个系列吧  项目生命周期  对于每一个项目来说,都会经历一些标准的过程,每个阶段都从前一阶段收益,并且为项目增加价值。毫不奇怪 ,项目要从分析阶段开始,其基本思路是确定项目的范围,确定我们该做哪些,而哪些应该放到下一个版本。 紧接而来的就是规划阶段,项目的发展线路应该如何,(重要里程碑)将会被确定以及划分 这将基本上告诉我们现在项目进行到哪儿了,并且可以在我们和计划的进度不符合的时候,迅速地让我们作出反应。再后来,项目将进入开发等等的阶段。 从最初的两个阶段得到的最重要的两样东西就是项目规格书和项目计划。 没有确定项目范围而进行项目计划是一件很难的事情,所以对于一个项目经理来说首先并且最重要的事情就是确定项目规格书。 因此,这次我将着重介绍项目规格书,并且在以后我将逐渐介绍如何做项目计划。  分析阶段 如果你没有多少写项目规格书的经验,你可能会惊讶与整个团队会为了完成项目规格书花费如此多的精力。 没错,整个团队-写规范是一个团队的努力,如果你认为这是一件只项目经理做的,那么请试着考虑下列各点: 开发团队需要项目规格书以便于开始开发,这样他们才能知道要开发什么,他们最终的劳动成果看上去应该是个什么样子  测试团队需要项目规格书告诉他们所期望的行为是什么,以至于他们可以开始测试 整个团队需要项目规格书用以界定任务,优先级,阶段划分,以及项目的发展蓝图,并且估计出该项目交付的时间 各有关方面要规格书以了解哪些功能将在什么时候交付 正如你看到的,一个项目经理能是不可能独立完成项目规格书的(任何在微软工作的项目经理)。 原因有太多的人参与,你不能独自一个人完成项目规格书,然后希望其他人全都同意。所以,如何在微软写出适当的项目规格书 ? 这里是我的基本步骤。  第1步.  做足功课 我一开始将对该领域做一些研究。 我尝试不同的东西;分析各种可能性,验证项目中的概念等等。我花了相当一段时间扮演一个潜在用户的角色,看到底我需要什么,我期待的产品是什么样的。 所以,我要说第一步是通过实验我们要了解项目看上去应该怎样,探索未知的区域。 这个阶段是纯理论的研究,此时你只需要尝试该领域的一些东西并取得一些经验。 我在做Visual Studio系统的项目中学到了很多,所有那些不同的东西你都需要做扩展,VB运行时包括什么,它是如何实现的,还有许多令人兴奋的事情。 事实证明了当我做为项目的项目经理的时候,我学到了多新东西!  第2步.  多和别人交流 我跟很多人交谈过。 在过去几个星期里,我几乎每天都开几个小会议,为了使项目规格书更加完善,我每天要送出数十份电子邮件。 我已花了不少时间与开发人员,测试人员,项目经理以及其他这个项目相关的人。当我需要一些我自己并不在行的技术方面的支持的时候,我也会和VB组之外的很多人进行交流。 我认为这是一个整个项目最酷的部分-实际了解了不同人对于项目的感受,什么是技术上的可行性,等等 这个阶段很有趣,但并不是写文档本身让我感到高兴。 当然我乐于看到一份文档变得越来越充实,更多细节以及内容被充实进去。 更令人振奋的是,事实上在你完成项目规格书的同时,你真正明白了整个项目在做什么。 你将知道每一个功能细节,因为这是你的工作。 这是不是不可思议? 你其实有责任了解这一切,所以,当有人有问题时,你知道答案。 我不知道别人怎么想,但我确实喜欢这种感觉。 在某些点上,你对整件事是如何工作有个完整的理解,如何将不同的模块整合在一起,他们将如何互动,有什么潜在的问题,等等。我想让我开始参与软件开发的想最重要的原因,是有机会去创造,建立,创新。  第3步.  让所有人快乐 好了,我花了一段时间写项目规格书,我终于完成了一个说明项目是做什么的文档。。 最好的部分来了-让所有的人同意我写的东西。 基本上,为了使所有人同意,你可以做两件事: 要么用枪瞄准他们的头:) 或和他们进行会议,这样你就能看到是什么困扰他们,并整理每一个你得到的评论,这样你就能另大家都对产品满意,并且相信项目规格书包含了可使他们开始工作所需要的所有信息。 在微软我们很人性化,所以我们偏向于第二种办法。 我们进行了一系列对项目规格书草案的校阅,这些基本上都是和同事们在项目规格书会议上面进行的。 人们给出他们的意见,对不同的问题进行讨论,并最终得到一个由多数人同意的方案来指引我们将走向何方。 让所有人幸福的最后一步就是来一次项目规格书的总校阅。 这是一次所有同事都会参加,在此你的项目规格书将得到正式批准。 大家都坐着看项目规格书,并且如果你把你的工作已经做的足够好,人在本次会议上不应该有太多的反馈,因为他们应该已经在非正式的时候提出过了。 我们的正式项目规格书校阅是周一,祝我们好运吧! 有趣的是在我来到这里之前,我以为微软(作为一个大公司) 有着大量文档和繁琐的流程,怪异模板等。这不能责怪我,其实许多即使小于微软的公司也有那些流程。 所以当我问: "那么我应该遵循什么样的模板? "得到的答案是"好了,这些就是你要去做的"时, 我是真的感到很吃惊。当然,基本准则还是有的,但你不一定非要遵照他们不可。 虽然他们是真的很有用,我从它们学到了很多新东西…但事实证明,每一步都严格遵守规范并不比只遵守其中正确的部分好多少。 不错,得到正确的东西,是不是太容易了--对于每一个特性的开发你必须付出很多精力以确保安全性,本地化,性能等,因为人们对这些东西是非常谨慎的。 但只要你有那些,并且大家都同意这里有那些就足够了,你就可以用你喜欢的布局或风格。 我不知道别人怎样,但我真的很喜欢这种自由!  第4步.  不断完善项目规格书 经过对项目规格书的审查,项目规格书将被打印并且文档将被标记为只读的,从此它永远不能改变… …这你只是期望罢了!  :) 规格书是一个动态的文件,并随着时间的推移,要不断改变和更新,项目经理的工作就是让其不断完善。 项目经理有责任了解每一个变化及其影响,让项目组做出正确的决定,这个是否应该改变哇,这次已经说了很多,有那么多东西写… … 所以我想我为大家开了个头,如果大家有什么问题,不要犹豫! 下周见!  ...[阅读全文]

posted @ | Feedback (11) | Filed Under [ VB Team Blog ]

摘要:[原文作者]:Jared Parsons [原文链接]:Closures in VB: Part 1 我叫Jared Parsons,是微软VB编译和调试组的软件开发人员。我为VB9.0开发的一个新特性叫做“lexical closure支持”。这个特性是对VB语言的一个重要扩充,因此我将通过几篇博客来解释这一特性是如何影响你的代码。 LexicalClosures(通常被简称为Closures)是Visual Basic 9.0几个新特性的内在支持,是Lambda和查询表达式的内在实质。我将针对VB9.0的Closures工作机制,局限性以及使用时易犯的错误将做系列性介绍。 首先,我们从一个基本的结论:什么是closure开始说起吧。在Wikipedia的定义是“...用于关联方法与环境的语法概念...”,但我更喜欢这样来描述它:一个Closure是一个特性,该特性允许用户从多个函数访问某一个环境(局部变量,参数和方法)。举例说明可能更易说明清楚:)    Class C1        Sub Test()            Dim x = 5            Dim f = Function(ByVal y As Integer) x + y            Dim result = f(42)        End Sub     End Class 在这段代码中,包含了一个Lambda表达式。它有一个方法参数并将这个参数与“Test”的局部变量做累加。在VB中,Lambda表达式被作为函数来实现的(C#也一样)。所以,现在我们有2个方法,它们是“Test”和“f”方法。“f“方法将访问“Test”方法的局部变量x。closure将在这里发挥其功效了。Closures负责使变量x在同一个进程中对于2个方法都可用(这被称为“提升变量”)。 要做到这点,编译器将执行4个步骤的操作: 1.        创建一个类,用于包含x以便在2个方法之间共享这个变量。这里,这个类称为“Closure” 2.        编译器将在这个“Closure”类中为Lambda表达式创建一个新方法。这里,这个方法名叫“f”。 3.        编译器将在“Test“方法内部创建一个该“Closure”类的实例 4.        在“Test“方法中,将所有对于x的访问都重新改写为访问Closure类的成员变量x.     Class Closure        Public x As Integer         Function f(ByVal y As Integer) As Integer            Return x + y        End Function    End Class     Class C1        Sub Test()            Dim c As New Closure()            c.x = 5            Dim f As Func(Of Integer, Integer) = AddressOf c.f            Dim result = f(42)        End......[阅读全文]

posted @ | Feedback (2) | Filed Under [ VB Team Blog ]