c# 泛型總結

來源:互聯網
上載者:User

標籤:

一、泛型概述:

泛型是C# 2.0引入的新特性,泛型為開發人員提供了類型的參數化的形式,他帶來的最大的好處之一是代碼的複用。他是通過運行時類型綁定來實現代碼的複用,或者說演算法的複用。其次,泛型為我們帶來的另一個好處是效能的提升,再次,它提供了編譯時間類型的安全檢查,為程式員減輕了負擔。下面將分別通過例子來就這三個方面來做個介紹。

一、演算法的複用。

下面我將舉一個簡單的例子,實現了一個簡單的List容器,提供Add元素的方法。

namespace GenericTest{    public class SimpleList<TIn>     {        private static TIn[] _element;        private const int DefaultSize = 5;        private int _currentIndex = -1;        private int _allocSize;        private int _length;        public SimpleList()        {            _element = new TIn[DefaultSize];            _allocSize = DefaultSize;        }        public TIn this[int index] { get { return _element[index]; } set { _element[index] = value; } }        public void Add(TIn value)        {            _currentIndex++;            if (_currentIndex >= DefaultSize)            {                _allocSize = _allocSize * 2;                TIn[] tmp = _element;                _element = new TIn[_allocSize];                tmp.CopyTo(_element, 0);                            }            _element[_currentIndex] = value;            _length++;        }        public int Length { get { return _length; }}    }    class Program    {        static void Main(string[] args)        {                        SimpleList<int> a = new SimpleList<int>();            a.Add(1);            a.Add(2);            a.Add(3);                       for (int i = 0; i < a.Length; i++)            {                Console.WriteLine(a[i]);            }            SimpleList<float> a1 = new SimpleList<float>();            a1.Add(2.3f);            for (int i = 0; i < a1.Length; i++)            {                Console.WriteLine(a[i]);            }                   }    }}

從代碼中我們可以看出我們定義的SimpleList類型Add方法帶有泛型參數,表明其可以接受任何類型的元素作為參數,當沒有泛型時,我們添加元素時,需要為每種類型都定義一個方法或者定義一個接收object型別參數的方法,運行時執行裝箱拆箱操作,進而影響程式的效能,以及不能提供編譯時間類型的安全檢查。通過上面的例子我們可以看出泛型為我們帶來的是演算法的複用,SimpList這個簡單的容器的Add方法能夠運用在任何類型的元素的添加上。

二、編譯時間類型的安全檢查。

我們在簡單定義一個Student類:

class Student
{
public string Name { get; set; }
public int Age { get; set; }
}

在執行個體化一個Student of SimpleList 的執行個體 :SimpleList<Student> st = new SimpleList<Student>(); 當我們向其中添加int元素時 st.Add(2),編譯器報錯,提示參數類型int不能賦值給參數類型Student,這便是泛型提供的編譯時間類型檢查的好處,我們不能隨便向其中添加元素。

三、效能的提升。

下面效能的提升,我們通過c#類庫提供的兩個容器來說明問題,一個是List,是System.Collections.Generic提供的泛型型別,一個是ArrayList,是System.Collections提供的非泛型型別。分別對實值型別和參考型別進行測試:

namespace ListBenchmark{    class Program    {        static void Main(string[] args)        {            ValueTypePerfTest();            ReferencePerfTest();        }        private static void ValueTypePerfTest()        {            int count = 10000000;            using (new OperationTimer("List<Int32>"))            {                List<Int32> l = new List<Int32>();                for (int i = 0; i < count; i++)                {                    l.Add(i);       //未裝箱                    Int32 x = l[i]; //未拆箱                }                l = null;  //確保垃圾收集器回收                            }            using (new OperationTimer("ArrayList<Int32>"))            {                ArrayList a = new ArrayList();                for (int i = 0; i < count; i++)                {                    a.Add(i);       //裝箱                    Int32 x = (int)a[i];//拆箱                }                a = null;//確保垃圾收集器回收                            }                    }        private static void ReferencePerfTest()        {            const int count = 10000000;            using (new OperationTimer("List<string>"))            {                List<string> l = new List<string>();                for (int i = 0; i < count; i++)                {                    l.Add("X"); //引用copy                    string x = l[i]; // 引用copy                }                l = null;                            }            using (new OperationTimer("ArrayList<string>"))            {                ArrayList a = new ArrayList();                for (int i = 0; i < count; i++)                {                    a.Add("X"); //引用copy                    string x = (String)a[i]; //cast check & 引用copy                }                a = null;                            }                    }    }    internal sealed class OperationTimer : IDisposable    {        private Stopwatch m_stopwatch;        private string m_text;        private int m_collectionCount;        public OperationTimer(string text)        {            PrepareForOperation();            m_text = text;            m_collectionCount = GC.CollectionCount(0);            m_stopwatch = Stopwatch.StartNew();        }        private static void PrepareForOperation()        {            GC.Collect();            GC.WaitForPendingFinalizers();            GC.Collect();        }        public void Dispose()        {            Console.WriteLine("{0}(GCs={1,3}) {2}",(m_stopwatch.Elapsed),GC.CollectionCount(0)- m_collectionCount,m_text);        }    }}

程式運行結果:從中可以看出對於實值型別,List比ArrayList有很大的效能的提升,主要是List添加元素時不需要進行boxing,擷取元素不需要unboxing,同時可以正是由於ArrayList的裝箱拆箱操作導致垃圾收集次數比較多。對於參考型別則執行時間相差無幾,只是做引用拷貝及擷取元素時的類型轉換檢查。

泛型型別的好處介紹到這,下面簡單的介紹一下泛型型別參數的約束。

四、泛型的型別參數約束:

泛型型別參數的約束規定了參數的編譯時間類型的限制。主要有參考型別約束,參考型別的約束不能使用一下之一:Object,Array,Delegate,MulticastDelegate ,ValueType,Enum,System.Void。例如如下泛型約束:

internal sealed class PrimaryConstratinOfStream<T> where T: Stream{},其中where為類型約束關鍵詞,該類型約束表明了使用PrimaryConstratinOfStream必須指定參數類型T為Stream類型或者派生自Stream類型,如FileStream;其中參考型別約束的兩個特殊的約束分別是class和struct,where T:class,表示T必須是參考型別,而where T:struct則表示T必須是實值型別。

其次,還有一種泛型型別約束的是介面類型,當指定了介面的約束,在使用對象時對於指定型別參數必須實現該介面。最後一種約束是構造器約束,如:

class ConstructorConstraint<T> where T: new(){},它告訴編譯器T必須是帶有一個public無參構造器的類型。

 

c# 泛型總結

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.