1 泛型基本概念
泛型基本概念
2 使用泛型类型可以最大限度地重用代码、保护类型的安全以及提高性能。
使用泛型类型可以最大限度地重用代码、保护类型的安全以及提高性能。
3 泛型最常见的用途是创建集合类。
泛型最常见的用途是创建集合类。
4 .NET Framework 类库在 System.Collections.Generic 命名空间中包含几个新的泛型集合类。应尽可能地使用这些类来代替普通的类,如 System.Collections 命名空间中的 ArrayList。
.NET Framework 类库在 System.Collections.Generic 命名空间中包含几个新的泛型集合类。应尽可能地使用这些类来代替普通的类,如 System.Collections 命名空间中的 ArrayList。
5
6 您可以创建自己的泛型接口、泛型类、泛型方法、泛型事件和泛型委托。
您可以创建自己的泛型接口、泛型类、泛型方法、泛型事件和泛型委托。
7
8 可以对泛型类进行约束以访问特定数据类型的方法。
可以对泛型类进行约束以访问特定数据类型的方法。
9
10 关于泛型数据类型中使用的类型的信息可在运行时通过反射获取。
关于泛型数据类型中使用的类型的信息可在运行时通过反射获取。
11
12 public class GenericList<T>     //声明一个泛型类
public class GenericList<T>     //声明一个泛型类
13 {
{
14 void Add(T input) { }
    void Add(T input) { }
15 }
}
16
17 //测试泛型类
//测试泛型类
18 // Declare a list of type int
// Declare a list of type int
19 GenericList<int> list1 = new GenericList<int>();
        GenericList<int> list1 = new GenericList<int>();
20 // Declare a list of type string
  // Declare a list of type string
21 GenericList<string> list2 = new GenericList<string>();
        GenericList<string> list2 = new GenericList<string>();
22 2. ArrayList的缺点-泛型的优点
2. ArrayList的缺点-泛型的优点
23 1) 添加到 ArrayList 中的任何引用或值类型都将隐式地向上强制转换为 Object。如果项是值类型,则必须在将其添加到列表中时进行装箱操作,在检索时进行取消装箱操作。强制转换以及装箱和取消装箱操作都会降低性能;在必须对大型集合进行循环访问的情况下,装箱和取消装箱的影响非常明显。
     1) 添加到 ArrayList 中的任何引用或值类型都将隐式地向上强制转换为 Object。如果项是值类型,则必须在将其添加到列表中时进行装箱操作,在检索时进行取消装箱操作。强制转换以及装箱和取消装箱操作都会降低性能;在必须对大型集合进行循环访问的情况下,装箱和取消装箱的影响非常明显。
24 2)另一个限制是缺少编译时类型检查。因为 ArrayList 将把所有项都强制转换为 Object;换句话说,ArrayList 需要一个 type parameter。这正是泛型所能提供的。
      2)另一个限制是缺少编译时类型检查。因为 ArrayList 将把所有项都强制转换为 Object;换句话说,ArrayList 需要一个 type parameter。这正是泛型所能提供的。
25 3)泛型List比 ArrayList 更安全并且速度更快。
  3)泛型List比 ArrayList 更安全并且速度更快。
26
27 3. 类型参数的约束
3. 类型参数的约束
28 在定义泛型类时,可以对客户端代码能够在实例化类时用于类型参数的类型种类施加限制。约束是使用 where 上下文关键字指定的。
  在定义泛型类时,可以对客户端代码能够在实例化类时用于类型参数的类型种类施加限制。约束是使用 where 上下文关键字指定的。
29 public class GenericList1<T> where T : Employee
public class GenericList1<T> where T : Employee
30 {
{
31
32 //T只能是Employee类
      //T只能是Employee类
33 }
}
34
35 public class GenericList2<T> where T : int
public class GenericList2<T> where T : int
36 {
{
37
38 //T只能是int值类型
      //T只能是int值类型
39
40 }
}
41
42 4.泛型类
4.泛型类
43 泛型类最常用于集合,如链接列表、哈希表、堆栈、队列、树等,其中,像从集合中添加和移除项这样的操作都以大体上相同的方式执行,与所存储数据的类型无关。
  泛型类最常用于集合,如链接列表、哈希表、堆栈、队列、树等,其中,像从集合中添加和移除项这样的操作都以大体上相同的方式执行,与所存储数据的类型无关。
