RSS 2.0 Feed
2005-09 Entries
摘要:动态语言今年来发展很快,各种脚本语言多少都带有些动态语言的特点。动态语言以其灵活的语法和丰富的运行时行为赢得了许多人的青睐。在.NET阵营,C#一直扮演着静态语言的角色,尽管3.0的语法改变很激进,但仍注重于编译时的类型检查和约束。动态特性用的不好会产生更多运行时问题,不易确保程序的可靠性,但其提高开发效率的作用是毋庸置疑的。Visual Basic 9.0是Visual Studio中唯一能让你统领动态和静态两大领域的语言,让你在程序中自由选择喜欢的风格。 Visual Basic 从1.0便支持后期绑定,即按照对象的运行时类型信息使用对象,而不是定义这个对象时的类型信息。如: Dim l As Object = New ArrayList()l.Add(12)l.RemoveAt(0) 我们知道Object没有Add或RemoveAt方法,但运行时类型ArrayList具有他们,因此Visual Basic允许到运行时再检查有无相应的操作并支持。既然这个过程已经是在运行时做的了,我们就应该允许这个后期绑定的操作本身也是在运行时确定。这个语法增强叫做动态标识符。比如我们可以和这样写: Dim l As Object = New ArrayList()l.("Add")(12)l.("RemoveAt")(0) 我们看到,这个时候方法名称Add和RemoveAt已经是字符串了,它当然也可以是包含字符串的变量!所以你甚至可以写出这样的代码: l.(Console.ReadLine())(12)l.("Remove" & "At")(0) 这样,作为方法名称的标识符就可以完全在动态期间确定了。方法名称如此,那么类型名称呢?理应如此。我们可以这样写: Dim l As Object = New ("ArrayList")() 这样,你的变量l的类型将根据一个运行时字符串的值确定。动态标识符还能将函数的参数也动态化,假设有下列子程序: Sub Method1(Optional arg1 As String, Optional arg2 As String) 运行的时候,我们可以动态地指定将数值赋给哪个参数: If a > 0 Then argString = "arg1" Else argString = "arg2"Method1({argString}:= a.ToString()) 注意在:=符号之前的大括号,表示对参数名称的动态结合。有了动态标识符这一特性,Visual Basic 9.0将不需要利用反射的复杂语法,就可以做很多需要反射和运行时类型信息来做的任务,这使得Visual Basic成为解决你手边小问题的最佳帮手。本期我们已经领略到Visual Basic 9.0在动态特性上的革新,下一期将介绍第二个动态特性——动态接口。...[阅读全文]

posted @ | Feedback (146) | Filed Under [ 技术随笔 Visual Basic 9.0 前沿播报 ]

