C# 泛型接口应用浅析

开发 后端
C# 泛型接口的概念是什么?C# 泛型接口的使用是如何进行的呢?那么本文就向你详细C# 泛型接口的内容。

C# 泛型接口的实用性:为泛型集合类或表示集合中项的泛型类定义接口通常很有用。对于泛型类,使用泛型接口十分可取,例如使用 IComparable﹤T﹥ 而不使用 IComparable,这样可以避免值类型的装箱和取消装箱操作。.NET Framework 2.0 类库定义了若干新的泛型接口,以用于 System.Collections.Generic 命名空间中新的集合类。将接口指定为类型参数的约束时,只能使用实现此接口的类型。下面的代码示例显示从 GenericList﹤T﹥ 类派生的 SortedList﹤T﹥ 类。SortedList﹤T﹥ 添加了约束 where T : IComparable﹤T﹥。这将使 SortedList﹤T﹥ 中的 BubbleSort 方法能够对列表元素使用泛型 CompareTo 方法。在此示例中,列表元素为简单类,即实现 IComparable﹤Person﹥ 的 Person。

C# 泛型接口代码

  1. //Type parameter T in angle brackets.  
  2. public class GenericList﹤T﹥ :  
  3.  System.Collections.Generic.IEnumerable﹤T﹥  
  4. {  
  5. protected Node head;  
  6. protected Node current = null;  
  7.  
  8. // Nested class is also generic on T  
  9. protected class Node  
  10. {  
  11. public Node next;  
  12. private T data;  //T as private member datatype  
  13.  
  14. public Node(T t)  //T used in non-generic constructor  
  15. {  
  16. next = null;  
  17. data = t;  
  18. }  
  19.  
  20. public Node Next  
  21. {  
  22. get { return next; }  
  23. set { next = value; }  
  24. }  
  25.  
  26. public T Data  //T as return type of property  
  27. {  
  28. get { return data; }  
  29. set { data = value; }  
  30. }  
  31. }  
  32.  
  33. public GenericList()  //constructor  
  34. {  
  35. head = null;  
  36. }  
  37.  
  38. public void AddHead(T t)  //T as method parameter type  
  39. {  
  40. Node n = new Node(t);  
  41. n.Next = head;  
  42. head = n;  
  43. }  
  44.  
  45. // Implementation of the iterator  
  46. public System.Collections.Generic.IEnumerator﹤T﹥ GetEnumerator()  
  47. {  
  48. Node current = head;  
  49. while (current != null)  
  50. {  
  51. yield return current.Data;  
  52. current = current.Next;  
  53. }  
  54. }  
  55.  
  56. // IEnumerable﹤T﹥ inherits from IEnumerable, therefore this class   
  57. // must implement both the generic and non-generic versions of   
  58. // GetEnumerator. In most cases, the non-generic method can   
  59. // simply call the generic method.  
  60. System.Collections.IEnumerator   
  61. System.Collections.IEnumerable.GetEnumerator()  
  62. {  
  63. return GetEnumerator();  
  64. }  
  65. }  
  66.  
  67. public class SortedList﹤T﹥ :  
  68.  GenericList﹤T﹥ where T : System.IComparable﹤T﹥  
  69. {  
  70. // A simple, unoptimized sort algorithm that   
  71. // orders list elements from lowest to highest:  
  72.  
  73. public void BubbleSort()  
  74. {  
  75. if (null == head || null == head.Next)  
  76. {  
  77. return;  
  78. }  
  79. bool swapped;  
  80.  
  81. do 
  82. {  
  83. Node previous = null;  
  84. Node current = head;  
  85. swapped = false;  
  86.  
  87. while (current.next != null)  
  88. {  
  89. //  Because we need to call this method, the SortedList  
  90. //  class is constrained on IEnumerable﹤T﹥  
  91. if (current.Data.CompareTo(current.next.Data) ﹥ 0)  
  92. {  
  93. Node tmp = current.next;  
  94. current.next = current.next.next;  
  95. tmp.next = current;  
  96.  
  97. if (previous == null)  
  98. {  
  99. head = tmp;  
  100. }  
  101. else 
  102. {  
  103. previous.next = tmp;  
  104. }  
  105. previous = tmp;  
  106. swapped = true;  
  107. }  
  108. else 
  109. {  
  110. previous = current;  
  111. current = current.next;  
  112. }  
  113. }  
  114. while (swapped);  
  115. }  
  116. }  
  117.  
  118. // A simple class that implements   
  119. //IComparable﹤T﹥ using itself as the   
  120. // type argument. This is a common  
  121. // design pattern in objects that   
  122. // are stored in generic lists.  
  123. public class Person : System.IComparable﹤Person﹥  
  124. {  
  125. string name;  
  126. int age;  
  127.  
  128. public Person(string s, int i)  
  129. {  
  130. name = s;  
  131. age = i;  
  132. }  
  133.  
  134. // This will cause list elements  
  135. // to be sorted on age values.  
  136. public int CompareTo(Person p)  
  137. {  
  138. return age - p.age;  
  139. }  
  140.  
  141. public override string ToString()  
  142. {  
  143. return name + ":" + age;  
  144. }  
  145.  
  146. // Must implement Equals.  
  147. public bool Equals(Person p)  
  148. {  
  149. return (this.age == p.age);  
  150. }  
  151. }  
  152.  
  153. class Program  
  154. {  
  155. static void Main()  
  156. {  
  157. //Declare and instantiate a new generic SortedList class.  
  158. //Person is the type argument.  
  159. SortedList﹤Person﹥ list = new SortedList﹤Person﹥();  
  160.  
  161. //Create name and age values to initialize Person objects.  
  162. string[] names = new string[]   
  163. {   
  164. "Franscoise",   
  165. "Bill",   
  166. "Li",   
  167. "Sandra",   
  168. "Gunnar",   
  169. "Alok",   
  170. "Hiroyuki",   
  171. "Maria",   
  172. "Alessandro",   
  173. "Raul"   
  174. };  
  175.  
  176. int[] ages = new int[] { 45, 19, 28,  
  177.  23, 18, 9, 108, 72, 30, 35 };  
  178.  
  179. //Populate the list.  
  180. for (int x = 0; x ﹤ 10; x++)  
  181. {  
  182. list.AddHead(new Person(names[x], ages[x]));  
  183. }  
  184.  
  185. //Print out unsorted list.  
  186. foreach (Person p in list)  
  187. {  
  188. System.Console.WriteLine(p.ToString());  
  189. }  
  190. System.Console.WriteLine("Done with unsorted list");  
  191.  
  192. //Sort the list.  
  193. list.BubbleSort();  
  194.  
  195. //Print out sorted list.  
  196. foreach (Person p in list)  
  197. {  
  198. System.Console.WriteLine(p.ToString());  
  199. }  
  200. System.Console.WriteLine("Done with sorted list");  
  201. }  

可将多重接口指定为单个类型上的约束,如下所示:

C# 泛型接口代码

  1. class Stack﹤T﹥ where T : System.IComparable﹤T﹥, IEnumerable﹤T﹥  
  2. {  

一个接口可定义多个类型参数,如下所示:

C# 泛型接口代码

  1. interface IDictionary﹤K, V﹥  
  2. {  

类之间的继承规则同样适用于接口:

C# 泛型接口代码

  1. interface IMonth﹤T﹥ { }  
  2.  
  3. interface IJanuary : IMonth﹤int﹥ { }  //No error  
  4. interface IFebruary﹤T﹥ : IMonth﹤int﹥ { }  //No error  
  5. interface IMarch﹤T﹥: IMonth﹤T﹥ { }//No error  
  6. //interface IApril﹤T﹥  : IMonth﹤T, U﹥ {}  //Error 

如果泛型接口为逆变的,即仅使用其类型参数作为返回值,则此泛型接口可以从非泛型接口继承。在 .NET Framework 类库中,IEnumerable﹤T﹥ 从 IEnumerable 继承,因为 IEnumerable﹤T﹥ 仅在 GetEnumerator 的返回值和当前属性 getter 中使用 T。

具体类可以实现已关闭的构造接口,如下所示:

C# 泛型接口代码

  1. interface IBaseInterface﹤T﹥ { }  
  2.  
  3. class SampleClass : IBaseInterface﹤string﹥ { } 

只要类参数列表提供了接口必需的所有参数,泛型类便可以实现泛型接口或已关闭的构造接口,如下所示:

C# 泛型接口代码

  1. interface IBaseInterface1﹤T﹥ { }  
  2. interface IBaseInterface2﹤T, U﹥ { }  
  3.  
  4. class SampleClass1﹤T﹥ :   
  5. IBaseInterface1﹤T﹥ { }//No error  
  6. class SampleClass2﹤T﹥ :   
  7. IBaseInterface2﹤T, string﹥ { }//No error 

对于泛型类、泛型结构或泛型接口中的方法,控制方法重载的规则相同。

C# 泛型接口的相关内容就向你介绍到这里,希望对你了解和学习C# 泛型接口有所帮助。

【编辑推荐】

  1. C# 强制类型转换与C# 泛型浅析
  2. C# 泛型类概念与实例的理解应用浅析
  3. C# 泛型的优点浅谈
  4. C# 泛型类型参数浅析
  5. C# 类型参数约束分析及应用浅析
责任编辑:仲衡 来源: MSDN
相关推荐

2009-08-24 17:58:19

C# 泛型集合

2009-08-24 17:27:05

C#泛型应用

2009-08-24 16:39:19

C# 泛型应用

2009-08-24 11:35:20

C# 泛型应用

2009-08-24 17:39:21

C# 泛型集合

2009-08-24 18:15:24

C# Dictiona

2009-08-24 14:51:25

C# 泛型泛型类型

2009-08-24 15:50:23

C# 泛型C# 泛型委托

2009-08-24 14:20:13

C# 强制类型转换

2009-08-24 13:31:38

C# 泛型约束

2009-08-24 15:28:19

C# 泛型方法

2009-08-24 10:37:27

C# 泛型

2009-08-24 14:26:42

C# 泛型类

2009-08-24 10:07:57

C#泛型处理

2009-08-07 08:53:52

C# ICloneab

2009-08-24 16:19:42

C# 泛型方法

2009-08-24 16:01:44

C# 泛型

2009-08-24 13:41:23

C# 泛型约束

2009-08-27 13:05:06

C#接口特点C#接口实例

2009-08-31 16:37:20

C#接口定义
点赞
收藏

51CTO技术栈公众号