44 对于大多数需要集合类的方案,推荐的方法是使用 .NET Framework 2.0 类库中所提供的类,如List, Queue,Stack,Dictionary。
  对于大多数需要集合类的方案,推荐的方法是使用 .NET Framework 2.0 类库中所提供的类,如List, Queue,Stack,Dictionary。
45 5. C++ 模板和 C# 泛型之间的区别
5. C++ 模板和 C# 泛型之间的区别
46 C# 泛型和 C++ 模板都是用于提供参数化类型支持的语言功能。然而,这两者之间存在许多差异。
  C# 泛型和 C++ 模板都是用于提供参数化类型支持的语言功能。然而,这两者之间存在许多差异。
47 C# 泛型未提供与 C++ 模板相同程度的灵活性。例如,尽管在 C# 泛型类中可以调用用户定义的运算符,但不能调用算术运算符。
C# 泛型未提供与 C++ 模板相同程度的灵活性。例如,尽管在 C# 泛型类中可以调用用户定义的运算符,但不能调用算术运算符。
48 C# 不允许非类型模板参数,如 template C<int i> {}。
C# 不允许非类型模板参数,如 template C<int i> {}。
49 C# 不支持显式专用化,即特定类型的模板的自定义实现。
C# 不支持显式专用化,即特定类型的模板的自定义实现。
50 C# 不支持部分专用化:类型参数子集的自定义实现。
C# 不支持部分专用化:类型参数子集的自定义实现。
51 C# 不允许将类型参数用作泛型类型的基类
C# 不允许将类型参数用作泛型类型的基类
52 C# 不允许类型参数具有默认类型
C# 不允许类型参数具有默认类型
53 在 C# 中,尽管构造类型可用作泛型,但泛型类型参数自身不能是泛型。C++ 确实允许模板参数。
在 C# 中,尽管构造类型可用作泛型,但泛型类型参数自身不能是泛型。C++ 确实允许模板参数。
54 C++ 允许那些可能并非对模板中的所有类型参数都有效的代码,然后将检查该代码中是否有用作类型参数的特定类型。C# 要求相应地编写类中的代码,使之能够使用任何满足约束的类型。例如,可以在 C++ 中编写对类型参数的对象使用算术运算符 + 和 - 的函数,这会在使用不支持这些运算符的类型来实例化模板时产生错误。C# 不允许这样;唯一允许的语言构造是那些可从约束推导出来的构造。
C++ 允许那些可能并非对模板中的所有类型参数都有效的代码,然后将检查该代码中是否有用作类型参数的特定类型。C# 要求相应地编写类中的代码,使之能够使用任何满足约束的类型。例如,可以在 C++ 中编写对类型参数的对象使用算术运算符 + 和 - 的函数,这会在使用不支持这些运算符的类型来实例化模板时产生错误。C# 不允许这样;唯一允许的语言构造是那些可从约束推导出来的构造。
55 举例如下:
举例如下:
56
57 //使用System.Collections.Generic命名空间中的泛型类List
           //使用System.Collections.Generic命名空间中的泛型类List
58 List<int>  lInt = new List<int>();
            List<int>  lInt = new List<int>();
59 lInt.Add(1);
            lInt.Add(1);
60 lInt.Add(3);
            lInt.Add(3);
61
62 List<string>  lString = new List<string>();
            List<string>  lString = new List<string>();
63 lString.Add("abc");
            lString.Add("abc");
64 lString.Add("789");
            lString.Add("789");
65
66 this.listBox_testIterator.Items.Clear();
            this.listBox_testIterator.Items.Clear();
67 foreach (int i in lInt)
            foreach (int i in lInt)
68 this.listBox_testIterator.Items.Add(i.ToString());
                this.listBox_testIterator.Items.Add(i.ToString());
69
70 this.listBox_testIterator.Items.Add("");
            this.listBox_testIterator.Items.Add("");
71 foreach (string s in lString)
            foreach (string s in lString)
72 this.listBox_testIterator.Items.Add(s);
                this.listBox_testIterator.Items.Add(s);
73
 泛型基本概念
