---------------------- Windows Phone 7手机开发、.Net培训、期待与您交流! ---------------------- ----------------------
泛型:在定义的时候不指定具体的类型结构,可以推迟到后面的声明或实例化时指定。
原因:避免在运行时强制转换或装箱拆箱操作的成本、风险。
名称空间:System.Collection.Generic
先了解下装箱和拆箱的概念:
装箱:把值类型转换为Object类型。
拆箱:取消装箱,从对象中提取值类型。
int i = 123;
object o = i; //装箱:值类型到object类型
int j = (int)o; //拆箱:object到值类型
装箱是隐式的,拆箱是显式的。装箱与拆箱过程需要大量的计算。
对值类型装箱会在堆中分配一个对象实例。
堆(Heap):从高地址开始分配,程序员分配,比如C#中实例化 new
栈(Stack):从低地址开始分派,编译器自动分配,存放函数的参数值,局部变量等。
泛型适用范围:
泛型可以创建自己的泛型类、泛型方法、泛型委托、泛型借口、泛型事件等。最常见的用途是创建集合、类。
泛型的特点:
1.若实例化的参数类型相同,编译器会重复使用该类型,防止代码膨胀。
2.拥有丰富的元数据,可以应用于强大的反射技术。
泛型约束: where关键字
在定义泛型类时,可以在实例化类时对类型参数的类型种类施加限制。 如果客户端代码尝试使用某个约束所不允许的类型来实例化类,则会产生编译时错误。 这些限制称为约束。 约束是使用 where 上下文关键字指定的。 下表列出了六种类型的约束:
约束 |
说明 |
---|---|
T:结构 |
类型参数必须是值类型。 可以指定除 Nullable 以外的任何值类型。 |
T:类 |
类型参数必须是引用类型;这一点也适用于任何类、接口、委托或数组类型。 |
T:new() |
类型参数必须具有无参数的公共构造函数。 当与其他约束一起使用时,new() 约束必须最后指定。 |
T:<基类名> |
类型参数必须是指定的基类或派生自指定的基类。 |
T:<接口名称> |
类型参数必须是指定的接口或实现指定的接口。 可以指定多个接口约束。 约束接口也可以是泛型的。 |
T:U |
为 T 提供的类型参数必须是为 U 提供的参数或派生自为 U 提供的参数。 |
例子:
public class BaseClass { } //声明父类表示T只能继承于BaseClasee,其实改成T where int 更好理解,
public class PersonClass : BaseClass { } //子类,继承父类BaseClass
public class OtherClass<T> where T : BaseClass { }//泛型类。类型参数T只能继承于BaseClass
OtherClass<PersonClass> other=new OtherClass<PersonClass>(); //这个声明能正常使用
在里面定义的变量类型T只能来自 int类型。
泛型关键字:default及运算符 ==、!=
在预先未知以下情况时,如何将默认值分配给参数化类型T:
1.T是引用类型还是值类型。
2.若T为值类型,则它是数值还是结构。
因此在不确定的情况下,避免使用运算符== 、 !=
示例:
public class OtherClass<T> where T : BaseClass {
T test=default (T);
public void Msg()
{
if (test == null)
{
MessageBox.Show("test的值为null");
}
else
{
MessageBox.Show("test的值不为null");
}
}
}
List<T> 对应的是非泛型集合ArrayList。
它本身就是个类,所以在声明使用时,T要变成具体的数据结构。
//非泛型,加入不同的值,会造成装箱拆箱的开销
ArrayList alst = new ArrayList();
alst.Add(123);
alst.Add("字符串");
//泛型List<T>
List<int> lst = new List<int>();
lst.Add(1);
//lst.Add("2"); //报错,一方面限制了类型,一方面避免了装箱拆箱的开销
Dictionary<K,V>:表示键/值对集合。其中键的值K必须是唯一的。
Dictionary<K,V>.KeyColletion:表示Dictionary<K,V>的键集合。
Dictionary<K,V>.ValueColletion:表示Dictionary<K,V>的值集合。
泛型类:
过程:从一个现有的具体类开始,逐一将每个类型更改为类型参数,直至达到通用化和可用性的最佳平衡。
泛型类可以从具体的,封闭式构造或开放式构造基类继承:
public class BaseClass { };
public class BaseClassGeneric<T> { };
public class PersonClass<T> : BaseClass { } //具体的
public class PersonClosed<T> : BaseClassGeneric<int> { }; //封闭构造
public class PersonOpen<T> : BaseClassGeneric<T> { };//开放构造
泛型方法:
在泛型类中定义
class GenericList<T>
{
public void ShowMsg<Y>(T s)
{
T i = s;
MessageBox.Show("你好"+s);
}
}
private void btnFxMethod_Click(object sender, EventArgs e)
{
GenericList<string> ls = new GenericList<string>();
ls.ShowMsg("游客");
}
}
泛型委托:
可以定义自己的类型参数。引用泛型委托的代码可以指定类型参数以创建已关闭的构造类型,就像实例化泛型类或调用泛型方式一样。
示例:
public delegate void Del<T>(T item); //定义个泛型委托
public static void Notify(int i); //定义个方法
Del<int> m1 = new Del<int>(Notify); //声明委托变量m1
Del<int> m2 = Notify; //也可以这么声明
基础类库中的泛型:
System.Collections.Generic,其中包含了一些已经可以使用的泛型容器类和相关的接口。和早期版本的.NET框架提供的非泛型容器类相比,这些类和接口更高效且是类型安全的。在设计、实现自定义的容器类之前,请你考虑是否使用或继承所列出类中的一个。
泛型类或接口 | 描述 | 对应的非泛型类型 |
Collection<T>ICollection<T> | 为泛型容器提供基类 | CollectionBaseICollection |
Comparer<T>IComparer<T>IComparable<T> | 比较两个相同泛型类型的对象是否相等、可排序。 | ComparerIComparerIComparable |
Dictionary<K, V>IDictionary<K,V> | 表示用键组织的键/值对集合。 | HashtableIDictionary |
Dictionary<K, V>.KeyCollection | 表示Dictionary<K, V>中键的集合。 | None. |
Dictionary<K, V>.ValueCollection | 表示Dictionary<K, V>中值的集合。 | None. |
IEnumerable<T>IEnumerator<T> | 表示可以使用foreach 迭代的集合。 | IEnumerableIEnumerator |
KeyedCollection<T, U> | 表示有键值的集合。 | KeyedCollection |
LinkedList<T> | 表示双向链表。 | None. |
LinkedListNode<T> | 表示LinkedList<T>中的节点。 | None. |
List<T>IList<T> | 使用大小可按需动态增加的数组实现 IList 接口 | ArrayListIList |
Queue<T> | 表示对象的先进先出集合。 | Queue |
ReadOnlyCollection<T> | 为泛型只读容器提供基类。 | ReadOnlyCollectionBase |
SortedDictionary<K, V> | 表示键/值对的集合,这些键和值按键排序并可按照键访问,实现IComparer<T>接口。 | SortedList |
Stack<T> | 表示对象的简单的后进先出集合。 | Stack |
---------------------- Windows Phone 7手机开发、.Net培训、期待与您交流! ---------------------- ----------------------