C# 泛型詳解---進階編程(七)

今天咱們來學習在C#的泛型技巧,傳統的課本都在講解什麼是泛型,而後列舉一大堆代碼示例告訴你什麼是泛型,今天咱們就來聊聊更加本質的東西,我爲何要用泛型?它是來解決什麼問題的?底層原理是什麼?c++

 

簡單來講,泛型解決的是什麼問題呢?算法重用和提高性能的。程序員

最最經典的例子是什麼?就是微軟支持的List<T>類型,想必絕大多的程序員都是使用過這個類的。若是沒有這個類,咱們能夠想象下,若是要你開發一個算法類,支持對數組的長度動態擴展的,還支持一些廣泛的數組操做的話。你會怎麼寫?算法

好比我要寫  int 數據類型的數組操做功能,寫了一遍的 ListInt 類,若是這時候咱們須要寫一個 float 類型的數組操做對象,咱們又得寫一遍 ListFloat, 也就是說,每用到一個新的類型的時候,都須要寫一遍類,而這之間的代碼絕大部分都是類似的。數組

 

你可能會提出我搞一個 ListObject 類就能夠了,這樣就能夠知足全部的狀況了,恭喜你,這真的是個很不錯的想法,不管你的類型是什麼?都會轉換爲object進行數組的操做,這樣只要寫一套代碼就能夠了。只是,當你用了一段時間以後,它會碰到2個比較麻煩的問題性能

1. 我實例化了 ListObject 類,Add了不少了int類型的數據,我如今要獲取全部的int類型的數組,好比int[],這個比較麻煩,須要對全部object數據進行強制轉換。數組的長度比較大的時候,這時候性能就不好,爲何說c和c++性能高,都是地址基於地址的操做,沒有類型轉換一說。學習

2. 我實例化了 ListObject 類,Add了不少了int類型的數據,可是我在用的時候,很容易就誤覺得是float類型的,從而轉換失敗,下降了開發的效率。對象

 

這時候咱們就要讓泛型出場了,List<T>類型,將數組通常的操做邏輯都進行了封裝,add,remove,insert,clear,等等操做。當你須要使用int類型的時候,就能夠定義List<int>的對象,當你須要short類型的時候,就能夠定義List<short>對象,並且不用再轉換來轉換去了。blog

彷佛除了上述的狀況須要泛型外,彷佛咱們實際中已經不須要泛型了,答案固然是否認的、ci

 

 

假設,咱們須要編寫一個公共的方法。是對數組操做的,好比咱們會寫一個方法,將數組擴充到指定長度開發

        /// <summary>
        /// 將一個數組進行擴充到指定長度,或是縮短到指定長度 ->
        /// Extend an array to a specified length, or shorten to a specified length or fill
        /// </summary>
        /// <typeparam name="T">數組的類型</typeparam>
        /// <param name="data">原先數據的數據</param>
        /// <param name="length">新數組的長度</param>
        /// <returns>新數組長度信息</returns>
        public static T[] ArrayExpandToLength<T>( T[] data, int length )
        {
            if (data == null) return new T[length];

            if (data.Length == length) return data;

            T[] buffer = new T[length];

            Array.Copy( data, buffer, Math.Min( data.Length, buffer.Length ) );

            return buffer;
        }

這麼來看,這個就特別是否寫成泛型,和類型無關的狀況。

 

 

以前是數組的例子,咱們再來看看另外一個實際的例子。咱們先看看代碼:

    /// <summary>
    /// 操做結果的泛型類,容許帶一個用戶自定義的泛型對象,推薦使用這個類
    /// </summary>
    /// <typeparam name="T">泛型類</typeparam>
    public class OperateResult<T> : OperateResult
    {
        #region Constructor

        /// <summary>
        /// 實例化一個默認的結果對象
        /// </summary>
        public OperateResult( ) : base( )
        {
        }

        /// <summary>
        /// 使用指定的消息實例化一個默認的結果對象
        /// </summary>
        /// <param name="msg">錯誤消息</param>
        public OperateResult( string msg ) : base( msg )
        {

        }

        /// <summary>
        /// 使用錯誤代碼,消息文原本實例化對象
        /// </summary>
        /// <param name="err">錯誤代碼</param>
        /// <param name="msg">錯誤消息</param>
        public OperateResult( int err, string msg ) : base( err, msg )
        {

        }

        #endregion

        /// <summary>
        /// 用戶自定義的泛型數據
        /// </summary>
        public T Content { get; set; }
    }

當你的自定義類須要攜帶一個數據時,而這個數據多是任意類型的時候,這時候可使用泛型。好比這裏的 OperateResult<int> 就是很是好的例子。能夠用來攜帶任意的自定義的數據。甚至是數組

OperateResult<List<int>> 這樣也是能夠的。

 

未完待與

相關文章
相關標籤/搜索