泛型基本概念2
 使用泛型类型可以最大限度地重用代码、保护类型的安全以及提高性能。
使用泛型类型可以最大限度地重用代码、保护类型的安全以及提高性能。3
 泛型最常见的用途是创建集合类。
泛型最常见的用途是创建集合类。4
 .NET Framework 类库在 System.Collections.Generic 命名空间中包含几个新的泛型集合类。应尽可能地使用这些类来代替普通的类,如 System.Collections 命名空间中的 ArrayList。
.NET Framework 类库在 System.Collections.Generic 命名空间中包含几个新的泛型集合类。应尽可能地使用这些类来代替普通的类,如 System.Collections 命名空间中的 ArrayList。5

6
 您可以创建自己的泛型接口、泛型类、泛型方法、泛型事件和泛型委托。
您可以创建自己的泛型接口、泛型类、泛型方法、泛型事件和泛型委托。7

8
 可以对泛型类进行约束以访问特定数据类型的方法。
可以对泛型类进行约束以访问特定数据类型的方法。9

10
 关于泛型数据类型中使用的类型的信息可在运行时通过反射获取。
关于泛型数据类型中使用的类型的信息可在运行时通过反射获取。11

12
 public class GenericList<T>     //声明一个泛型类
public class GenericList<T>     //声明一个泛型类13
 {
{14
 void Add(T input) { }
    void Add(T input) { }15
 }
}16

17
 //测试泛型类
//测试泛型类18
 // Declare a list of type int
// Declare a list of type int19
 GenericList<int> list1 = new GenericList<int>();
        GenericList<int> list1 = new GenericList<int>();20
 // Declare a list of type string
  // Declare a list of type string21
 GenericList<string> list2 = new GenericList<string>();
        GenericList<string> list2 = new GenericList<string>();22
 2. ArrayList的缺点-泛型的优点
2. ArrayList的缺点-泛型的优点23
 1) 添加到 ArrayList 中的任何引用或值类型都将隐式地向上强制转换为 Object。如果项是值类型,则必须在将其添加到列表中时进行装箱操作,在检索时进行取消装箱操作。强制转换以及装箱和取消装箱操作都会降低性能;在必须对大型集合进行循环访问的情况下,装箱和取消装箱的影响非常明显。
     1) 添加到 ArrayList 中的任何引用或值类型都将隐式地向上强制转换为 Object。如果项是值类型,则必须在将其添加到列表中时进行装箱操作,在检索时进行取消装箱操作。强制转换以及装箱和取消装箱操作都会降低性能;在必须对大型集合进行循环访问的情况下,装箱和取消装箱的影响非常明显。24
 2)另一个限制是缺少编译时类型检查。因为 ArrayList 将把所有项都强制转换为 Object;换句话说,ArrayList 需要一个 type parameter。这正是泛型所能提供的。
      2)另一个限制是缺少编译时类型检查。因为 ArrayList 将把所有项都强制转换为 Object;换句话说,ArrayList 需要一个 type parameter。这正是泛型所能提供的。25
 3)泛型List比 ArrayList 更安全并且速度更快。
  3)泛型List比 ArrayList 更安全并且速度更快。26

27
 3. 类型参数的约束
3. 类型参数的约束28
 在定义泛型类时,可以对客户端代码能够在实例化类时用于类型参数的类型种类施加限制。约束是使用 where 上下文关键字指定的。
  在定义泛型类时,可以对客户端代码能够在实例化类时用于类型参数的类型种类施加限制。约束是使用 where 上下文关键字指定的。29
 public class GenericList1<T> where T : Employee
public class GenericList1<T> where T : Employee30
 {
{31

32
 //T只能是Employee类
      //T只能是Employee类33
 }
}34

35
 public class GenericList2<T> where T : int
public class GenericList2<T> where T : int36
 {
{37

38
 //T只能是int值类型
      //T只能是int值类型39

40
 }
}41

42
 4.泛型类
