泛型


泛型 
一、什么是泛型? 
通过泛型可以定义类型安全类,而不会损害类型安全、性能或工作效率 

二、实例化泛型 
1、可以使用任何类型来声明和实例化 
2、申明和实例话都必须用一个特定的类型来代替一般类型T 
3、例子: 
//原来写法 
Public   class   Stack 

object[]   m_Items; 
public   void   Push(object   item) 
{...} 
public   object   Pop() 
{...} 

Stack   stack   =   new   Stack(); 
stack.Push(1); 
int number = (int)stack.Pop(); 

//有了泛型后 
Public   class   Stack <T> 

T[]   m_Items; 
public   void   Push(T   item) 
{...} 
public   T   Pop() 
{...} 

Stack <int>   stack   =   new   Stack <int> (); 
stack.Push(1); 
int   number   =   (int)stack.Pop(); 

三:泛型的好处 
1、一次性的开发、测试和部署代码,通过任何类型来重用它 
2、编译器支持和类型安全 
3、不会强行对值类型进行装箱和取消装箱,或者对引用类型进行向下强制类型转换,所以性能得到显著提高。 
注:值类型大概可以提高200%,引用类型大概为100% 

四:多个泛型 
1、单个类型可以定义多个泛型 

五:泛型别名 
1、在文件头部使用using   为特定类型取别名,别名作用范围是整个文件 
2、例子 
using   List   =   LinkedList <int,string> ; 
class   ListClient 

static   void   Main(string[]   args) 

List   list   =   new   List(); 
list.AddHead(123, "AAA "); 



五:泛型约束 
(1)、派生约束 
如: 
public   class   LinkedList <K,T>   where   K:IComparable 

T   Find(K   key) 

if   (str.Key.CompareTo(key)   ==   0)//只有实现这个接口才可比较 



注意: 
1、所有的派生约束必须放在类的实际派生列表之后 
如:public   class   LinkedList <K,T> :IEnumerable <T>   where   K:IComparable <K> 
        {...} 
2、一个泛型参数上可以约束多个接口(用逗号分隔) 
public   class   LinkedList <K,T>   where   K:IComparable <K> ,IConvertible 
3、在一个约束中最多只能使用一个基类 
4、约束的基类不能是密封类或静态类 
5、不能将System.Delegate或System.Array约束为基类 
6、可以同时约束一个基类以及一个或多个接口,但是该基类必须首先出现在派生约束列表中。 
7、C#允许你将另一个泛型参数指定为约束 
public   class   MyClass <T,U>   where   T:U 
{...} 
8、可以自己定义基类或接口进行泛型约束 
9、自定义的接口或基类必须与泛型具有一致的可见性 

(2)、构造函数约束 
如: 
class   Node   <K,T>   where   T:new() 


注意: 
1、可以将构造函数的约束和派生约束结合起来,前提是构造函数的约束出现在约束列表中的最后 

(3)、引用/值类型约束 
1、可以使用struct约束将泛型参数约束为值类型(如int、bool、enum),或任何自定义结构 
2、同样可以使用class约束将泛型参数约束为引用类型 
3、不能将引用/值类型约束与基类约束一起使用,因为基类约束涉及到类 
4、不能使用结构和默认构造函数约束,因为默认构造函数约束也涉及到类 
5、虽然您可以使用类和默认构造函数约束,但是这样做没有任何价值 
6、可以将引用/值类型约束与接口约束组合起来,前提是引用/值类型约束出现在约束列表的开头 

六:泛型和强制类型转换 
1、C#编译器只允许将泛型参数隐式转换到Object或约束指定的类型 
如: 
interface   IS{...} 
class   BaseClass{...} 
class   MyClass <T>   where   T:BaseClass,IS 

void   SomeMethod(T   t) 

IS   obj1   =   t; 
BaseClass   obj2   =   t; 
object   obj3   =   t; 


2、编译器允许你将泛型参数显示强制转换到其他任何借口,但不能将其转换到类 
interface   IS{...} 
class   SomeClass{...} 
class   MyClass   <T>   //没有约束 

