C#学习笔记-接口,集合与泛型
罗朝辉(http://www.cnblogs.com/kesalin/)
《C#与.NET高级程序设计》读书笔记
接口
1, 接口可以被定义为抽T象成员T的集合。接口可以包含方法,属性,事件以及索引器。实现接口是一个要么全要要么全不要的问题,不能部分实现接口的方法。
2,使用 as 关键字获取接口应用。
Person p = new Person("LiLai");
IStudent s = p as IStudent;
if (s != NULL)
Console.WriteLine("{0} is a student", p.Name);
else
Console.WriteLine("{0} is not a student", p.Name);
我们也可以使用 is 来判断一个对象是否实现了某个接口:
if (p is IStudent)
....
else
...
3,接口可以如同对象一样被当做参数,返回值使用。
4,通过显式接口实现,解决实现多个接口的同名方法引起的命名冲突。显式实现的成员是自动私有的,所以使用这些成员的时候必须将对象显式转换为对应的接口。
5,接口支持继承,并支持多重继承。
6,枚举对象的构建
如果自定义类型要和C#的foreach关键字一起使用的话,容器就需要定义一个名为GetEnumerator()的方法,它由IEnumerator接口类型来定制。通常这个方法的实现只是交给保存子对象的内部成员,然而,我们也可以使用yield return语法来提供多个“命名迭代器” 方法。
7,回调接口
回调接口通常不会由对获取事件感兴趣的对象直接实现,而是由一个叫做接收器对象的辅助对象来实现。事件的发送者会在合适的情况下调用接收器。 回调接口很有点像ObjC中的 delegate。
集合和泛型
1,最基础的容器就是 System.Array,然而我们不能在增加或删除元素时自动调整Array的大小。我们可以利用定义在System.Collections命名空间中的接口ICollection,IComparer,IDictionary,IDictionaryEnumerator,IEnumerable,IEnumerator,IHashCodeProvider,IList等来实现更灵活的容器,或使用System.Collections.Generic命名空间的泛型容器类型Collection<T>,Comparer<T>, Dictionary<TKey, TValue>, List<T>, Queue<T>, SortedDictionary<T>, Stack<T>, LinkedList<T>, ReadOnlyCollection<T>等。
2,装箱和撤箱
.NET平台支持两大类的数据类型:值类型和引用类型。简单来说,装箱就是把值类型转换为引用类型,反之就是撤箱。具体点说:装箱就是把变量保存在System.Object中,将值类型显示转换为相应的引用类型;而撤箱就是把保存在对象引用中的值转换回栈上的相应值类型。撤箱必须回到合适的数据类型,否则会引发InvalidCastException异常。
装箱和撤箱能方便我们往容器中存取值类型,但是也是有成本的,因为装箱需要创建新对象,撤箱时需要销毁对象,而且强制转换也可能引起类型安全问题。因此我们常用泛型容器来解决此类问题。
3,C#中泛型基本使用与C++相同。C#泛型中引进了 default 关键字,以用于设置类型参数的默认值,数值的默认值为0,引用类型的默认值为null,一个结构的字段被设为0或null。
4,C#中使用 where 关键字来约束类型参数,where 可以用来控制类型参数的各种特性,但目前还不支持运算符约束。
5,泛型类可以作为其他类的基类,它可以定义许多虚方法或抽象方法,但对泛型类的派生类有一些限制:派生类必须指定一个类型参数,如果基类定义了泛型虚方法或抽象方法,派生类型必须使用指定类型参数重写泛型方法。