这类庞杂不仅是关于初学者,关于一些有开辟履历的.NET开辟者,也是一个不那么轻易控制的特征。
接下来我们来相识一下C#2.0到场的特征:泛型。
一.泛型的基本特征概述
在现实项目开辟中,任何API只要将object作为参数范例和返回范例运用,便可以在某个时刻触及强范例转换。提到强范例转换,预计许多开辟者第一回响反映就是“效力”这个次,关于强范例的利害主要看运用者运用的环境,天底下没有相对的坏事,也没有相对的功德,有关强范例的题目不是本次的重点,不做重点引见。
泛型是CLR和C#供应的一种特别机制,支撑另一种情势的代码重用,即“算法重用”。泛型完成了范例和要领的参数化,泛型范例和要领也可以让参数通知运用者运用什么范例。
泛型所带来的优点:更好的编译时搜检,更多在代码中能直接表现的信息,更多的IDE支撑,更好的机能。可以有人会疑问,为何泛型会带来这么多优点,运用一个不能辨别差别范例的通例API,相称于在一个动态环境中接见谁人API。
CLR许可建立泛型援用和泛型值范例,然则不许可建立泛型罗列,而且CLR许可建立泛型接口和泛型托付,CLR许可在援用范例、值范例或接口中定义泛型要领。定义泛型范例或要领时,为范例指定了任何变量(如:T)都称为范例参数。(T是一个变量名,在源代码中可以运用一个数据范例的任何位置,都可以运用T)在C#中泛型参数变量要么成为T,要么最少一大写T开首。
二.泛型类、泛型接口和泛型托付概述
1.泛型类
泛型范例仍然是范例,所以可以从任何范例派生。运用一个泛型范例并指定范例实参时,现实是在CLR中定义一个新范例对象,新范例对象是从泛型派生自的谁人范例派生的。
运用泛型范例参数的一个要领在基尼险谁人JIT编译时,CLR猎取IL,用指定的范例实参举行替代,然后建立适当的当地代码。
假如没有为泛型范例参数供应范例实参,那就么就是未绑定泛型范例。假如指定了范例实参,该范例就是已组织范例。
已组织范例可所以开辟或关闭的,开辟范例还包括一个类ixngcanshu,而关闭范例则不是开辟的,范例的每一个部份都是明白的。一切代码现实都是在一个关闭的已组织范例的高低文中实行。
泛型类在.NET的运用主要在鸠合类中,大多数鸠合类在System.Collections.Generic和System.Collections.ObjectModel类中。下面简朴的引见一种泛型鸠合类:
(1).SynchronizedCollection:供应一个线程平安鸠合,个中包括泛型参数所指定范例的对象作为元素.
[ComVisible(false)] public class SynchronizedCollection<T> : IList<T>, ICollection<T>, IEnumerable<T>, IList, ICollection, IEnumerable { /// <summary> /// 初始化 <see cref="T:System.Collections.Generic.SynchronizedCollection`1"/> 类的新实例。 /// </summary> public SynchronizedCollection(); /// <summary> /// 经由过程用于对线程平安鸠合的接见举行同步的对象来初始化 <see cref="T:System.Collections.Generic.SynchronizedCollection`1"/> 类的新实例。 /// </summary> /// <param name="syncRoot">用于对线程平安鸠合的接见举行同步的对象。</param><exception cref="T:System.ArgumentNullException"> <paramref name="syncRoot"/> 为 null。</exception> public SynchronizedCollection(object syncRoot); /// <summary> /// 运用指定的可罗列元素列表和用于对线程平安鸠合的接见举行同步的对象来初始化 <see cref="T:System.Collections.Generic.SynchronizedCollection`1"/> 类的新实例。 /// </summary> /// <param name="syncRoot">用于对线程平安鸠合的接见举行同步的对象。</param> <param name="list">用于初始化线程平安鸠合的元素的 <see cref="T:System.Collections.Generic.IEnumerable`1"/> 鸠合。</param> <exception cref="T:System.ArgumentNullException"><paramref name="syncRoot"/> 或 <paramref name="list"/> 为 null。</exception> public SynchronizedCollection(object syncRoot, IEnumerable<T> list); /// <summary> /// 运用指定的元素数组和用于对线程平安鸠合的接见举行同步的对象来初始化 <see cref="T:System.Collections.Generic.SynchronizedCollection`1"/> 类的新实例。 /// </summary> /// <param name="syncRoot">用于对线程平安鸠合的接见举行同步的对象。</param> <param name="list">用于初始化线程平安鸠合的 <paramref name="T"/> 范例元素的 <see cref="T:System.Array"/>。</param> <exception cref="T:System.ArgumentNullException"><paramref name="syncRoot"/> 或 <paramref name="list"/> 为 null。</exception> public SynchronizedCollection(object syncRoot, params T[] list); /// <summary> /// 将项增加到线程平安只读鸠合中。 /// </summary> /// <param name="item">要增加到鸠合的元素。</param> <exception cref="T:System.ArgumentException">设置的值为 null,或许不是鸠合的准确泛型范例 <paramref name="T"/>。</exception> public void Add(T item); /// <summary> /// 从鸠合中移除一切项。 /// </summary> public void Clear(); /// <summary> /// 从特定索引处最先,将鸠合中的元素复制到指定的数组。 /// </summary> /// <param name="array">从鸠合中复制的 <paramref name="T "/>范例元素的目标 <see cref="T:System.Array"/>。</param> <param name="index">复制最先时地点的数组中的从零最先的索引。</param> public void CopyTo(T[] array, int index); /// <summary> /// 肯定鸠合是不是包括具有特定值的元素。 /// </summary> /// /// <returns> /// 假如在鸠合中找到元素值,则为 true;否则为 false。 /// </returns> /// <param name="item">要在鸠合中定位的对象。</param> <exception cref="T:System.ArgumentException">设置的值为 null,或许不是鸠合的准确泛型范例 <paramref name="T"/>。</exception> public bool Contains(T item); /// <summary> /// 返回一个轮回接见同步鸠合的罗列数。 /// </summary> /// /// <returns> /// 一个 <see cref="T:System.Collections.Generic.IEnumerator`1"/>,用于接见鸠合中存储的范例的对象。 /// </returns> public IEnumerator<T> GetEnumerator(); /// <summary> /// 返回某个值在鸠合中的第一个婚配项的索引。 /// </summary> /// /// <returns> /// 该值在鸠合中的第一个婚配项的从零最先的索引。 /// </returns> /// <param name="item">从鸠合中移除一切项。</param><exception cref="T:System.ArgumentException">设置的值为 null,或许不是鸠合的准确泛型范例 <paramref name="T"/>。</exception> public int IndexOf(T item); /// <summary> /// 将一项插进去鸠合中的指定索引处。 /// </summary> /// <param name="index">要从鸠合中检索的元素的从零最先的索引。</param><param name="item">要作为元素插进去到鸠合中的对象。</param> <exception cref="T:System.ArgumentOutOfRangeException">指定的 <paramref name="index"/> 小于零或大于鸠合中的项数。</exception> <exception cref="T:System.ArgumentException">设置的值为 null,或许不是鸠合的准确泛型范例 <paramref name="T"/>。</exception> public void Insert(int index, T item); /// <summary> /// 从鸠合中移除指定项的第一个婚配项。 /// </summary> /// /// <returns> /// 假如从鸠合中胜利移除了项,则为 true;否则为 false。 /// </returns> /// <param name="item">要从鸠合中移除的对象。</param> public bool Remove(T item); /// <summary> /// 从鸠合中移除指定索引处的项。 /// </summary> /// <param name="index">要从鸠合中检索的元素的从零最先的索引。</param> <exception cref="T:System.ArgumentOutOfRangeException">指定的 <paramref name="index"/> 小于零或大于鸠合中的项数。</exception> public void RemoveAt(int index); /// <summary> /// 从鸠合中移除一切项。 /// </summary> protected virtual void ClearItems(); /// <summary> /// 将一项插进去鸠合中的指定索引处。 /// </summary> /// <param name="index">鸠合中从零最先的索引,在此处插进去对象。</param><param name="item">要插进去到鸠合中的对象。</param> <exception cref="T:System.ArgumentOutOfRangeException">指定的 <paramref name="index"/> 小于零或大于鸠合中的项数。</exception> <exception cref="T:System.ArgumentException">设置的值为 null,或许不是鸠合的准确泛型范例 <paramref name="T"/>。</exception> protected virtual void InsertItem(int index, T item); /// <summary> /// 从鸠合中移除指定 <paramref name="index"/> 处的项。 /// </summary> /// <param name="index">要从鸠合中检索的元素的从零最先的索引。</param> <exception cref="T:System.ArgumentOutOfRangeException">指定的 <paramref name="index"/> 小于零或大于鸠合中的项数。</exception> protected virtual void RemoveItem(int index); /// <summary> /// 运用另一项替代指定索引处的项。 /// </summary> /// <param name="index">要替代的对象的从零最先的索引。</param><param name="item">要替代的对象。</param> <exception cref="T:System.ArgumentOutOfRangeException">指定的 <paramref name="index"/> 小于零或大于鸠合中的项数。</exception> protected virtual void SetItem(int index, T item); /// <summary> /// 返回一个轮回接见同步鸠合的罗列数。 /// </summary> /// /// <returns> /// 一个 <see cref="T:System.Collections.Generic.IEnumerator`1"/>,用于接见鸠合中存储的范例的对象。 /// </returns> IEnumerator IEnumerable.GetEnumerator(); /// <summary> /// 从特定索引处最先,将鸠合中的元素复制到指定的数组。 /// </summary> /// <param name="array">从鸠合中复制的 <paramref name="T"/> 范例元素的目标 <see cref="T:System.Array"/>。</param> <param name="index">复制最先时地点的数组中的从零最先的索引。</param> void ICollection.CopyTo(Array array, int index); /// <summary> /// 向鸠合中增加一个元素。 /// </summary> /// /// <returns> /// 新元素的插进去位置。 /// </returns> /// <param name="value">要增加到鸠合中的对象。</param> int IList.Add(object value); /// <summary> /// 肯定鸠合是不是包括具有特定值的元素。 /// </summary> /// <returns> /// 假如在鸠合中找到元素 <paramref name="value"/>,则为 true;否则为 false。 /// </returns> /// <param name="value">要在鸠合中定位的对象。</param><exception cref="T:System.ArgumentException"><paramref name="value"/> 不是鸠合所含范例的对象。</exception> bool IList.Contains(object value); /// <summary> /// 肯定鸠合中某个元素的从零最先的索引。 /// </summary> /// /// <returns> /// 假如在鸠合中找到,则为 <paramref name="value"/> 的索引;否则为 -1。 /// </returns> /// <param name="value">鸠合中要肯定其索引的元素。</param> int IList.IndexOf(object value); /// <summary> /// 将某个对象插进去到鸠合中的指定索引处。 /// </summary> /// <param name="index">从零最先的索引,将在该位置插进去 <paramref name="value"/>。</param><param name="value">要在鸠合中插进去的对象。</param> <exception cref="T:System.ArgumentOutOfRangeException">指定的 <paramref name="index"/> 小于零或大于鸠合中的项数。</exception> <exception cref="T:System.ArgumentException">设置的 <paramref name="value"/> 为 null,或许不是鸠合的准确泛型范例 <paramref name="T"/>。</exception> void IList.Insert(int index, object value); /// <summary> /// 从鸠合中移除作为元素的指定对象的第一个婚配项。 /// </summary> /// <param name="value">要从鸠合中移除的对象。</param> void IList.Remove(object value); }
(2).KeyedByTypeCollection:供应一个鸠合,该鸠合的项是用作键的范例。
[__DynamicallyInvokable] public class KeyedByTypeCollection<TItem> : KeyedCollection<Type, TItem> { /// <summary> /// 初始化 <see cref="T:System.Collections.Generic.KeyedByTypeCollection`1"/> 类的新实例。 /// </summary> public KeyedByTypeCollection(); /// <summary> /// 依据指定的对象罗列初始化 <see cref="T:System.Collections.Generic.KeyedByTypeCollection`1"/> 类的新实例。 /// </summary> /// <param name="items">泛型范例 <see cref="T:System.Object"/> 的 <see cref="T:System.Collections.Generic.IEnumerable`1"/>,用于初始化鸠合。</param> <exception cref="T:System.ArgumentNullException"><paramref name="items"/> 为 null。</exception> public KeyedByTypeCollection(IEnumerable<TItem> items); /// <summary> /// 返回鸠合中第一个具有指定范例的项。 /// </summary> /// /// <returns> /// 假如为援用范例,则返回范例 <paramref name="T"/> 的对象;假如为值范例,则返回范例 <paramref name="T"/> 的值。 假如鸠合中不包括范例 <paramref name="T"/> 的对象,则返回范例的默认值:假如是援用范例,默认值为 null;假如是值范例,默认值为 0。 /// </returns> /// <typeparam name="T">要在鸠合中查找的项的范例。</typeparam> [TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")] public T Find<T>(); /// <summary> /// 从鸠合中移除具有指定范例的对象。 /// </summary> /// /// <returns> /// 从鸠合中移除的对象。 /// </returns> /// <typeparam name="T">要从鸠合中移除的项的范例。</typeparam> [TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")] public T Remove<T>(); /// <summary> /// 返回 <see cref="T:System.Collections.Generic.KeyedByTypeCollection`1"/> 中包括的范例 <paramref name="T"/> 的对象的鸠合。 /// </summary> /// /// <returns> /// 一个范例 <paramref name="T"/> 的 <see cref="T:System.Collections.ObjectModel.Collection`1"/>,包括来自原始鸠合的范例 <paramref name="T"/> 的对象。 /// </returns> /// <typeparam name="T">要在鸠合中查找的项的范例。</typeparam> [TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")] public Collection<T> FindAll<T>(); /// <summary> /// 从鸠合中移除一切具有指定范例的元素。 /// </summary> /// /// <returns> /// <see cref="T:System.Collections.ObjectModel.Collection`1"/>,包括来自原始鸠合的范例 <paramref name="T"/> 的对象。 /// </returns> /// <typeparam name="T">要从鸠合中移除的项的范例。</typeparam> [TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")] public Collection<T> RemoveAll<T>(); /// <summary> /// 猎取鸠合中包括的某个项的范例。 /// </summary> /// /// <returns> /// 鸠合中指定的 <paramref name="item"/> 的范例。 /// </returns> /// <param name="item">鸠合中要检索其范例的项。</param><exception cref="T:System.ArgumentNullException"><paramref name="item"/> 为 null。</exception> [__DynamicallyInvokable] protected override Type GetKeyForItem(TItem item); /// <summary> /// 在鸠合中的特定位置插进去一个元素。 /// </summary> /// <param name="index">从零最先的索引,应在该位置插进去 <paramref name="item"/>。</param><param name="item">要在鸠合中插进去的对象。</param> <exception cref="T:System.ArgumentNullException"><paramref name="item"/> 为 null。</exception> [__DynamicallyInvokable] protected override void InsertItem(int index, TItem item); /// <summary> /// 运用一个新对象替代指定索引处的项。 /// </summary> /// <param name="index">要替代的 <paramref name="item"/> 的从零最先的索引。</param><param name="item">要增加到鸠合中的对象。</param> <exception cref="T:System.ArgumentNullException"><paramref name="item"/> 为 null。</exception> [__DynamicallyInvokable] protected override void SetItem(int index, TItem item); }
CLR支撑泛型托付,目标是保证任何范例的对象都能以一种范例平安的体式格局传给一个回调要领。泛型托付许可一个孩子范例实例在传给一个回调要领时不实行任何装箱处置惩罚。托付机遇只供应了4个要领:一个组织器,一个Invlke要领,一个BeginInvoke要领和一个EndInvoke要领。假如定义的一个托付范例指定了范例参数,编译器会定义托付类的要领,用指定的范例参数替代要领的参数范例和值范例。
以上就是C#编程基本之泛型要领剖析(上)的内容,更多相关内容请关注ki4网(www.ki4.cn)!