欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

淺談C#泛型的用處與特點

 更新時間:2013年09月22日 11:00:15   作者:  
泛型是 2.0 版 C# 語言和公共語言運行庫 (CLR) 中的一個新功能。泛型將類型參數(shù)的概念引入 .NET Framework,類型參數(shù)使得設(shè)計如下類和方法成為可能:這些類和方法將一個或多個類型的指定推遲到客戶端代碼聲明并實例化該類或方法的時候
泛型是 2.0 版 C# 語言和公共語言運行庫 (CLR) 中的一個新功能。泛型將類型參數(shù)的概念引入 .NET Framework,類型參數(shù)使得設(shè)計如下類和方法成為可能:這些類和方法將一個或多個類型的指定推遲到客戶端代碼聲明并實例化該類或方法的時候。例如,通過使用泛型類型參數(shù) T,您可以編寫其他客戶端代碼能夠使用的單個類,而不致引入運行時強制轉(zhuǎn)換或裝箱操作的成本或風(fēng)險,如下所示:

復(fù)制代碼 代碼如下:

// Declare the generic class
public class GenericList<T>
{
void Add(T input) { }
}
class TestGenericList
{
private class ExampleClass { }
static void Main()
{
// Declare a list of type int
GenericList<int> list1 = new GenericList<int>();
// Declare a list of type string
GenericList<string> list2 = new GenericList<string>();
// Declare a list of type ExampleClass
GenericList<ExampleClass> list3 = new GenericList<ExampleClass>();
}
}


使用泛型類型可以最大限度地重用代碼、保護類型的安全以及提高性能。
泛型最常見的用途是創(chuàng)建集合類。
.NET Framework 類庫在 System.Collections.Generic 命名空間中包含幾個新的泛型集合類。應(yīng)盡可能地使用這些類來代替普通的類,如 System.Collections 命名空間中的 ArrayList。
您可以創(chuàng)建自己的泛型接口、泛型類、泛型方法、泛型事件和泛型委托。
可以對泛型類進行約束以訪問特定數(shù)據(jù)類型的方法。
關(guān)于泛型數(shù)據(jù)類型中使用的類型的信息可在運行時通過反射獲取。

為什么要使用C#泛型?

為了了解這個問題,我們先看下面的代碼,代碼省略了一些內(nèi)容,但功能是實現(xiàn)一個棧,這個棧只能處理int數(shù)據(jù)類型:

復(fù)制代碼 代碼如下:

publicclassStack
{
privateint[]m_item;
publicintPop(){...}
publicvoidPush(intitem){...}
publicStack(inti)
{
this.m_item=newint[i];
}
}

上面代碼運行的很好,但是,當我們需要一個棧來保存string類型時,該怎么辦呢?很多人都會想到把上面的代碼復(fù)制一份,把int改成string不就行了。當然,這樣做本身是沒有任何問題的,但一個優(yōu)秀的程序是不會這樣做的,因為他想到若以后再需要long、Node類型的棧該怎樣做呢?還要再復(fù)制嗎?優(yōu)秀的程序員會想到用一個通用的數(shù)據(jù)類型object來實現(xiàn)這個棧:

復(fù)制代碼 代碼如下:

publicclassStack
{
privateobject[]m_item;
publicobjectPop(){...}
publicvoidPush(objectitem){...}
publicStack(inti)
{
this.m_item=new[i];
}
}

這個棧寫的不錯,他非常靈活,可以接收任何數(shù)據(jù)類型,可以說是一勞永逸。但全面地講,也不是沒有缺陷的,主要表現(xiàn)在:

當Stack處理值類型時,會出現(xiàn)裝箱、折箱操作,這將在托管堆上分配和回收大量的變量,若數(shù)據(jù)量大,則性能損失非常嚴重。

在處理引用類型時,雖然沒有裝箱和折箱操作,但將用到數(shù)據(jù)類型的強制轉(zhuǎn)換操作,增加處理器的負擔(dān)。

在數(shù)據(jù)類型的強制轉(zhuǎn)換上還有更嚴重的問題(假設(shè)stack是Stack的一個實例):

復(fù)制代碼 代碼如下:

Node1x=newNode1();
stack.Push(x);
Node2y=(Node2)stack.Pop();

上面的代碼在編譯時是完全沒問題的,但由于Push了一個Node1類型的數(shù)據(jù),但在Pop時卻要求轉(zhuǎn)換為Node2類型,這將出現(xiàn)程序運行時的類型轉(zhuǎn)換異常,但卻逃離了編譯器的檢查。

