日期:2012-07-30  浏览次数:20555 次

C# 编程语言的未来功能

Prashant Sridharan
Microsoft Corporation
2003年3月
适用于:
   Microsoft® Visual C#(TM)

摘要:Microsoft Corporation 正在开发 C# 语言的下一个主要版本。本文介绍了四种主要的新功能,即泛型、迭代程序、匿名方法和局部类型。

目录
简介
泛型
迭代程序
匿名方法
局部类型
符合标准
可用性
更多信息
简介
C# 是创新性的新式编程语言,它巧妙地结合了最常用的行业语言和研究语言中的功能。在保持 C# 设计思想不变的同时,Microsoft 在 C# 语言中引入了几种潜在的新功能,提高了开发人员在语言构造方面的效率。

Microsoft C#
自 2001 年 2 月 C# 问世以来,很多开发人员已经开始使用 C# 编程语言来构建软件。而 Microsoft 自身也使用 C# 构建了几种正式的应用程序,包括 .NET Framework、MSN Web 属性和 Tablet PC SDK。由此可见,C# 是一种适用于构造高品质商业软件的语言。

C# 语言中的许多功能是基于以下四种不同设计目标而创建的:

统一的类型系统以及简化值类型和引用类型在 C# 语言中的用法。
通过 XML 注释、特性、属性、事件和委托等功能建立基于组件的设计。
借助 C# 语言的独特功能(包括安全的指针操作、溢出检查等)建立实用的开发人员控制功能。
建立诸如 foreach 和 using 语句这样的实用语言构造,提高开发人员的效率。
在 C# 语言的“Visual Studio for Yukon”版本中,Microsoft 计划通过将广泛的研究语言和行业语言中的各种功能结合在一起建立一种简洁、实用的语法。这些语言功能包括泛型、迭代程序、匿名方法和局部类型。

潜在的未来功能
实际上,C# 的未来创新功能主要基于统一的类型系统、基于组件的开发、开发人员控制功能和实用的语言构造。下面总结了 Microsoft 计划在 C# 语言的下一个主要版本中提供的四种主要的新功能。这些功能的设计尚未完成,Microsoft Corporation 欢迎广大的开发人员针对这些功能发表评论。

泛型
随着项目变得越来越复杂,程序员日益需要一种方法来更好地重复使用和自定义他们现有的基于组件的软件。为了实现在其他语言中重复使用高级代码,程序员通常要使用一种名为“泛型”的功能。C# 将包括一种安全且高效的泛型,它与 C++ 中的模板和 Java 语言中提出的泛型在语法上只是稍有差别,但在实现方式上却存在很大差别。

生成最新的泛型类
利用目前的 C#,程序员可以通过在基本对象类型的实例中存储数据来创建有限形式的真正泛型。由于在 C# 中每个对象都是从基本对象类型继承的,再加上统一 .NET 类型系统的装箱和取消装箱功能,程序员可以将引用类型和值类型存储到对象类型的变量中。但是,对于引用类型、值类型与基本对象类型之间的转换,还有一些性能缺陷。

为了说明这一点,以下代码示例创建了一个简单的 Stack 类型,其中包含两个操作“Push”和“Pop”。Stack 类将其数据存储在对象类型的数组中,Push 和 Pop 方法使用基本对象类型来接受和返回数据:

public class Stack
{
   private object[] items = new object[100];

   public void Push(object data)
   {
      ...
   }

   public object Pop()
   {
      ...
   }
}
然后,就可以将自定义类型(例如 Customer 类型)压入堆栈。但是,如果程序需要检索数据,则需要将 Pop 方法的结果(基本对象类型)显式转换成 Customer 类型。

Stack s = new Stack();
s.Push(new Customer());
Customer c = (Customer) s.Pop();
如果将一个值类型(例如一个整数)传递给 Push 方法,运行时会自动将其转换为引用类型(该过程称作装箱),然后将其存储在内部数据结构中。与此类似,如果程序要从堆栈中检索一个值类型(例如一个整数),则需要将从 Pop 方法获取的对象类型显式转换成值类型,该过程称作取消装箱:

Stack s = new Stack();
s.Push(3);
int i = (int) s.Pop();
值类型和引用类型之间的装箱和取消装箱操作非常繁重。

而且,在当前的实现中,无法限制堆栈中放置的数据类型。实际上,可以先创建堆栈,然后将 Customer 类型压入堆栈。然后,可使用同一堆栈并尝试将数据弹出,接着将其转换为其他类型,如下例所示:

Stack s = new Stack();
s.Push(new Customer());

Employee e = (Employee) s.Pop();
尽管上一个代码示例错误地使用了要实现的单个类型 Stack 类,应视为错误,但它实际上却是合法代码,对它进行编译时不会出现问题。但在运行时,该程序会由于无效转换操作而失败。

创建和使用泛型
使用 C# 中的泛型可以根据它们所用的类型创建专供编译器使用的高效数据结构。创建这些所谓的参数化类型后,其内部算法保持不变,但其内部数据的类型可以随着最终用户的设置而改变。

为了帮助开发人员节省学习该语言的时间,C# 中泛型的声明方法与 C++ 中的大致相同。程序员可以按通常的方法创建类和结构,并使用尖括号标记(< 和 >)指定类型参数。使用类时,必须用该类的用户提供的实际类型替换每个参数。

下例将创建一个 Stack 类,在此类声明后的尖括号中指定并声明一个名为 ItemType 的类型参数。泛型 Stack 类的实例将接受为其创建的类型并在本地存储该类型的数据,而不是在创建的类型与基本对象类型之间进行转换。类型参数 ItemType 充当代理,直到在实例化过程中指定了类型并将其用作内部项数组的类型(即 Push 方法的参数类型和 Pop 方法的返回类型):

public class Stack<ItemType>
{
   private ItemType[] items;

   public void Push(ItemType data)
   {
      ...
   }

   public ItemType Pop()
   {
      ...
   }
}
当程序按照以下示例使用 Stack 类时,您可以指定泛型类使用的实际类型。本例使用实例化语句中的尖括号标记将原始的整数类型指定为参数,指示 Stack 类使用此类型:

Stack<int> stack = new Stack<int>();
stack.Push(3);
int x = stack.Pop();
执行此操作时,程序将创建 Stack 类的新实例,其中的每个 ItemType 都被提供的整数参数替换。实际上,当程序用整数参数创建 Stack 类的新实例时,在 Stack 类内部本地存储的项目数组将为整数,而不是对象。程序还消除了与将整数压入堆栈相关联的装箱问题。此外,当程序从堆栈弹出项目时,您无需将其显式转换为相应的类型,因为 Stack 类的当前特定实例会将整数本地存储在其数据结构中。

如果希望程序在 Stack 类中存储其他类型的项目,则必须创建一个 Sta