测试员版本
并不是说,测试工具是完美的,NUint的"绿色化、干净化"的理念使它有一种精炼的纯度,使之非常易于集成进你的开发过程中。另一方面,VSTS允许以多种方法进行测试,测试用例能在调试器下运行或单独运行,也能选择多个不同的测试等等。悲哀的是,就测试函数的可伸缩性及多样性来说,FIT(测试用例输入输出的表格描述)还未获得支持。
开发人员版本 对开发人员来说,VSTS在基于Visio建模的基础上,整合了单元测试。它没有了架构师版本中的,以部署为中心的建模器,并加载了测试员版本中的测试用例管理工具。这种平衡真有点难以取舍:如果你能放弃建模器,测试员版本的VSTS将是更好的SKU。
包装盒中的秘密 在Visual Studio 2005中,微软支持以下四种语言:C#、Visual Basic、C++、J#,C#与Visual Basic可是 .NET中的重量级选手。在 .NET 2.0中,最主要变化的是演变为通用语言运行时库(CLR),而C# 2.0则在其中加入了对泛型的支持,最常见的是集合类库、混合了特定类中类型安全的泛型。
泛型存在的必要性已争论了很久,支持"动态语言"中隐式类型转换的爱好者,对类型的安全声明并不感兴趣,其他的,如Java领域,也表示与它们引入的复杂性相比,所提供的价值并不明显。但就个人来说,还是倾向于显式类型转换,实际上,在Visual Basic的世界中,尽管支持泛型,但它们似乎总不是讨论的焦点。(所有的 .NET语言至少必须能使用泛型,所有微软公司的语言都能使用及生成泛型。)
CLR中泛型的实现,还是有点意思的。在C++中,泛型的实例化是在编译时完成的--编译器为每个实例化的泛型,都生成了一个不相同的二进制类型。在Java 5中,类型安全的语法,由一个单一的存储了Object引用的运行时泛型提供支持,远比C++所使用的模型简洁得多,但却需要对值类型进行装箱及解箱(转换为及转换自基于Object的引用类型)。在CLR中,如果泛型的类型参数为一个值类型,在加载时,一个确切的泛型会被实例化,这让CLR泛型有了Java泛型中的可伸缩性及简洁性,且对值类型来说,也提高了执行效率。
例1是C#及Java的对比程序,程序用于显示装箱带来的性能损失。编译并运行在一个2.66G,32位Intel处理器上,系统为VMWare中的Windows Server 2003,并为其分配了1G的
内存。对比开发工具为C# 2.0及Java JDK 5.0 Update 6,C#程序在3.01秒内运行完毕,而Java程序在10.109秒内运行完毕。虽然这可能代表了最坏情况下的Java表现,但也表明装箱的性能损失真的是非常大。
例1:C#及Java的对比程序
//Program.cs using System; using System.Collections.Generic; using System.Text;
namespace ConsoleApplication1 { class Program { static void Main(string[] args) { RunIt(); DateTime start = DateTime.Now; for (int i = 0; i < 5; i++) { RunIt(); } TimeSpan elapsed = DateTime.Now - start; Console.WriteLine("Elapsed time: {0} ms", elapsed); Console.ReadLine(); } static void RunIt() { List<int>[] n = new List<int>[5]; for (int i = 0; i < n.Length; i++) { n[i] = new List<int>(); } for (int i = 0; i < 1000000; i++) { n[0].Add(1); } for (int i = 1; i < n.Length; i++) { List<int> newArray = n[i]; List<int> oldArray = n[i - 1]; foreach (int j in oldArray) { newArray.Add(oldArray[j] * 2); } } for (int i = 0; i < n.Length; i++) { List<int> array = n[i]; foreach (int j in array) { int number = j; } } } } }
//GenericValueArrayListTest.java import java.util.*;
public class GenericValueArrayListTest { public static void main(String[] args) { RunIt(); Date start = new Date(); for(int i = 0; i < 5; i++){ RunIt(); }
Date finish = new Date(); System.out.printf("Elapsed time: %d ms", finish.getTime() - start.getTime()); }
static void RunIt() { ArrayList<Integer>[] n = new ArrayList[5]; for(int i = 0; i < n.length; i++){ n[i] = new ArrayList<Integer>(); } for (int i = 0; i < 1000000; i++) { n[0].add(1); } for(int i = 1; i < n.length; i++){ ArrayList<Integer> newArray = n[i]; ArrayList<Integer> oldArray = n[i - 1]; for(int j : oldArray){ newArray.add(j * 2); } } for (int i = 0; i < n.length; i++) { ArrayList<Integer> array = n[i];
for(int j : array){ int number = j; } } } } |
除了泛型,C# 2.0主要是通达LINQ(Language Integrated Query 语言集成查询)的一块踏脚石。这又是一种横跨微软公司语言产品的功能,但这次是由C#充当开路先锋。LINQ整合lambda函数、类型推论及智能库,设计的目的是为了使查询--不只是数据库而是任意集合--能成为主流编程语言中的第一类要素。
回过头来看Visual Basic.NET,这个版本试图在抗拒转向完全面向对象语言的社区中,重拾对VB的激情。诚然,比较以前的版本,这次的VB.NET无疑是一次巨大的进步,但社区中的很多人也感到,即使不能带来任何好处,也必须重写以往工作正常的程序,所以我们看到,一些人继续使用VB.NET,而更多的人转向了C#,还有一些人则全然抗拒 .NET。另外,Visual Basic引入了"My"命名空间,其目的是为了降低基类库(Base Class Library)的复杂性及提供对对象的即时访问,还加强了"编辑并继续"这个深受大家喜爱的功能。
在2005年秋天的专业开发者大会上,微软展示了代号为"Visual Basic Orcas"的部分功能,包括了LINQ及在语言字面上直接整合XML。如同C#一样,这个版本的VB看起来会有重大的改变了。
最后来看一下C++,此次Visual Studio中最重要的变化无疑是C++/CLI了,这是一个对C++语言的扩展,并为托管对象添加了"句柄"作为第一类语言实体,在某种意义上来说,其与指针的语法非常相似。并且,使用gcnew关键字来实例化可垃圾回收的托管对象,另外,确定性最终清理也是一大亮点。相比Visual Studio 2003通过双下划线来访问托管对象,句柄的语法似乎更容易使用一些。
另一方面,Visual C++ 2005在编写桥接或混合托管与非托管代码的程序上,显示出了无与伦比的可伸缩性:你可编写完全控制进入点的DLL、在各种字符串表示法之间进行转换、还可充分挖掘Win32的性能,并且,在托管领域,微软可能会说:"对CLR而言,没有比C++更低级的语言了,包括CLR自身。"(虽然有点夸大,但也可看出微软在重心在何处。)
对本地程序(native program)开发者来说,Visual C++ 2005也有几项让人感兴趣的特性,比如:标准库中增强了安全的函数实现--strcpy_s()以及其他;OpenMP的实现--其允许对特定类型的操作,以共享内存的方式并行处理(一般运用于数组算法上);可支持更多的设备等等;最后,要提一下,对基于Windows的SmartPhone本地程序开发,现在可在Visual Studio中完成了。
既然说到设备,就讲得再开一点,Visual Studio 2005扩大了语言可支持设备的范围,.NET Compact Framework也有了P/Invoke功能,如果缺少它,那将是开发中的一个重大障碍。现在,.NET Framework已有了32位及64位版本,在64位Windows上将会并行运行,以避免"DLL Hell"。当然了,Visual C++ 2005也能进行本地64位程序开发。