針對object類型棧的問題,我們引入泛型,他可以優(yōu)雅地解決這些問題。泛型用用一個通過的數(shù)據(jù)類型T來代替object,在類實例化時指定T的類型,運行時(Runtime)自動編譯為本地代碼,運行效率和代碼質(zhì)量都有很大提高,并且保證數(shù)據(jù)類型安全。

使用C#泛型

下面是用泛型來重寫上面的棧,用一個通用的數(shù)據(jù)類型T來作為一個占位符,等待在實例化時用一個實際的類型來代替。讓我們來看看泛型的威力:

復(fù)制代碼 代碼如下:

publicclassStack
{
privateT[]m_item;
publicTPop(){...}
publicvoidPush(Titem){...}
publicStack(inti)
{
this.m_item=newT[i];
}
}

類的寫法不變,只是引入了通用數(shù)據(jù)類型T就可以適用于任何數(shù)據(jù)類型,并且類型安全的。這個類的調(diào)用方法:

復(fù)制代碼 代碼如下:

//實例化只能保存int類型的類
Stacka=newStack(100);
a.Push(10);
a.Push("8888");//這一行編譯不通過,因為類a只接收int類型的數(shù)據(jù)
intx=a.Pop();
//實例化只能保存string類型的類
Stackb=newStack(100);
b.Push(10);//這一行編譯不通過,因為類b只接收string類型的數(shù)據(jù)
b.Push("8888");
stringy=b.Pop();

這個類和object實現(xiàn)的類有截然不同的區(qū)別:

1.他是類型安全的。實例化了int類型的棧,就不能處理string類型的數(shù)據(jù),其他數(shù)據(jù)類型也一樣。

2.無需裝箱和折箱。這個類在實例化時,按照所傳入的數(shù)據(jù)類型生成本地代碼,本地代碼數(shù)據(jù)類型已確定,所以無需裝箱和折箱。

3.無需類型轉(zhuǎn)換。

理論知識:

所謂泛型:即通過參數(shù)化類型來實現(xiàn)在同一份代碼上操作多種數(shù)據(jù)類型。泛型編程是一種編程范式,它利用“參數(shù)化類型”將類型抽象化,從而實現(xiàn)更為靈活的復(fù)用。

C#泛型賦予了代碼更強的類型安全,更好的復(fù)用,更高的效率,更清晰的約束。

C#泛型能力由CLR在運行時支持,區(qū)別于C++的編譯時模板機制,和java的編譯時的“搽拭法”。這使得泛型能力可以在各個支持CLR的語言之間進行無縫的互操作。

C#泛型代碼在被編譯為IL和元數(shù)據(jù)時,采用特殊的占位符來表示泛型類型,并用專有的IL指令支持泛型操作。而真正的泛型實例化工作以“on-demand”的方式,發(fā)生在JIT編譯時。

C#泛型編譯機制如下:

第一輪編譯時,編譯器只為Stack類型產(chǎn)生“泛型版”的IL代碼和元數(shù)據(jù),并不進行泛型類型的實例化,T在中間只充當占位符。

JIT編譯時,當JIT編譯器第一次遇到Stack時,將用int類型替換“泛型版”IL代碼與元數(shù)據(jù)中的T -- 進行泛型類型的實例化。

CLR為所有類型參數(shù)為“引用類型”的泛型類型產(chǎn)生同一份代碼,但如果類型參數(shù)為“值類型”,對每一個不同的“值類型”,CLR將為其產(chǎn)生一份獨立的代碼。

C#泛型的幾個特點

如果實例化泛型類型的參數(shù)相同,那么JIT編譯器會重復(fù)使用該類型,因此C#的動態(tài)泛型能力避免了C++靜態(tài)模板可能導(dǎo)致的代碼膨脹的問題。

C#泛型類型攜帶有豐富的元數(shù)據(jù),因此C#的泛型類型可以應(yīng)用于強大的反射技術(shù)。

C#的泛型采用“基類、接口、構(gòu)造器、值類型/引用類型”的約束方式來實現(xiàn)對類型參數(shù)的“顯示約束”,提高了類型安全的同時,也喪失了C++模板基于“簽名”的隱式約束所具有的高靈活性。

C#泛型類在編譯時,先生成中間代碼IL,通用類型T只是一個占位符。在實例化類時,根據(jù)用戶指定的數(shù)據(jù)類型代替T并由即時編譯器(JIT)生成本地代碼,這個本地代碼中已經(jīng)使用了實際的數(shù)據(jù)類型,等同于用實際類型寫的類,所以不同的封閉類的本地代碼是不一樣的。按照這個原理,我們可以這樣認為:泛型類的不同的封閉類是分別不同的數(shù)據(jù)類型。

