Understanding Generic Type, 理解泛型
什么是泛型
所谓泛型,就是指类型可以为任意. 最常用的泛型当然是用于创建集合了.
1: List<int> list = new List<int>();
2: list.Add(1);
为什么要用泛型?
这个问题可以分为几个分支, 我们一个一个来思考
-
泛型跟传统的集合类比较有什么优势
-
a. 效率好,
- 因为集合类(以ArrayList为例)对于所有对象的操作采用object作为对象
1: ArrayList arrayList = new ArrayList();
2: arrayList.Add(12);
3: arrayList.Add("hello arraylist");
- 如上面的代码所示,他们在操作时既可以使用值类型,也可以是String, 因为他们都会向上转型为Object, 这样存在一定的性能损失,但是这是不是说泛型做集合性能就比ArrayList好呢? 请看这里
-
b. 类型确定
-
1: int result = 0;
2: foreach (int i in list)
3: {
4: result +=i;
5: }
- 我们可以对泛型进行操作,对于ArrayList,我们则不那么方便了, 而且这样对于ArrayList这样书写也不会提示错误,然而在运行时则会出错。为程序的稳健性带来了隐患
1: foreach (int i in array)
2: {
3: result += i;
4: }
-
c. 代码重用
- 过去,我们如果要定义一个强类型的集合,最常见的办法是继承自ICollection
1: public class StrongTypeCollection : ICollection
2: {
3: public void Add() { // TODO:: Implement this }
4:
5: // Other Methods To Override
6: }
- 而现在我们使用IList<int> myCollection = new List<int>(int capbility); 就好再例如,我们可以使用
1: public class MyClass : IComparable<int>, IComparable<double>
2: {
3: }
泛型的用途
1. 集合类定义, 2. 泛型类型, 3. 泛型方法 4. 泛型代理
但之前,让我们先来看看泛型的使用限定,即泛型的约束。泛型的约束分为5种
值类型约束 | class MyClass<T> where T : struct |
引用类型约束 | class MyClass<T> where T : class |
接口类型约束 | class MyClass<T> where T : IComparable<int> |
基类约束(只有继承自BaseClass的子类才能成为改泛型的类型) | class MyClass<T> where T : BaseClass |
无参构造函数约束 | class MyClass<T> where T : new() 当有多种类型的时候,new()只能放在最后 class MyClass<T> where T : class, new() |
上面的例子都是一个类型的泛型,在.Net中可以定义多个类型
1: // 定义多个类型
2: public class MyClass<U, T>
3: // 定义多个类型并确定类型的约束
4: public class MyClass<U, T>
5: where U : struct
6: where T : class, new()
7: // 确定类型之间的关系
8: public class MyClass<U, T> where U : T
最后一行代码,所代表的关系是U必须继承自T, 见上面表格中的基类约束
关于上面的三种用法,我们最后分别给出一个例子
集合类定义
1: IList<MyStruct> list = new List<MyStruct>();
泛型类型
1: public class MyItem : IComparable<MyItem>
2: {
3: public int CompareTo(MyItem item)
4: {
5: return this.Value.CompareTo( item.Value);
6: }
7:
8: public int Value {get;set;}
9: }
泛型方法
1: using System;
2: using System.Collections.Generic;
3: public class MyClass
4: {
5: public static void Main()
6: {
7: MyGeneric my = new MyGeneric();
8: my.Run<double>(3);
9:
10: // The Type Must be the concerate generic type
11: // my.Run<double>(new Random());
12:
13: Console.Read();
14: }
15: }
16: public class MyGeneric
17: {
18: public void Run<T>(T t) where T : struct
19: {
20: Console.WriteLine("The Value Here Is {0}", t);
21: }
22: }
泛型代理
1: public delegate void MyAction<T>(T t); // Define the Type
2: public event MyAction<string> OnActing; // Define The Event Instance
3:
4: public void Output(string message)
5: {
6: Console.WriteLine(message);
7: }
8:
9: public void TestGenericDelegate()
10: {
11: OnActing += Output; // Register A Event
12: OnActing("Hello, Generic Methods"); // Call The Event
13: }
还有几个特性为.Net泛型的小点心也不错哦
1. default(T) : 给泛型确定类型默认值, 引用类型为NULL,值类型为默认值,如int为0
2. 比较大小
1: public class MyClass<T>
2: {
3: public T Value {get;set;}
4: public int CompareTo(T t)
5: {
6: return this.Value - t,Value; // Wrong
7: }
8: }
9:
10: public class MyClass<T> where T : IComapreable<T>
11: {
12: public T Value {get;set;}
13: public int CompareTo(T t)
14: {
15: return this.Value.CompareTo(t,Value); // Correct
16: }
17: }
3. 反射中对于泛型的特殊处理,反射中对于泛型采用特殊处理,点击这里查看
4. 泛型类之间不共享静态成员,查看详细: Generic Types Don't Share Static Members
参考:
http://msdn.microsoft.com/en-us/library/512aeb7t.aspx
Generic Types Don't Share Static Members
本博客内所有文章属于创作共享,您可以自由转载,摘抄,修改成您自己的版本,然而,如果您要将本文作为商业之用,请联系作者,谢谢合作。