void   SomeMethod(T   t) 

IS   obj1   =   (IS)t;   //可以 
SomeClass   obj2   =   (SomeClass)t   //不可以 


3、可以使用临时的Object变量,将泛型参数强制转换到其他任何类型 
class   SomeClass{...} 
class   MyClass   <T>   

void   SomeMethod(T   t) 

object   temp   =   t; 
SomeClass   obj   =   (SomeClass)temp;//可以 


注意:这里只是告诉你这样写是可以的,但是要不要这样写?不要这样写,因为如果t确实没有继承SomeClass编译没错但是运行就会出错 
4、解决上面强制转换问题,可以使用is和as运算符进行判断 
public   class   MyClass <T> 

public   void   SomeMethod <T   t> 

if   (t   is   int   ){...} 
if   (t   is   LinkedList <int,string> ){...} 
//如果泛型参数的类型是所查询的类型,则is运算符返回true 
string   str   =   t   as   string; 
//如果这写类型兼容,则as将执行强制类型转换,否则将返回null 
if   (str   !=   null){...} 
LinkedList <int,string>   list   =   t   as   LinkedList <int,string> ; 
if   (list   !=   null){...} 



七:继承和泛型 
1、在从泛型基类派生,可以提供类型实参,而不是基类泛型参数 
public   class   BaseClass <T> {...} 
public   class   SubClass:BaseClass <int> 
2、如果子类是泛型,而非具体的类型实参,则可以使用子类泛型参数作为泛型基类的指定类型 
public   class   BaseClass <TT> {...} 
public   class   SubClass <T> :BaseClass <T> {...} 
3、在使用子类泛型参数时,必须在子类级别重复在基类级别规定的任何约束 
4、基类可以定义其签名使用泛型参数的虚礼方法,在重写它们时,子类必须在方法签名中提供相应的类型。 
如: 
public   class   BaseClass <T> 

public   virtual   T   SomeMethod() 
{...} 

public   class   SubClass:BaseClass <int> 

public   override   int   SomeMethod() 
{...} 

5、如果该子类是泛型,则它还可以在重写时使用它自己的泛型参数 
public   class   SubClass <T> :BaseClass <T> 

public   override   T   SomeMethod() 
{...} 

6、你可以定义泛型接口、泛型抽象类,甚至泛型抽象方法。 
7、不能对泛型参数使用+或+=之类的运算符 
public   class   Calculator <T> 

public   T   Add   (T   arg1,T   arg2) 

return   arg1   +   arg2;//错误 


但是我们可以通过泛型抽象类、接口来实现在个功能,因为实现泛型抽象类、接口我们就已经明确传一个参数了,就可以执行诸如+这样的操作。 

八:泛型方法 
1、方法可以定义特定于其执行范围的泛型参数 
public   class   MyClass <T> 

public   void   MyMethod <X> (X   x) 
{...} 

2、即使各包含类根本不使用泛型,你也可以定义方法特定的泛型参数 
public   class   MyClass 

public   void   MyMethod <T> (T   t) 
{...} 

注意:该功能只使用于方法,属性,索引器只能使用在类的作用范围中定义的泛型参数。 
3、调用泛型方法 
MyClass   obj   =   new   MyClass(); 
obj.MyMethod <int> (3); 
也可以这样: 
MyClass   obj   =   new   MyClass(); 
obj.MyMethod(3);   //该功能称为泛型推理 
4、泛型方法也可以有自己的泛型参数约束 
pubic   class   MyClass 

public   void   SomeMethod <T> (T   t)   where   T:IComparable <T> 
{...} 

5、子类方法实现不能重复在父级别出现的约束 
public   class   BaseClass 

public   virtual   void   SomeMethod <T> (T   t)where   T:new() 
{...} 

pubic   class   SubClass:BaseClass 

public   override   void   SomeMethod <T> (T   t)//不能再有约束 
{...} 

6、静态方法 
静态方法可以定义特定的泛型参数和约束 
public   class   MyClass <T> 

public   static   T   SomeMethod <X> (T   t,X   x) 
{...} 

