c#v2.0 扩展特性(1)

转载 2004年07月22日 17:04:00

 Introduction to C# 2.0

C# 2.0 introduces several language extensions, the most important of which are Generics, Anonymous Methods, Iterators, and Partial Types.

C#2.0 介绍几种语言扩展,泛型,匿名方法,迭代器 和、partial Types.

·         Generics permit classes, structs, interfaces, delegates, and methods to be parameterized by the types of data they store and manipulate. Generics are useful because they provide stronger compile-time type checking, require fewer explicit conversions between data types, and reduce the need for boxing operations and run-time type checks.


·         Anonymous methods allow code blocks to be written “in-line” where delegate values are expected. Anonymous methods are similar to lambda functions in the Lisp programming language. C# 2.0 supports the creation of “closures” where anonymous methods access surrounding local variables and parameters.

·         Iterators are methods that incrementally compute and yield a sequence of values. Iterators make it easy for a type to specify how the foreach statement will iterate over its elements.

·         Partial types allow classes, structs, and interfaces to be broken into multiple pieces stored in different source files for easier development and maintenance. Additionally, partial types allow separation of machine-generated and user-written parts of types so that it is easier to augment code generated by a tool.

This chapter gives an introduction to these new features. Following the introduction are four chapters that provide a complete technical specification of the features.


The language extensions in C# 2.0 were designed to ensure maximum compatibility with existing code. For example, even though C# 2.0 gives special meaning to the words where, yield, and partial in certain contexts, these words can still be used as identifiers. Indeed, C# 2.0 adds no new keywords as such keywords could conflict with identifiers in existing code.



Generics permit classes, structs, interfaces, delegates, and methods to be parameterized by the types of data they store and manipulate. C# generics will be immediately familiar to users of generics in Eiffel or Ada, or to users of C++ templates, though they do not suffer many of the complications of the latter.



 Why generics?

Without generics, general purpose data structures can use type object to store data of any type. For example, the following simple Stack class stores its data in an object array, and its two methods, Push and Pop, use object to accept and return data, respectively:


public class Stack
object[] items;
int count;

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

public object Pop() {...}

While the use of type object makes the Stack class very flexible, it is not without drawbacks. For example, it is possible to push a value of any type, such a Customer instance, onto a stack. However, when a value is retrieved, the result of the Pop method must explicitly be cast back to the appropriate type, which is tedious to write and carries a performance penalty for run-time type checking:


Stack stack = new Stack();
stack.Push(new Customer());
Customer c = (Customer)stack.Pop();

If a value of a value type, such as an int, is passed to the Push method, it is automatically boxed. When the int is later retrieved, it must be unboxed with an explicit type cast:


Stack stack = new Stack();
int i = (int)stack.Pop();

Such boxing and unboxing operations add performance overhead since they involve dynamic memory allocations and run-time type checks.


A further issue with the Stack class is that it is not possible to enforce the kind of data placed on a stack. Indeed, a Customer instance can be pushed on a stack and then accidentally cast it to the wrong type after it is retrieved:



Stack stack = new Stack();
stack.Push(new Customer());
string s = (string)stack.Pop();

While the code above is an improper use of the Stack class, the code is technically speaking correct and a compile-time error is not reported. The problem does not become apparent until the code is executed, at which point an InvalidCastException is thrown.

The Stack class would clearly benefit from the ability to specify its element type. With generics, that becomes possible.



Creating and using generics


Generics provide a facility for creating types that have type parameters. The example below declares a generic Stack class with a type parameter T. The type parameter is specified in < and > delimiters after the class name. Rather than forcing conversions to and from object, instances of Stack accept the type for which they are created and store data of that type without conversion. The type parameter T acts as a placeholder until an actual type is specified at use. Note that T is used as the element type for the internal items array, the type for the parameter to the Push method, and the return type for the Pop method:


public class Stack
T[] items;
int count;

public void Push(T item) {...}

public T Pop() {...}

When the generic class Stack is used, the actual type to substitute for T is specified. In the following example, int is given as the type argument for T:

当泛型类Stack被使用,替代T的真实类型将被指定。下面的例子里,int 被指定代替T

Stack stack = new Stack();
int x = stack.Pop();

