• c#泛型(包括泛型抽象类的继承)


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

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

  • 相关阅读:
    Hadoop压缩
    Hive数据倾斜总结
    DQL、DML、DDL、DCL
    HashMap/HashSet,hashCode,哈希表
    HashMap详解
    Hive分区和桶
    String不可变StringBuffer可变
    Java线程和守护进程
    Ambari安装小记
    P3
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/1893814.html
Copyright © 2020-2023  润新知