int   number   =   MyClass <int> .SomeMethod <string> (3, "AAA "); 
或者:int   mumber   =   MyClass <int> .SomeMethod(3, "AAA "); 

九:泛型委托 
1、在某个类中定义的委托可以利用该类的泛型参数 
2、委托也可以定义自己的泛型参数

C#代码
  1. 1.泛型和泛型强制转换 
  2.  
  3. using System; 
  4. using System.Collections.Generic; 
  5. using System.Text; 
  6.   
  7. namespace VS2005Demo2 
  8. 6{ 
  9. 8    C# 编译器只允许将泛型参数隐式强制转换到 Object 或约束指定的类型#region  C# 编译器只允许将泛型参数隐式强制转换到 Object 或约束指定的类型 
  10. 9    public interface ISomeInterface 
  11. 10    { } 
  12. 11    class BaseClass 
  13. 12    { } 
  14. 13    class MyClass<T> where T : BaseClass, ISomeInterface 
  15. 14    { 
  16. 15        void SomeMethod(T t) 
  17. 16        { 
  18. 17            ISomeInterface obj1 = t; 
  19. 18            BaseClass obj2 = t; 
  20. 19            object obj3 = t; 
  21. 20        } 
  22. 21    } 
  23. 22    #endregion 
  24. 23 
  25. 24    编译器允许您将泛型参数显式强制转换到其他任何接口,但不能将其转换到类#region 编译器允许您将泛型参数显式强制转换到其他任何接口,但不能将其转换到类 
  26. 25    class SomeClass 
  27. 26    { } 
  28. 27    //class MyClass1<T> 
  29. 28    //{ 
  30. 29    //    void SomeMethod(T t) 
  31. 30    //    { 
  32. 31    //        ISomeInterface obj1 = (ISomeInterface)t;  //Compiles 
  33. 32    //        SomeClass obj2 = (SomeClass)t;           //Does not compile 
  34. 33    //    } 
  35. 34    //} 
  36. 35    #endregion 
  37. 36 
  38. 37 
  39. 38    使用临时的 Object 变量,将泛型参数强制转换到其他任何类型#region 使用临时的 Object 变量,将泛型参数强制转换到其他任何类型 
  40. 39    class MyClass2<T> 
  41. 40    { 
  42. 41        void SomeMethod(T t) 
  43. 42        { 
  44. 43            object temp = t; 
  45. 44            SomeClass obj = (SomeClass)temp; 
  46. 45        } 
  47. 46    } 
  48. 47    #endregion 
  49. 48 
  50. 49    使用isas运算符#region 使用isas运算符 
  51. 50    public class MyClass3<T> 
  52. 51    { 
  53. 52        public void SomeMethod(T t) 
  54. 53        { 
  55. 54            if (t isint) { } 
  56. 55            if (t is LinkedList<int,string>) { } 
  57. 56            string str = t asstring
  58. 57            if (str != null) { } 
  59. 58            LinkedList<int,string> list = tas LinkedList<int,string>; 
  60. 59            if (list != null) { } 
  61. 60        } 
  62. 61    } 
  63. 62    #endregion 
  64. 63 
  65. 64} 
  66. 65 
  67.  
  68. 2.继承和泛型 
  69.  
  70.   1using System; 
  71.   2using System.Collections.Generic; 
  72.   3using System.Text; 
  73.   4 
  74.   5namespace VS2005Demo2 
  75.   6{ 
  76.   7    继承和泛型#region 继承和泛型 
  77.   8    public class BaseClass<T> 
  78.   9    { } 
  79. 10    public class SubClass : BaseClass<int
  80. 11    { } 
  81. 12 
  82. 13 
  83. 14    public class SubClass1<R> : BaseClass<R> 
  84. 15    { } 
  85. 16    #endregion 
  86. 17 
  87. 18    继承约束#region 继承约束 
  88. 19    public class BaseClass1<T> where T : ISomeInterface 
  89. 20    { } 
  90. 21    public class SubClass2<T> : BaseClass1<T> where T : ISomeInterface 
  91. 22    { } 
  92. 23 
  93. 24    //构造函数约束 
  94. 25    public class BaseClass3<T> where T :new() 
  95. 26    { 
  96. 27        public T SomeMethod() 
  97. 28        { 
  98. 29            return new T(); 
  99. 30        } 
  100. 31    } 
  101. 32    public class SubClass3<T> : BaseClass3<T> where T :new() 
  102. 33    { } 
  103. 34 
  104. 35    #endregion 
  105. 36 
  106. 37    虚拟方法#region 虚拟方法 
  107. 38    public class BaseClass4<T> 
  108. 39    { 
  109. 40        public virtual T SomeMethod() 
  110. 41        { 
  111. 42            return default(T); 
  112. 43        } 
  113. 44    } 
  114. 45    public class SubClass4 : BaseClass4<int
  115. 46    { 
  116. 47        public overrideint SomeMethod() 
  117. 48        { 
  118. 49            return 0; 
  119. 50        } 
  120. 51    } 
  121. 52 
  122. 53    public class SubClass5<T> : BaseClass4<T> 
  123. 54    { 
  124. 55        public override T SomeMethod() 
  125. 56        { 
  126. 57            return default(T); 
  127. 58        } 
  128. 59    } 
  129. 60 
  130. 61    #endregion 
  131. 62 
  132. 63    接口、抽象类继承#region 接口、抽象类继承 
  133. 64    public interface ISomeInterface6<T> 
  134. 65    { 
  135. 66        T SomeMethod(T t); 
  136. 67    } 
  137. 68    public abstractclass BaseClass6<T> 
  138. 69    { 
  139. 70        public abstract T SomeMethod(T t); 
  140. 71    } 
  141. 72    public class SubClass6<T> : BaseClass6<T>,ISomeInterface6<T> 
  142. 73    { 
  143. 74        public override T SomeMethod(T t) 
  144. 75        { return default(T); } 
  145. 76    } 
  146. 77    #endregion 
  147. 78 
  148. 79    泛型抽象方法和泛型接口#region 泛型抽象方法和泛型接口 
  149. 80    //public class Calculator<T> 
  150. 81    //{ 
  151. 82    //    public T Add(T arg1, T arg2) 
  152. 83    //    { 
  153. 84    //        return arg1 + arg2;//Does not compile 
  154. 85    //    } 
  155. 86    //    //Rest of the methods 
  156. 87    //} 
  157. 88 
  158. 89    public abstractclass BaseCalculator<T> 
  159. 90    { 
  160. 91        public abstract T Add(T arg1, T arg2); 
  161. 92        //public abstract T Subtract(T arg1, T arg2); 
  162. 93        //public abstract T Divide(T arg1, T arg2); 
  163. 94        //public abstract T Multiply(T arg1, T arg2); 
  164. 95    } 
  165. 96    public class MyCalculator : BaseCalculator<int
  166. 97    { 
  167. 98        public overrideint Add(int arg1,int arg2) 
  168. 99        { 
  169. 100            return arg1 + arg2; 
  170. 101        } 
  171. 102        //Rest of the methods 
  172. 103    } 
  173. 104 
  174. 105    public interface ICalculator<T> 
  175. 106    { 
  176. 107        T Add(T arg1, T arg2); 
  177. 108        //Rest of the methods 
  178. 109    } 
  179. 110    public class MyCalculator1 : ICalculator<int
  180. 111    { 
  181. 112        public int Add(int arg1,int arg2) 
  182. 113        { 
  183. 114            return arg1 + arg2; 
  184. 115        } 
  185. 116        //Rest of the methods 
  186. 117    } 
  187. 118    #endregion 
  188. 119 
  189. 120} 
  190. 121 
  191.  
  192. 3.泛型方法 
  193.  
  194.   1using System; 
  195.   2using System.Collections.Generic; 
  196.   3using System.Text; 
  197.   4 
  198.   5namespace VS2005Demo2 
  199.   6{ 
  200.   7 
  201.   8    泛型方法#region 泛型方法 
  202.   9    public class MyClass 
  203. 10    { 
  204. 11        public void MyMethod<T>(T t) 
  205. 12        { } 
  206. 13    } 
  207. 14 
  208. 15    public class Class3 
  209. 16    { 
  210. 17        public void Test() 
  211. 18        { 
  212. 19            MyClass obj = new MyClass(); 
  213. 20            obj.MyMethod<int>(3); 
  214. 21 
  215. 22            obj.MyMethod(3); 
  216. 23        } 
  217. 24    } 
  218. 25    #endregion 
  219. 26 
  220. 27    编译器无法只根据返回值的类型推断出类型#region 编译器无法只根据返回值的类型推断出类型 
  221. 28    public class MyClass1 
  222. 29    { 
  223. 30        public T MyMethod<T>() 
  224. 31        { return default(T); } 
  225. 32    } 
  226. 33 
  227. 34    public class Class31 
  228. 35    { 
  229. 36        public void Test() 
  230. 37        { 
  231. 38 
  232. 39            MyClass1 obj = new MyClass1(); 
  233. 40            int number = obj.MyMethod<int>(); 
  234. 41        } 
  235. 42    } 
  236. 43    #endregion 
  237. 44 
  238. 45    泛型方法约束#region 泛型方法约束 
  239. 46    public class Class32 
  240. 47    { 
  241. 48        public T MyMethod<T>(T t) where T : IComparable<T> 
  242. 49        { return default(T); } 
  243. 50    } 
  244. 51    #endregion 
  245. 52 
  246. 53    泛型虚拟方法#region 泛型虚拟方法 
  247. 54    public class BaseClass33 
  248. 55    { 
  249. 56        public virtualvoid SomeMethod<T>(T t) 
  250. 57        { } 
  251. 58    } 
  252. 59    public class SubClass33 : BaseClass33 
  253. 60    { 
  254. 61        public overridevoid SomeMethod<T>(T t) 
  255. 62        { 
  256. 63            base.SomeMethod<T>(t); 
  257. 64        } 
  258. 65    } 
  259. 66 
  260. 67    public class BaseClass34 
  261. 68    { 
  262. 69        public virtualvoid SomeMethod<T>(T t) where T :new() 
  263. 70        { } 
  264. 71    } 
  265. 72    public class SubClass34 : BaseClass34 
  266. 73    { 
  267. 74        public overridevoid SomeMethod<T>(T t)// where T : IComparable<T> 
  268. 75        { } 
  269. 76    } 
  270. 77 
  271. 78    public class BaseClass35 
  272. 79    { 
  273. 80        public virtualvoid SomeMethod<T>(T t) 
  274. 81        { } 
  275. 82    } 
  276. 83    public class SubClass35 : BaseClass35 
  277. 84    { 
  278. 85        public overridevoid SomeMethod<T>(T t) 
  279. 86        { 
  280. 87            base.SomeMethod<T>(t); 
  281. 88            base.SomeMethod(t); 
  282. 89        } 
  283. 90    } 
  284. 91    #endregion 
  285. 92 
  286. 93    泛型静态方法#region 泛型静态方法 
  287. 94    public class MyClass36<T> 
  288. 95    { 
  289. 96        public static T SomeMethod(T t) 
  290. 97        { return default(T); } 
  291. 98    } 
  292. 99 
  293. 100    public class Class36 
  294. 101    { 
  295. 102        public void Test() 
  296. 103        { 
  297. 104            int number = MyClass36<int>.SomeMethod(3); 
  298. 105        } 
  299. 106    } 
  300. 107 
  301. 108    public class MyClass37<T> 
  302. 109    { 
  303. 110        public static T SomeMethod<X>(T t, X x) 
  304. 111        { return default(T); } 
  305. 112    } 
  306. 113    public class Class37 
  307. 114    { 
  308. 115        public void Test() 
  309. 116        { 
  310. 117            int number = MyClass37<int>.SomeMethod<string>(3,"AAA"); 
  311. 118            int number1 = MyClass37<int>.SomeMethod(3,"AAA"); 
  312. 119        } 
  313. 120    } 
  314. 121 
  315. 122    public class MyClass38 
  316. 123    { 
  317. 124        public static T SomeMethod<T>(T t) where T : IComparable<T> 
  318. 125        {  return default(T); } 
  319. 126    } 
  320. 127 
  321. 128    #endregion 
  322. 129} 
  323. 130 
  324.  
  325. 4.泛型委托 
  326.  
  327. 1using System; 
  328. 2using System.Collections.Generic; 
  329. 3using System.Text; 
  330. 5namespace VS2005Demo2 
  331. 6{ 
  332. 7    泛型委托#region 泛型委托 
  333. 8    public class MyClass40<T> 
  334. 9    { 
  335. 10        public delegatevoid GenericDelegate(T t); 
  336. 11        public void SomeMethod(T t) 
  337. 12        { } 
  338. 13    } 
  339. 14 
  340. 15    public class MyClassTest40 
  341. 16    { 
  342. 17        public void Tests() 
  343. 18        { 
  344. 19            MyClass40<int> obj =new MyClass40<int>(); 
  345. 20            MyClass40<int>.GenericDelegate del; 
  346. 21 
  347. 22            del = new MyClass40<int>.GenericDelegate(obj.SomeMethod); 
  348. 23            del(3); 
  349. 24 
  350. 25            //委托推理 
  351. 26            del = obj.SomeMethod; 
  352. 27 
  353. 28        } 
  354. 29    } 
  355. 30    #endregion 
  356. 31 
  357. 32    委托泛型参数#region 委托泛型参数 
  358. 33    public class MyClass41<T> 
  359. 34    { 
  360. 35        public delegatevoid GenericDelegate<X>(T t, X x); 
  361. 36    } 
  362. 37 
  363. 38    //外部委托 
  364. 39    public delegatevoid GenericDelegate<T>(T t); 
  365. 40 
  366. 41    public class MyClass42 
  367. 42    { 
  368. 43        public void SomeMethod(int number) 
  369. 44        { } 
  370. 45    } 
  371. 46 
  372. 47    public class MyClassTest42 
  373. 48    { 
  374. 49        public void Test() 
  375. 50        { 
  376. 51            MyClass42 obj = new MyClass42(); 
  377. 52            GenericDelegate<int> del; 
  378. 53            //del = new GenericDelegate<int>(obj.SomeMethod); 
  379. 54 
  380. 55            del = obj.SomeMethod; 
  381. 56            del(3); 
  382. 57 
  383. 58        } 
  384. 59    } 
  385. 60 
  386. 61    #endregion 
  387. 62 
  388. 63    委托泛型参数#region 委托泛型参数 
  389. 64    public delegatevoid MyDelegate<T>(T t) where T : IComparable<T>; 
  390. 65    #endregion 
  391. 66 
  392. 67    事件#region 事件 
  393. 68 
  394. 69    public delegatevoid GenericEventHandler<S, A>(S sender, A args); 
  395. 70     
  396. 71    public class MyPublisher 
  397. 72    { 
  398. 73        public event GenericEventHandler<MyPublisher, EventArgs> MyEvent; 
  399. 74        public void FireEvent() 
  400. 75        { 
  401. 76            MyEvent(this, EventArgs.Empty); 
  402. 77        } 
  403. 78    } 
  404. 79 
  405. 80    public class MySubscriber<A>//Optional: can be a specific type 
  406. 81    { 
  407. 82        public void SomeMethod(MyPublisher sender, A args) 
  408. 83        { } 
  409. 84    } 
  410. 85    public class MyClassTest43 
  411. 86    { 
  412. 87        public void Test() 
  413. 88        { 
  414. 89            MyPublisher publisher = new MyPublisher(); 
  415. 90            MySubscriber<EventArgs> subscriber = new MySubscriber<EventArgs>(); 
  416. 91            publisher.MyEvent += subscriber.SomeMethod; 
  417. 92        } 
  418. 93    } 
  419. 94    #endregion 
  420. 95} 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值