4.泛型类43
 泛型类最常用于集合,如链接列表、哈希表、堆栈、队列、树等,其中,像从集合中添加和移除项这样的操作都以大体上相同的方式执行,与所存储数据的类型无关。
  泛型类最常用于集合,如链接列表、哈希表、堆栈、队列、树等,其中,像从集合中添加和移除项这样的操作都以大体上相同的方式执行,与所存储数据的类型无关。44
 对于大多数需要集合类的方案,推荐的方法是使用 .NET Framework 2.0 类库中所提供的类,如List, Queue,Stack,Dictionary。
  对于大多数需要集合类的方案,推荐的方法是使用 .NET Framework 2.0 类库中所提供的类,如List, Queue,Stack,Dictionary。45
 5. C++ 模板和 C# 泛型之间的区别
5. C++ 模板和 C# 泛型之间的区别46
 C# 泛型和 C++ 模板都是用于提供参数化类型支持的语言功能。然而,这两者之间存在许多差异。
  C# 泛型和 C++ 模板都是用于提供参数化类型支持的语言功能。然而,这两者之间存在许多差异。47
 C# 泛型未提供与 C++ 模板相同程度的灵活性。例如,尽管在 C# 泛型类中可以调用用户定义的运算符,但不能调用算术运算符。
C# 泛型未提供与 C++ 模板相同程度的灵活性。例如,尽管在 C# 泛型类中可以调用用户定义的运算符,但不能调用算术运算符。48
 C# 不允许非类型模板参数,如 template C<int i> {}。
C# 不允许非类型模板参数,如 template C<int i> {}。49
 C# 不支持显式专用化,即特定类型的模板的自定义实现。
C# 不支持显式专用化,即特定类型的模板的自定义实现。50
 C# 不支持部分专用化:类型参数子集的自定义实现。
C# 不支持部分专用化:类型参数子集的自定义实现。51
 C# 不允许将类型参数用作泛型类型的基类
C# 不允许将类型参数用作泛型类型的基类52
 C# 不允许类型参数具有默认类型
C# 不允许类型参数具有默认类型53
 在 C# 中,尽管构造类型可用作泛型,但泛型类型参数自身不能是泛型。C++ 确实允许模板参数。
在 C# 中,尽管构造类型可用作泛型,但泛型类型参数自身不能是泛型。C++ 确实允许模板参数。54
 C++ 允许那些可能并非对模板中的所有类型参数都有效的代码,然后将检查该代码中是否有用作类型参数的特定类型。C# 要求相应地编写类中的代码,使之能够使用任何满足约束的类型。例如,可以在 C++ 中编写对类型参数的对象使用算术运算符 + 和 - 的函数,这会在使用不支持这些运算符的类型来实例化模板时产生错误。C# 不允许这样;唯一允许的语言构造是那些可从约束推导出来的构造。
C++ 允许那些可能并非对模板中的所有类型参数都有效的代码,然后将检查该代码中是否有用作类型参数的特定类型。C# 要求相应地编写类中的代码,使之能够使用任何满足约束的类型。例如,可以在 C++ 中编写对类型参数的对象使用算术运算符 + 和 - 的函数,这会在使用不支持这些运算符的类型来实例化模板时产生错误。C# 不允许这样;唯一允许的语言构造是那些可从约束推导出来的构造。55
 举例如下:
举例如下:56

57
 //使用System.Collections.Generic命名空间中的泛型类List
           //使用System.Collections.Generic命名空间中的泛型类List58
 List<int>  lInt = new List<int>();
            List<int>  lInt = new List<int>();59
 lInt.Add(1);
            lInt.Add(1);60
 lInt.Add(3);
            lInt.Add(3);61

62
 List<string>  lString = new List<string>();
            List<string>  lString = new List<string>();63
 lString.Add("abc");
            lString.Add("abc");64
 lString.Add("789");
            lString.Add("789");65

66
 this.listBox_testIterator.Items.Clear();
            this.listBox_testIterator.Items.Clear();67
 foreach (int i in lInt)
            foreach (int i in lInt)68
 this.listBox_testIterator.Items.Add(i.ToString());
                this.listBox_testIterator.Items.Add(i.ToString());69

70
 this.listBox_testIterator.Items.Add("");
            this.listBox_testIterator.Items.Add("");71
 foreach (string s in lString)
            foreach (string s in lString)72
 this.listBox_testIterator.Items.Add(s);
                this.listBox_testIterator.Items.Add(s);73

 
                    
                     
                    
                 
                    
                 
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号