您的位置:首页 > 编程语言 > C#

CLR Via C# 3rd 阅读摘要 -- Chapter 12 - Generics

2010-04-07 16:06 507 查看

Generics in the Framework Class Library

1. System.Collections.Generic、System.Collections.ObjectModel、System.Collections.Concurrent;

2. System.Array提供了很多静态的泛型方法,比如:AsReadOnly,BinarySearch,ConvertAll,Exists,Find,FindAll,FindIndex,FindLast,FindLastIndex,ForEach,IndexOf,LastIndexOf,Resize,Sort,TrueForAll。

Wintellect's Power Collections Library

1. Generic Collection Classes from Wintellect's Power Collections Library:

BigList<T>:有序的,当元素超过100时很有效;

Bag<T>:无序的,散列的,可重复;

OrderedBag<T>:有序的,可重复;

Set<T>:无序的,不可重复;

OrderedSet<T>:有序的,不可重复;

Deque<T>:双向队列;

OrderedDictionary<TKey, TValue>:键有序,一个键一个值;

MultiDictionary<TKey, TValue>:键无序,一个键对个值,键可重复,

OrderedMultiDictionary<TKey, TValue> :键有序,一个键多个值,键可重复。

Generics Infrastructure

1. 要支持泛型,.NET基础设施要做到 :

创建新的IL指令;

修改现有的元数据表格式;

修改编程语言以支持新的语法;

修改编译器以生成相应的IL指令和元数据表;

修改JIT处理新的IL指令;

创建新的反射成员使得开发者可以查询泛型参数的类型和成员信息;

修改调试器以调试泛型代码;

修改IDE的IntelliSense支持显示泛型特性。

2. Open and Closed Types:

type objects:CLR创建的应用程序使用的每个类型的内部数据结构;

open type:一个有泛型类型参数的类型。CLR不允许构造任何open type的实例;

close type:所有的泛型参数都被实际类型传入替换。这时候CLR允许构造类型实例。

3. Generic Types and Inheritance,推荐:先定义一个普通的Node基类,然后定义一个泛型的TypedNode类(base Node);

4. using DateTimeList = System.Collections.Generic.List<System.DateTime>优于定义一个类internal sealed class DateTimeList : List<DateTime>;

5. 泛型,CLR会针对每一个方法和类型的组合生成本地代码,这会引起代码爆炸,使应用程序的工作集臃肿,并因此影响性能;

6. 针对代码爆炸,CLR所做的优化:

如果一个方法使用一个实际的类型参数调用,之后总是以同样的类型参数调用,CLR针对这个方法/类型组合只编译一次代码;

CLR把所有的引用类型参数看成是同一个,所以这段代码就可以共享。注意值类型就不行了。

Generic Interfaces

1. 对值类型,泛型的接口可以避免装箱操作。

Generic Delegates

1. 委托实际就是一个类,实现类型安全的回调。包含四个方法:构造器,Invoke,BeginInvoke,EndInvoke;

2. 推荐使用泛型的Action和Func。

Delegate and Interface Contravariant and Covariant Generic Type Arguments

1. Invariant,Contravariant,Covariant:

Invariant:泛型类型参数不能被改变;

Contravariant(逆变):泛型类型参数可以从一个类变成一个从它继承的子类(in);

Covariant(协变):泛型类型参数可以从一个类变成该类的父类(out)。

public delegate TResult Func<in T, out TResult>(T arg);

2. 使用带泛型参数并有返回值的委托时,推荐总是指定inout以表明逆变或协变。

Generic Methods

1. 当你定义一个泛型类、结构、接口之后,这个类型中的任何方法都可以引用该类型的类型参数;

2. 泛型方法与类型推导,在进行类型推导时,C#使用变量的数据类型,而不是该变量所指对象的实际类型;

3. 编译器总是优先使用显示匹配。

Generics and Other Members

1. 在C#中,properties、indexers、operator methods、constructors、finalizers本身不能有类型参数。

Verifiability and Constraints

1. public static T Min<T>(T 01, T 02) where T : IComparable<T> { ... };

2. CLR不允许基于类型参数名称或约束的重载;

3. 当重载一个virtual的泛型方法时,重载的方法必须指定跟基类相同数量的类型参数,并且具有相同的约束;

4. 第一约束:

可以是一个没有密封的类的引用类型;

不能是这些特定类型:System.Object,System.Array,System.Delegate,System.MulticastDelegate,System.ValueType,System.Enum,System.Void;

两个特别的第一约束:class struct

编译器和CLR将System.Nullable<T>值类型作为一个特定类型,它不能满足struct的约束。 因为CLR想要禁止递归类型比如Nullable<Nullable<T>>。

5. 第二约束:where T : TBase

6. 构造器约束:where T : new()

7. 其他的可验证性的问题:

除非转换的类型跟约束中的类型相容,否则转换泛型变量到其他类型是非法的。但是可以先转换成Object或者使用as

除非泛型类型约束成一个引用类型,否则设置泛型变量为null是非法的。但是可以用default(T)来设置默认值;

无论怎样,用==或者!=比较泛型变量和null都是非法的;

如果泛型类型参数不是约束成引用类型,比较两个相同类型的泛型变量也是非法的。主要是非原生值类型不知道怎么处理==操作符;

不能在泛型变量上使用运算符。

本章小结

本章讲了现代编程语言中的一个很重要的概念:泛型。泛型带来的好处:源代码保护;类型安全;更清爽的代码;更好的性能。解释了泛型(泛型类型,泛型接口,泛型委托,泛型方法)的实现机制和限制,然后介绍了如何对泛型类型进行验证和约束。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: