当前位置: 首页 > 文档资料 > C# 中文指南 >

C# 高级 - 泛型

优质
小牛编辑
125浏览
2023-12-01

泛型允许推迟类或方法中编程元素的数据类型规范的编写,直到实际在程序中使用它的时候再编写。换句话说,泛型允许编写一个可以与任何数据类型协作的类或方法。

你可以通过数据类型的替代参数来编写类或方法的规范。当编译器遇到类的构造函数或方法的函数调用时,它会生成代码来处理指定的数据类型。下面这个简单的示例将有助于理解这个概念:

  1. using System;
  2. using System.Collections.Generic;
  3. namespace GenericApplication
  4. {
  5. public class MyGenericArray<T>
  6. {
  7. private T[] array;
  8. public MyGenericArray(int size)
  9. {
  10. array = new T[size + 1];
  11. }
  12. public T getItem(int index)
  13. {
  14. return array[index];
  15. }
  16. public void setItem(int index, T value)
  17. {
  18. array[index] = value;
  19. }
  20. }
  21. class Tester
  22. {
  23. static void Main(string[] args)
  24. {
  25. // 声明一个整型数组
  26. MyGenericArray<int> intArray = new MyGenericArray<int>(5);
  27. // 设置值
  28. for (int c = 0; c < 5; c++)
  29. {
  30. intArray.setItem(c, c*5);
  31. }
  32. // 获取值
  33. for (int c = 0; c < 5; c++)
  34. {
  35. Console.Write(intArray.getItem(c) + " ");
  36. }
  37. Console.WriteLine();
  38. // 声明一个字符数组
  39. MyGenericArray<char> charArray = new MyGenericArray<char>(5);
  40. // 设置值
  41. for (int c = 0; c < 5; c++)
  42. {
  43. charArray.setItem(c, (char)(c+97));
  44. }
  45. // 获取值
  46. for (int c = 0; c< 5; c++)
  47. {
  48. Console.Write(charArray.getItem(c) + " ");
  49. }
  50. Console.WriteLine();
  51. Console.ReadKey();
  52. }
  53. }
  54. }

编译执行上述代码,得到如下结果:

  1. 0 5 10 15 20
  2. a b c d e

泛型的特性

泛型是一种可以增强程序功能的技术,表现在如下几个方面:

  • 它有助于最大限度地进行重用代码、确保类型的安全以及提高性能。
  • 你可以创建泛型集合类。.NET 框架类库在 System.Collections.Generic 命名空间中包含了一些新的泛型集合类,你可以使用这些泛型集合类来替代 System.Collections 中的集合类。
  • 你可以创建自己的泛型接口、泛型类、泛型方法、泛型事件和泛型委托。
  • 你可以对泛型类进行约束,使其只访问具有特定数据类型的方法。
  • 在运行时,通过使用反射方法可以获取泛型数据类型中所使用的类型信息。

泛型方法

在之前的例子中,我们使用过一个泛型类,我们还可以通过类型参数来声明泛型方法。下述示例很好地展示了这个概念:

  1. using System;
  2. using System.Collections.Generic;
  3. namespace GenericMethodAppl
  4. {
  5. class Program
  6. {
  7. static void Swap<T>(ref T lhs, ref T rhs)
  8. {
  9. T temp;
  10. temp = lhs;
  11. lhs = rhs;
  12. rhs = temp;
  13. }
  14. static void Main(string[] args)
  15. {
  16. int a, b;
  17. char c, d;
  18. a = 10;
  19. b = 20;
  20. c = 'I';
  21. d = 'V';
  22. // 显示交换之前的值
  23. Console.WriteLine("Int values before calling swap:");
  24. Console.WriteLine("a = {0}, b = {1}", a, b);
  25. Console.WriteLine("Char values before calling swap:");
  26. Console.WriteLine("c = {0}, d = {1}", c, d);
  27. // 调用 swap 进行交换
  28. Swap<int>(ref a, ref b);
  29. Swap<char>(ref c, ref d);
  30. // 显示交换之后的值
  31. Console.WriteLine("Int values after calling swap:");
  32. Console.WriteLine("a = {0}, b = {1}", a, b);
  33. Console.WriteLine("Char values after calling swap:");
  34. Console.WriteLine("c = {0}, d = {1}", c, d);
  35. Console.ReadKey();
  36. }
  37. }
  38. }

编译执行上述代码,得到如下结果:

  1. Int values before calling swap:
  2. a = 10, b = 20
  3. Char values before calling swap:
  4. c = I, d = V
  5. Int values after calling swap:
  6. a = 20, b = 10
  7. Char values after calling swap:
  8. c = V, d = I

泛型委托

你可以通过类型参数来定义一个泛型委托,如:

  1. delegate T NumberChanger<T>(T n);

泛型委托示例:

  1. using System;
  2. using System.Collections.Generic;
  3. delegate T NumberChanger<T>(T n);
  4. namespace GenericDelegateAppl
  5. {
  6. class TestDelegate
  7. {
  8. static int num = 10;
  9. public static int AddNum(int p)
  10. {
  11. num += p;
  12. return num;
  13. }
  14. public static int MultNum(int q)
  15. {
  16. num *= q;
  17. return num;
  18. }
  19. public static int getNum()
  20. {
  21. return num;
  22. }
  23. static void Main(string[] args)
  24. {
  25. // 创建委托实例
  26. NumberChanger<int> nc1 = new NumberChanger<int>(AddNum);
  27. NumberChanger<int> nc2 = new NumberChanger<int>(MultNum);
  28. // 使用委托对象调用方法
  29. nc1(25);
  30. Console.WriteLine("Value of Num: {0}", getNum());
  31. nc2(5);
  32. Console.WriteLine("Value of Num: {0}", getNum());
  33. Console.ReadKey();
  34. }
  35. }
  36. }

编译执行以上代码,得到如下结果:

  1. Value of Num: 35
  2. Value of Num: 175