正在阅读:C# 编程语言的未来功能C# 编程语言的未来功能

2009-03-12 23:34 出处:PConline 作者:Microsoft/ASPCool 责任编辑:ycx
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 { private ItemType[] items; public void Push(ItemType data) { ... } public ItemType Pop() { ... } } 当程序按照以下示例使用 Stack 类时,您可以指定泛型类使用的实际类型。本例使用实例化语句中的尖括号标记将原始的整数类型指定为参数,指示 Stack 类使用此类型: Stack stack = new Stack(); stack.Push(3); int x = stack.Pop(); 执行此操作时,程序将创建 Stack 类的新实例,其中的每个 ItemType 都被提供的整数参数替换。实际上,当程序用整数参数创建 Stack 类的新实例时,在 Stack 类内部本地存储的项目数组将为整数,而不是对象。程序还消除了与将整数压入堆栈相关联的装箱问题。此外,当程序从堆栈弹出项目时,您无需将其显式转换为相应的类型,因为 Stack 类的当前特定实例会将整数本地存储在其数据结构中。 如果希望程序在 Stack 类中存储其他类型的项目,则必须创建一个 Stack 类的新实例并将新类型指定为参数。假设有一个简单的 Customer 类型,希望程序使用 Stack 对象存储该类型。要实现此操作,只需实例化 Stack 类并将 Customer 对象作为其类型参数,即可轻松重复使用程序代码: Stack stack = new Stack(); stack.Push(new Customer()); Customer c = stack.Pop(); 当然,如果程序创建了一个将 Customer 类型作为参数的 Stack 类,则只能在该堆栈中存储 Customer 类型。实际上,C# 中的泛型具有严格的类型,这意味着您不能在该堆栈中存储整数,如以下示例所示: Stack stack = new Stack(); stack.Push(new Customer()); stack.Push(3) // 编译时错误 Customer c = stack.Pop(); // 不需要类型转换。 泛型的优点 使用泛型,程序员只需编写、测试和部署一次代码,即可对各种不同的数据类型重复使用该代码。第一个 Stack 示例具备此功能,第二个 Stack 示例允许程序重复使用对其应用程序性能影响不大的代码。对于值类型,第一个 Stack 示例具有较大的性能问题,而第二个 Stack 示例完全消除了这种问题,因为它去除了装箱和向下的类型转换。 而且,编译时还会对泛型进行检查。当程序使用提供的类型参数实例化泛型类时,此类型参数只能是程序在类定义中指定的类型。例如,如果程序创建了一个 Customer 对象类型的 Stack,就无法将整数压入堆栈。通过强制执行这种操作,可以生成更可靠的代码。 此外,与其他严格的类型实现相比,泛型的 C# 实现降低了代码的膨胀速度。使用泛型创建具有类型的集合,可以在保持操作性能优势的同时避免创建每个类的特定变体。例如,程序可以创建一个参数化的 Stack 类,而无需创建用于存储整数的 IntegerStack、用于存储字符串的 StringStack 以及用于存储 Customer 类型的 CustomerStack。 这样可以增加代码的可读性。只需创建一个 Stack 类,程序就可以将与某个堆栈相关联的所有操作封装在一个使用方便的类中。然后,在创建 Customer 类型的 Stack 时,尽管其中存储了 Customer 类型,但显而易见,程序使用的仍然是堆栈数据结构。
键盘也能翻页,试试“← →”键

关注我们

最新资讯离线随时看 聊天吐槽赢奖品