C#2.0中的泛型基礎介紹

來源:互聯網
上載者:User

泛型簡介
    泛型是C#2.0最為強大的特點之一。泛型使得我們定義型別安全(type-safe)的資料結構。因為我們可以重用資料處理的演算法而無需關注資料的特定類型,從而提高開發效率和代碼品質。從觀念上講,泛型類似欲C++中的模板,但是他們的實現和功能卻有著很大的不同。

泛型問題描述
    假設一種常用的資料結構,例如stack,他提供的經典method比如push和pop。 當我們想要開發一個通用stack(genaral-purpose)的時候,我們會想利用這種stack能夠處store任意類型的執行個體。在C#1.1中,我們只能用一個基於對象的(object-based) stack, 也就是在stack中的內部資料結構是不定型的(amorphous),然後stack 的method與objects進行互動。
比如
Public stack stack

{

obejct[] m_Items;

public void push(object item)

{...}

public object opo()

{...}

}
Stack mystack=new Stack();
mystack.push(1);
mystack.push(2);
int number=(int)stack.pop();

但是,對於基於對象的解決方案,存在2個問題。
    第一個問題是效能performance. 當我們利用實值型別的時候,我們必須採用裝箱操作(box) 將他們Push到stack中,當從stack中pop時,我們必須執行unbox操作,從而導致一些不必要的記憶體回收操作。即使我們用參考型別(reference type)而不是實值型別,仍然會存在效能下降,因為其必須將其從一個對象轉變成(cast)與其實際互動的類型,從而增加開銷。
Stack mystack=new Stack();
mystack.push("1");
string number=(string)stack.pop();
       第二個問題是關於型別安全(type safety).因為編譯器允許我們將任何類型轉換成object或者將object轉換cast)成任何類型。這樣,我們便失去了編譯時間(compile-time)型別安全。例如,以下代碼編譯時間沒問題,但是執行時會拋出異常
stack mystack=new stack();
mystack.push(1);
string number=(string)stack.pop();
解決這個問題的方法是我們設計一種指定特定類型的stack.例如IntStack,StringStack等等。這樣就失去了reuse的意義。

什麼是泛型(Generics)
    泛型允許我們定義一種型別安全的類,同時兼顧型別安全,效能和效率。我們只需要實現一次泛型服務,然後你就可以利用任何類型來使用它。文法為 <and > 標記,來封裝一個泛型型別參數。例如,下面的代碼demonstrate如何定義和使用一個泛型stack

block 1: the implementation of generic stack
public class stack<T>
{
readonly int m_size;
int m_stackpointer=0;
T[] m_Items;
public stack(int size)
{
m_size=size;
m_Items=new T[m_size];
}
public void Push(T item)
{
    if(m_stackpointer>=m_size)
        throw new StackOverflowException();
    m_Items[m_stackpointer]=item;
    m_stackpointer++;
}

public T pop()
{
    m_stackpointer--;
    if(m_stackpointer>=0)
            return m_Items[m_stackpointer];
    else
        {
            m_stackpointer=0;
            throw new InvalidOperationException("cannot pop an empty stack");
        }

}
}

blcok 2: the use of specific-type stack
public class program
{
    public static void Man()
    {
        stack<int> mystack=new stack<int>();
        mystack.push(1);
        mystack.push(2);
        int numnber=mystack.pop();
}
}

泛型的益處
    .Net中的泛型允許我們重用代碼,提高開發效率。即使改變資料類型或者內部資料,代碼也不需要重寫,不管是實值型別或者是參考型別。我們只需要開發,測試,發布我們的代碼一次後,我們就可以對任何的資料類型進行重用,包括未來未知的資料類型,所有編譯器支援的和型別安全的即可。因為泛型代碼不會強制執行裝箱和拆箱操作,或者類型轉換,因此performance得以提高。

泛型的應用
sample 1:單泛型
public struct Point<T>
{
   public T X;
   public T Y;
}
然後我們可以利用這個泛型點作為整數座標點,例如
Point<int> point;
point.X=1;
point.Y=2;

多泛型
例如,以下是一個泛型的鏈表的樣本

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace GenericTest
{
    public class Node<K, I>
    {
        public K m_key;
        public I m_item;
        public Node<K,I> next;

        public Node()
        {
         
        }

        public Node(K key, I item)
        {
            m_item = item;
            m_key = key;
            next = null;
        }
    }

    public class List<K,I>
    {
        Node<K, I> m_listHead;
        Node<K, I> m_listTail;

        public List()
        {
            m_listHead = m_listTail = null;
        }

        public void InsertList(K key,I item)
        {
            Node<K, I> newNode = new Node<K, I>(key, item);
            if (m_listHead == null)
                m_listHead = newNode;
            else
                 m_listTail.next= newNode;
            m_listTail = newNode;
            m_listTail.next = null;
        }

        public void ShowList()
        {
            Node<K,I> p;
            p=m_listHead;
            while (p!=null)
            {
                Console.WriteLine("key:{0} item:{1}", p.m_key, p.m_item);
                p = p.next;
            }
        }

    }

    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("\nGeneric List  1 test:");
            List<int, string> mylist = new List<int, string>();
            mylist.InsertList(1, "herengang");
            mylist.InsertList(2, "guliqun");
            mylist.InsertList(4, "Herenchao");
            mylist.ShowList();

            List<DateTime, string> haha = new List<DateTime, string>();
            Console.WriteLine("\nGeneric List 2 test:");
            haha.InsertList(DateTime.Now, "AAA");
            haha.InsertList(DateTime.Today, "BBB");
            haha.ShowList();
        }
    }
}

//generic type aliasing 給泛型取別名
using List = LinkedList<int,string>;
class ListClient
{
static void Main(string[] args)
{
List list = new List();
list.AddHead(123,"AAA");
}
}
說明:該文章翻譯自http://msdn2.microsoft.com/en-us/library/ms379564(VS.80).aspx

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.