這樣泛型不僅更加靈活,也同時將代碼的簡便和提高到一個層次!不用再為具體不同的重載方法寫具體的代碼了!

C# 泛型是開發(fā)工具庫中的一個無價之寶。它們可以提高性能、類型安全和質(zhì)量,減少重復(fù)性的編程任務(wù),簡化總體編程模型,而這一切都是通過優(yōu)雅的、可讀性強的語法完成的。盡管 C# 泛型的根基是 C++ 模板,但 C# 通過提供編譯時安全和支持將泛型提高到了一個新水平。C# 利用了兩階段編譯、元數(shù)據(jù)以及諸如約束和一般方法之類的創(chuàng)新性的概念。毫無疑問,C# 的將來版本將繼續(xù)發(fā)展泛型,以便添加新的功能,并且將泛型擴展到諸如數(shù)據(jù)訪問或本地化之類的其他 .NET Framework 領(lǐng)域。

當然,C#的泛型還很多應(yīng)用,現(xiàn)在我還只是了解了它的機制和原理,在接下來的學(xué)習(xí)中我會系統(tǒng)得學(xué)習(xí)泛型所支持的抽象泛型,接口泛型,結(jié)構(gòu)和委托等!

相關(guān)文章

  • C#實現(xiàn)加密exe文件

    C#實現(xiàn)加密exe文件

    這篇文章主要為大家詳細介紹了C#如何實現(xiàn)加密exe文件的功能,文中的示例代碼講解詳細,對我們學(xué)習(xí)C#有一定的幫助,感興趣的小伙伴可以跟隨小編一起了解一下
    2023-01-01
  • C#之IP地址和整數(shù)互轉(zhuǎn)的小例子

    C#之IP地址和整數(shù)互轉(zhuǎn)的小例子

    C#之IP地址和整數(shù)互轉(zhuǎn)的小例子,需要的朋友可以參考一下
    2013-03-03
  • c# 調(diào)用Surfer軟件,添加引用的具體操作方法

    c# 調(diào)用Surfer軟件,添加引用的具體操作方法

    本篇文章主要是對c#中調(diào)用Surfer軟件,添加引用的具體操作方法進行了介紹,需要的朋友可以過來參考下,希望對大家有所幫助
    2014-01-01
  • C#實現(xiàn)基于XML配置MenuStrip菜單的方法

    C#實現(xiàn)基于XML配置MenuStrip菜單的方法

    這篇文章主要介紹了C#實現(xiàn)基于XML配置MenuStrip菜單的方法,涉及C#使用XML配置MenuStrip菜單的原理與實現(xiàn)技巧,具有一定參考借鑒價值,需要的朋友可以參考下
    2015-08-08
  • C#針對xml基本操作及保存配置文件應(yīng)用實例

    C#針對xml基本操作及保存配置文件應(yīng)用實例

    這篇文章主要介紹了C#針對xml基本操作及保存配置文件應(yīng)用實例,包括了針對XML文件的定義、初始化、創(chuàng)建、以及增刪改查等基礎(chǔ)操作,并配有詳細的實例加以說明,需要的朋友可以參考下
    2014-10-10
  • WinForm相對路徑的陷阱

    WinForm相對路徑的陷阱

    這篇文章主要介紹了WinForm相對路徑的陷阱,是在進行C#程序設(shè)計中尤其需要注意的問題,需要的朋友可以參考下
    2014-08-08
  • LINQ投影操作符Select與限制操作符where介紹

    LINQ投影操作符Select與限制操作符where介紹

    這篇文章介紹了LINQ投影操作符Select與限制操作符where,文中通過示例代碼介紹的非常詳細。對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-02-02
  • LINQ基礎(chǔ)之Intersect、Except和Distinct子句

    LINQ基礎(chǔ)之Intersect、Except和Distinct子句

    這篇文章介紹了LINQ使用Intersect、Except和Distinct子句的方法,文中通過示例代碼介紹的非常詳細。對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-04-04
  • WPF+ASP.NET SignalR實現(xiàn)動態(tài)折線圖的繪制

    WPF+ASP.NET SignalR實現(xiàn)動態(tài)折線圖的繪制

    這篇文章將以一個簡單的動態(tài)折線圖示例,簡述如何通過ASP.NET SignalR實現(xiàn)后臺通知功能,文中的示例代碼講解詳細,感興趣的小伙伴可以了解一下
    2023-01-01
  • C#數(shù)據(jù)表格(DataGridView)控件的應(yīng)用案例

    C#數(shù)據(jù)表格(DataGridView)控件的應(yīng)用案例

    這篇文章主要介紹了C#數(shù)據(jù)表格(DataGridView)控件的應(yīng)用案例,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-03-03

最新評論