zoukankan      html  css  js  c++  java
  • C#泛型实例详解

    本文以实例形式讲述了C#泛型的用法,有助于读者深入理解C#泛型的原理,具体分析如下:

    首先需要明白什么时候使用泛型:

    当针对不同的数据类型,采用相似的逻辑算法,为了避免重复,可以考虑使用泛型。

    一、针对类的泛型

    针对不同类型的数组,写一个针对数组的"冒泡排序"。

    1.思路

    ● 针对类的泛型,泛型打在类旁。 
    ● 由于在"冒泡排序"中需要对元素进行比较,所以泛型要约束成实现IComparable接口。

     1 class Program
     2 {
     3   static void Main(string[] args)
     4   {
     5     SortHelper<int> isorter = new SortHelper<int>();
     6     int[] iarray = {8, 7, 1, 2, 12};
     7     isorter.BubbleSort(iarray);
     8     foreach (int item in iarray)
     9     {
    10       Console.Write(item+ ", ");
    11     }
    12     Console.ReadKey();
    13   }
    14 }
    15  
    16 public class SortHelper<T> where T : IComparable
    17 {
    18   public void BubbleSort(T[] array)
    19   {
    20     int length = array.Length;
    21     for (int i = 0; i <= length -2; i++)
    22     {
    23       for (int j = length - 1; j >= 1; j--)
    24       {
    25         if (array[j].CompareTo(array[j-1]) < 0)
    26         {
    27           T temp = array[j];
    28           array[j] = array[j - 1];
    29           array[j - 1] = temp;
    30         }
    31       }
    32     }
    33   }
    34 }

     运行结果如下图所示:

    2.关于泛型约束

    where T : IComparable 把T约束为实现IComparable接口 
    where T : class 
    where T : struct 
    where T : IComparable, new() 约束泛型必须有构造函数

    3.关于冒泡算法

    ● 之所以for (int i = 0; i <= length -2; i++),这是边界思维,比如有一个长度为5的数组,如果0号位元素最终调换到4号位,每次调一个位,需要经过4次才能到4号位,即for(int i = 0; i <= 5-2, i++),i依次为0, 1, 2, 4,期间经历了4次。

    ● 至于for (int j = length - 1; j >= 1; j--)循环,即遍历从最后一个元素开始到索引为1的元素,每次与前一个位置上的元素比较。

    4.关于比较

    int类型之所以能比较,是因为int类型也实现了IComparable接口。

    byte类型也一样实现了IComparable接口。

    二、自定义一个类,使之也能实现冒泡算法

    冒泡算法涉及到元素比较,所以自定义类必须实现IComparable接口。

     1 class Program
     2 {
     3   static void Main(string[] args)
     4   {
     5     Book[] bookArray = new Book[2];
     6     Book book1 = new Book(100, "书一");
     7     Book book2 = new Book(80, "书二");
     8     bookArray[0] = book1;
     9     bookArray[1] = book2;
    10  
    11     Console.WriteLine("冒泡之前:");
    12     foreach (Book b in bookArray)
    13     {
    14       Console.WriteLine("书名:{0},价格:{1}", b.Title, b.Price);
    15     }
    16  
    17     SortHelper<Book> sorter = new SortHelper<Book>();
    18     sorter.BubbleSort(bookArray);
    19     Console.WriteLine("冒泡之后:");
    20     foreach (Book b in bookArray)
    21     {
    22       Console.WriteLine("书名:{0},价格:{1}", b.Title, b.Price);
    23     }
    24     Console.ReadKey();
    25   }
    26 }
    27  
    28 public class SortHelper<T> where T : IComparable
    29 {
    30   public void BubbleSort(T[] array)
    31   {
    32     int length = array.Length;
    33     for (int i = 0; i <= length -2; i++)
    34     {
    35       for (int j = length - 1; j >= 1; j--)
    36       {
    37         if (array[j].CompareTo(array[j-1]) < 0)
    38         {
    39           T temp = array[j];
    40           array[j] = array[j - 1];
    41           array[j - 1] = temp;
    42         }
    43       }
    44     }
    45   }
    46 }
    47  
    48 //自定义类实现IComparable接口
    49 public class Book : IComparable
    50 {
    51   private int price;
    52   private string title;
    53  
    54   public Book(){}
    55  
    56   public Book(int price, string title)
    57   {
    58     this.price = price;
    59     this.title = title;
    60   }
    61  
    62   public int Price
    63   {
    64     get { return this.price; }
    65   }
    66  
    67   public string Title
    68   {
    69     get { return this.title; }
    70   }
    71  
    72   public int CompareTo(object obj)
    73   {
    74     Book book = (Book)obj;
    75     return this.Price.CompareTo(book.Price);
    76   }
    77 }

     运行结果如下图所示:

    三、针对方法的泛型

    继续上面的例子,自定义一个类,并定义泛型方法。

     1 //方法泛型
     2 public class MethodSortHelper
     3 {
     4   public void BubbleSort<T>(T[] array) where T : IComparable
     5   {
     6     int length = array.Length;
     7     for (int i = 0; i <= length - 2; i++)
     8     {
     9       for (int j = length - 1; j >= 1; j--)
    10       {
    11         if (array[j].CompareTo(array[j - 1]) < 0)
    12         {
    13           T temp = array[j];
    14           array[j] = array[j - 1];
    15           array[j - 1] = temp;
    16         }
    17       }
    18     }
    19   }
    20 }

     主程序如下:

     1 class Program
     2 {
     3   static void Main(string[] args)
     4   {
     5     Book[] bookArray = new Book[2];
     6     Book book1 = new Book(100, "书一");
     7     Book book2 = new Book(80, "书二");
     8     bookArray[0] = book1;
     9     bookArray[1] = book2;
    10  
    11     Console.WriteLine("冒泡之前:");
    12     foreach (Book b in bookArray)
    13     {
    14       Console.WriteLine("书名:{0},价格:{1}", b.Title, b.Price);
    15     }
    16  
    17     MethodSortHelper sorter = new MethodSortHelper();
    18     sorter.BubbleSort<Book>(bookArray);
    19     Console.WriteLine("冒泡之后:");
    20     foreach (Book b in bookArray)
    21     {
    22       Console.WriteLine("书名:{0},价格:{1}", b.Title, b.Price);
    23     }
    24     Console.ReadKey();
    25   }
    26 } 

     运行结果如下图所示:

    另外,使用泛型方法的时候,除了按以下:

    还可以这样写:  

    可见,泛型方法可以根据数组实例隐式推断泛型是否满足条件。

    四、泛型的其它优点

    1.避免隐式装箱和拆箱

    以下包含隐式装箱和拆箱:

     1 ArrayList list = new ArrayList();
     2 for(int i = 0; i < 3; i++)
     3 {
     4   list.Add(i); //Add接收的参数类型是引用类型object,这里包含了隐式装箱
     5 }
     6 for(int i = 0; i < 3; i++)
     7 {
     8   int value = (int)list[i]; //引用类型强转成值类型,拆箱
     9   Console.WriteLine(value);
    10 }

     使用泛型避免隐式装箱和拆箱:

     1 List<int> list = new List<int>();
     2 for(int i = 0; i < 3; i++)
     3 {
     4   list.Add(i);
     5 }
     6 for(int i = 0; i < 3; i++)
     7 {
     8   int value = list[i];
     9   Console.WriteLine(value);
    10 }

    2.能在编译期间及时发现错误

    不使用泛型,在编译期不会报错的一个例子:

    ArrayList list = new ArrayList();
    int i = 100;
    list.Add(i);
    string value = (string)list[0];
    

      使用泛型,在编译期及时发现错误:

    List<int> list = new List<int>();
    int i = 100;
    list.Add(i);
    string value = (string)list[0];
    

    五、使用泛型的技巧

    1.在当前文件中给泛型取别名

    using IntList = List<int>;
    IntList list = new IntList();
    list.Add(1);
    

    2.在不同文件中使用泛型别名,定义一个类派生于泛型

    public class IntList : List<int>{}
    

      

  • 相关阅读:
    收集一些关于前端的网站(持续更新)
    关于表单设计(登录)的几点感悟
    css样式表中的样式覆盖顺序(转)
    UI设计常用网站(随时更新)
    关于ps安装遇到的问题解决(转载整理)
    【工作记录】解决溢出div自适应的高度问题
    Cross origin requests are only supported for protocol schemes: http, data, chrome-extension, https, chrome-extension-resource. 报错处理
    [css]img垂直居中的方法
    iOS学习第三天杂记
    iOS学习第二天杂记--UI
  • 原文地址:https://www.cnblogs.com/zk-zhou/p/6634625.html
Copyright © 2011-2022 走看看