The Stack type is called a constructed type. In the Stack type, every occurrence of T is replaced with the type argument int. When an instance of Stack is created, the native storage of the items array is an int[] rather than object[], providing substantial storage efficiency compared to the non-generic Stack. Likewise, the Push and Pop methods of a Stack operate on int values, making it a compile-time error to push values of other types onto the stack, and eliminating the need to explicitly cast values back to their original type when they’re retrieved.

Stack类型被称作构造类型. Stack里,每次出现T将被类型参数int代替。当一个Stack实例被创建,本身存储items数组是一个int型数组,比非泛型栈的对象数组提供真实性存储效率。同样的,PushPop方法操作int 值,如果push其他类型的数据给栈,将导致一个编译时错误,它排除了当值被返回时所要求的显式转化成原型。


Generics provide strong typing, meaning for example that it is an error to push an int onto a stack of Customer objects. Just as a Stack is restricted to operate only on int values, so is Stack restricted to Customer objects, and the compiler will report errors on the last two lines of the following example:

泛型提供强类型,意味着举例说来 将一个整型数据压入Customer 泛类型的栈。正像一个int泛型栈被严格约束只能操作int型,因此Customer型被严格要求操作Customer对象。下面例子的最后两行,编译器编译的时候会报告错误。

Stack stack = new Stack();
stack.Push(new Customer());
Customer c = stack.Pop();
stack.Push(3);                   // Type mismatch error
int x = stack.Pop();             // Type mismatch error

Generic type declarations may have any number of type parameters. The Stack example above has only one type parameter, but a generic Dictionary class might have two type parameters, one for the type of the keys and one for the type of the values:


public class Dictionary
public void Add(K key, V value) {...}

public V this[K key] {...}

When Dictionary is used, two type arguments would have to be supplied:


Dictionary dict = new Dictionary();
dict.Add("Peter", new Customer());
Customer c = dict["Peter"];

c#v2.0 扩展特性 翻译(1)

 Introduction to C# 2.0C# 2.0 introduces several language extensions, the most important of which ar...
  • eshao
  • eshao
  • 2004年07月19日 16:37
  • 1189

c#v2.0 扩展特性(2)

   Generic type instantiations 范型实例化 Similar to a non-generic type, the compiled representation of a...
  • lovered
  • lovered
  • 2004年07月22日 17:06
  • 817

c#v2.0 扩展特性 翻译(2)

  • zgqtxwd
  • zgqtxwd
  • 2008年05月01日 04:07
  • 77

c#v2.0 扩展特性 翻译(2)

 Generic type instantiations范型实例化Similar to a non-generic type, the compiled representation of a gen...
  • eshao
  • eshao
  • 2004年07月22日 11:11
  • 1171


QinQ映射配置与管理 QinQ映射功能可以将用户的VLAN标签映射为指定的VLAN标签,从而起到屏蔽不同用户VLAN标签的作用。但QinQ映射功能只能在子接口上应用,通过QinQ映射功能,子接口在向...
  • kaoa000
  • kaoa000
  • 2017年07月07日 13:25
  • 250

VS2008编译出现问题:error C2485: “__restrict”: 无法识别的扩展属性 解决办法

VS2008编译出现问题:error C2485: “__restrict”: 无法识别的扩展属性 解决办法 错误:Error3 error C2485: '__restrict' : unre...
  • swanabin
  • swanabin
  • 2014年01月06日 12:18
  • 3403


PDO概述:     PDO是PHP Data Object (PHP数据对象)的简称,它是与PHP5.1版本一起发行的。目前支持的数据库包括Firebird、FreeTDS、Interbase、M...
  • qq_28602957
  • qq_28602957
  • 2016年03月29日 16:49
  • 1736


  • tingyuxuan140
  • tingyuxuan140
  • 2017年06月25日 21:51
  • 90


1、建立自定义特性 public class RemarkAttribute : Attribute { public RemarkAttribute(string rem...
  • zhgl7688
  • zhgl7688
  • 2016年04月02日 14:00
  • 798


  • kaoa000
  • kaoa000
  • 2017年06月23日 12:30
  • 488
您举报文章:c#v2.0 扩展特性(1)