摘要:本期介绍的两个VB9作为数据开发辅助功能的新特性。CLR在.NET 2.0增加了许多关于委托的新特性(但大部分都不为任何语言所支持),其中一个叫做协变的特性允许放松委托与函数绑定时的签名检查(C# 2.0支持)。为了追求更高的灵活性,VB9决定在协变的基础上再进一步,引入松弛委托的概念。主要是按照以下规则为委托的实例指定函数: 1、函数的参数个数和返回值类型与委托的签名相同2、函数的参数类型与委托签名相应位置上的参数类型有父子类或接口-实现关系,或Visual Basic定义的隐式转换规则。 就是说,假如我们有个委托的签名是F(Integer),那么不仅可以为他的实例指定g(Integer)签名的函数,还可以指定g(Double)或者g(Object)签名的函数,因为Int32有到Double的隐式转换,而且是Object的子类。举个实际的例子:Public Delegate Sub Test()Sub Test(arg As Integer) '在代码中 Sub Func()Sub Func(arg As Object) Console.WriteLine(arg.ToString()) End Sub Dim d As Test = AddressOf Func d(13) 可为空类型在VB2005中就已经支持,而且和C#一样可以与Object类型互转而不会出现语义不同问题。但是VB2005没有加入C#那些语法糖,如定义语法的简化、lifted运算符和空值判断运算符。虽然我觉得这些语法糖未必有多好吃,不过VB9最终还是添加了一些。首先是问号定义的语法。Dim var1 As T? Dim var2? As T 以上两个定义是等价的,其意义是:当T为引用类型时,变量的类型为T;当T为值类型时,变量的类型为System.Nullable(Of T)。这样就将所有可为空类型的定义语法统一起来,进而可以用统一的方法判断空值。第二个引用的语法是lifted运算符:当T类型定义的运算符用于T?型时,将自动按以下规则计算:如果原运算结果类型为U,那么使用可为空类型运算的结果就是U?;参与运算的数中有任意一方为Nothing,结果就是Nothing。这样,多年阔别Visual Basic的Null传播又回来了。注意,没有以T?格式定义的引用类型,尽管可以为空引用,但是不会Null传播,只会抛出异常,这一点要注意。 VB9前沿播报的静态篇就到此结束了,从下一篇起,我们进入Visual Basic语法改进的动态篇。...[阅读全文]

posted @ | Feedback (3) | Filed Under [ 技术随笔 Visual Basic 9.0 前沿播报 ]

摘要:终于达到100篇了!不过是到达博客堂一年多才达到,惭愧。我会继续在这里发表更多Visual Basic和.NET的技术文章的。 9月23日北京Tech Ed 2005就要举行了,在9月24日下午,分会场5,您将听到我的课程: DEV342: Visual Basic 2005: 应用程序框架和高级语言特性 在这个课程上,我将用Visual Studio 2005 RC向大家展示:1、使用和扩展新的Visual Basic应用程序框架,简化多种程序的编写,包括用户身份验证、应用程序日志和配置信息。2、使用并扩展Visual Basic 2005的多种IDE特性3、体验全方位的Visual Basic 8.0语言新特性。 欢迎介时参加!...[阅读全文]

posted @ | Feedback (16) | Filed Under [ 闲话集锦 ]

摘要:前面所介绍的Visual Basic 9.0新特性,初衷都是为了迎合.NET Framework新的数据框架——Linq。Linq的一个口号是“让查询无处不在”,它将类似SQL的语法强类型地引入到Visual Basic中,而且可以任意组合使用。不要以为只是把数据库的SQL写到VB中而已,那样就太小看Linq了。VB的目标是让一切包含数据的对象都可以用类SQL查询,包含数据库映射对象(DLinq),XML(XLinq),甚至是.NET Framework中的一切集合对象。 我们来看一个例子。假如Employee类有FirstName,LastName和Age等属性。现在有一个List(Of Employee)类型的集合叫做emp。假设我们要查询所有Age大于25的员工的姓名。回忆一下前面我们介绍的特性怎么给查询带来新的变化。首先我们给IEnumerable增加扩展方法Where:<Extension()> _ Public Function Where()Function Where(Of T)([Me] As IEnumerable(Of T), predicate As Func(Of T, Boolean))_ As IEnumerable(Of T) Dim result As New Collection(Of T) For Each Dim item In [Me] If predicate(item) Then result.Add(item) Next Return result End Function 注意Func,这是.NET Framework将会增加的一组泛型委托之一,用于On-the-fly创建各种参数个数和类型的委托,而不必声明新的委托类型。这里Func用于表示一个断言。于是我们就把条件查询封装了。与此同时,我们还可以封装一个Select方法,用于数据类型转换,以此类推,还可以有OrderBy和GroupBy等等……这些就成为Linq的查询算符。 回忆一下,我们还有嵌套函数,于是可以按下列方法使用查询算符:Function F()Function F(obj As Employee)As Boolean Return obj.Age > 25 End Function Dim result = emp.Where(AddressOf F) 这里稍显麻烦的就是,我们需要自己定义函数,这样进行复杂查询就会写得很累,即使可能会有Lambda表达式帮助,我们也希望寻求更容易理解的方法,那就是查询包含Query Comprehension。新引入的Select,Where等查询关键字可以帮你完成前面介绍的一整套内容:Dim result =......[阅读全文]

posted @ | Feedback (5) | Filed Under [ 技术随笔 Visual Basic 9.0 前沿播报 ]

摘要:为了支持Linq平台所支持的查询特性,VB9必须引入少量“函数式编程(FP)”的特性。本次所介绍的嵌套函数和Closue特性就是最重要的一个环节。在我们探讨为什么引入这样一些特性之前,先来看看这个特性是什么样的。 VB9允许在过程内部定义函数或子程序,如: Public Sub MyProc()Sub MyProc() Sub Nested()Sub Nested() 'Code here End Sub End Sub 首先能够想到的第一个用途就是,一个帮助函数(HelperFunction)可以仅供某个过程单独使用,在这个过程外部无法访问到这个过程定义的嵌套函数。这与Delphi的嵌套函数类似。注意,嵌套函数仅可以在定义之后的上下文中访问。下面这个特性就是嵌套函数与传统函数最大的不同:Public Sub MyProc()Sub MyProc() Dim x As Integer Sub Nested()Sub Nested(i As Integer) x = i End Sub 'Invoke subroutine Nested(20) Console.WriteLine(x); End Sub 嵌套函数可以访问到外部过程中的变量,这个特性叫做Closure。有了Closure,我们就可以生成规则可变化的函数,以便实现延迟计算,这就是FP一个基本功能。VB9的内嵌函数Closure可能是通过Tuple特性来实现的,不过目前还没有关于原理的进一步细节。VB9内嵌函数相对于C#的匿名函数,主要有两个优点: 1。无需委托即可调用,可反复调用。当需要委托时,可通过AddressOf获取。2。可直接递归。(当然,高手可以用Y算子,后话了……) Visual Basic还考虑增加匿名内嵌函数的表达方式,就是众所周知的Lambda表达式。但是目前还没有语法放出来,我就先不介绍了。...[阅读全文]

posted @ | Feedback (15) | Filed Under [ 技术随笔 Visual Basic 9.0 前沿播报 ]

摘要:Visual Basic 9.0支持新一代语言集成的查询功能,支持在DLinq的数据对象或者XLinq的XML数据上实施关系型的查询,这些查询是利用DLinq或者XLinq相关对象上一组方法(或者叫算符)来实现的。而VB9的开发人员认为这套查询方法也应该能用于现有的对象数据组织方式,比如IEnumerable和其他集合。因此,Visual Basic 9.0需要一种从外部给现有类型增加方法的功能,这就是扩展方法。 扩展方法其实是一种编译器后台翻译的方法,原本是接受T类型参数的方法,可以用T类型成员的语法写出。这个语法仅用于类库设计者使用,不宜乱用,所以Visual Basic 9.0不提供特别的语法支持,类库设计者只需要把相应的Attribute置于声明扩展方法的模块与方法上即可。<Extension()>Module MyExtensionModule MyExtension <Extension()> _ Public Function Count()Function Count(Of T)([Me] As IEnumerable(Of T))As Integer For Each Dim item In [Me] Count += 1 Next End Function End Module 注意,我们把扩展方法的第一个参数命名为Me,是为了提醒程序员,这个参数在扩展方法起作用之后,就如同实例方法Me一样,当然这不是必须的,只是一种推荐做法。 扩展方法要起作用,并不是没有条件的,如果谁都扩展Framework中的方法,就会乱成一锅粥了。因此规定,需要用Imports语句导入扩展方法所在的模块,才能让扩展方法起作用。Imports MyExtionsion 导入扩展方法之后,就可以使用该扩展方法了:Dim arr = {1, 2, 3, 4, 5} Dim length = arr.Count '以上一句会被自动翻译成 'Dim length = MyExtionsion.Count(arr) 最后提醒一句,扩展方法只是语法糖,没有必要的扩展最好不要使用它。过多的扩展会导致语法清晰,但设计上糟糕的情况出现。请仔细考虑使用这个特性。...[阅读全文]

posted @ | Feedback (3) | Filed Under [ 技术随笔 Visual Basic 9.0 前沿播报 ]

摘要:在Visual Basic 2005以前的版本,如果类或结构没有定义初始化构造函数,我们就必须用属性逐一赋值的方式。比如'假设有个结构Person,有Name和Age属性 'VB 2005代码 Dim p As Person With p .Name = "Jack" .Age = 27 End With 这样,对象的初始化不能与对象的定义同时完成,多少有些不便。特别是我们在表达式中需要Person类型的时候,无法就地生成,必须另写代码初始化,这会打断我们的思路。Visual Basic 9.0为所有对象提供了一个表达式初始化语法,让你可以对任何公有属性在初始化时一并赋值。(其实我早就想要这个语法了,呵呵)Dim p = New Person{.Name = "Jack", .Age = 27} 看这个语法比以前简洁多了,就好像把With语句写在了初始化语句里一样。初始化语法并没有取代构造函数,而且它还可以和构造函数任何混合使用。比如假设Person类型有一个初始化Name的构造函数,你便可以这样写。Dim p = New Person("Jack") {.Age = 27} 也就是说,初始化器并非要求对所有属性进行初始化。对系统里的List(Of T)类型,VB9还专门实现了List初始化语法:Dim l1 = New List(Of Integer){1, 2, 3, 4} Dim l2 = New List(Of Person){ _ New Person{.Name = "Jack", .Age = 27}, _ New Person{.Name = "Lucy", .Age = 26}} 这种特性着实给我们编写代码带来了很大的方便,也让“表达式”所能表达的内容大大丰富了。“一句话编程”正在慢慢引入VB,呵呵。 最后我们介绍一下匿名类型。当你恰好需要一个结构变量有A As......[阅读全文]

posted @ | Feedback (6) | Filed Under [ 技术随笔 Visual Basic 9.0 前沿播报 ]

摘要:不要惊讶,每个PDC上都会有微软最新产品的前瞻,所以在Visual Basic 2005发布以前看到Visual Basic 9.0的消息就是可以理解的了。Visual Basic 9.0 (codename Visual Basic Orcas)将随下一个Visual Stduio主版本(9.0,Orcas)一起发布,但是微软很早就开始了新语言特性的规划,在今天(PST 9月13日)召开的PDC大会上,用户不仅可以领略到新一代Visual Basic 9.0的特性,还可以在动手实验室里亲自尝试预览版。没有参加PDC大会的VB Fans和开发者,可以从我的Blog获取首轮中文播报。注意现在距离VB9.0正式推出还很远,本系列文章仅对当前公布的内容做简单介绍,并不保证和正式版特性一致。 言归正传,这次Visual Basic 9.0的主题就是数据和动态。VB9试图从语言角度上增强以获得前所未有的数据(包括对象中的数据、数据库和XML)开发体验。其次,Visual Basic试图从动态语言中吸取一些优良的特性,让用户感到更少受限制,更方便。此外还有一些和数据无关的静态特性。我打算将本文分成动态篇和静态篇,分别介绍Visual Basic 9.0近乎于两个世界的开发体验。 我要介绍的Visual Basic 9.0第一个新特性是局部变量类型推测。在以前版本,我们声明变量的同时,必须用As语句指定变量的类型。Dim aInt As Integer = 5 Dim aDbl As Double = 3.33 Dim aStr As String = "Hello" Dim aLst As List(Of Integer) = anotherList.ConvertAll(Of Integer)(PStr.Length) 'VBF语法 我们观察这几个声明,他们的初始化语句都包含了足够确定返回类型的信息,比如“5”就已经确定为Integer。因此,在Visual Basic 9.0中,可以免除局部变量的类型声明,由初始化语句确定。Dim aInt = 5 Dim aDbl = 3.33 Dim aStr = "Hello" Dim aLst = anotherList.ConvertAll(Of Integer)(PStr.Length) 这样,变量的声明就被充分简化了。注意,这些代码似乎在Visual Basic 2005也有效,那么有什么不同呢?这里类型推测发生在编译时,是一种强类型特性。比如将aInt初始化为5,那么aInt并非是定义为Object类型,而是定义为真正的Integer,如果再给aInt赋值无法转换成Integer的数值,就会发生编译错误。在Visual Basic 2005中,Option Strict Off的情况下,不用As语句指定类型会默认为Object类型,这条规则到了Visual Basic 9.0将不再有效,要声明为Object类型必须显式指定As Object。注意最后一个,我们看到泛型类型的类型实参也会随类型推测一并确定,因此不再需要书写前思考返回类型的类型实参具体是什么了。 Visual Basic 9.0还支持For Each循环的循环变量类型自动推测。Dim list As List(Of ALongNameStructure) = ... For Each Dim item......[阅读全文]

posted @ | Feedback (8) | Filed Under [ 技术随笔 Visual Basic 9.0 前沿播报 ]