c# 中的泛型以及強型別與弱型別
一直說C#是強型別語言,通俗地講,便是指C#中的“變數”在開發時其型別便是明確的:String便是String,Int32就是Int32。強型別的語言有以下幾點好處:
1.能夠享受程式碼提示功能
2.能夠獲得重構工具的支援
3.能夠在編譯期發現更多錯誤
與強型別相對的就是弱型別了,下面先簡單介紹一下強型別與弱型別,接著再說明一下為何引入泛型以及泛型的好處。
一、強型別與弱型別
1)不管是強型別還是弱型別,變數都有兩個屬性:型別和值;也就是說,弱型別的變數同樣有型別。
不管是哪一種程式語言,其中使用的變數,都既有型別,又有值。強型別的變數型別,必須在原始碼中明確定義,稱之為“變數宣告”,弱型別的變數型別則是無需宣告的,由直譯器解釋。但是,這並不意味著,弱型別的變數就沒有型別這一概念了,舉例來說,PHP的GetType就是返回該變數“當前”的型別。
2)強型別的變數型別是不能改變的,弱型別變數是隨需改變的,這是強弱的真正含義
強型別的變數一經宣告,就只能儲存這種型別的值,其他的值則必須通過轉換之後才能付給該變數,有編譯器自動理解的轉換,也有由程式設計師明確指定的強制轉換。但是,弱型別的變數型別則是隨著需要不斷轉換
簡單點說,強型別的變數的型別是在編譯階段就確定了,而弱型別的變數的型別是在執行的時候才確定的。最典型的就是var關鍵字。
(1)C#
var Name = "Bill Gates";
Name = 123;
在C#語言中,第一句的變數宣告以及賦值就已經指明Name是string型別的變量了,以後再想修改Name的型別就會報錯。
var Name = "Bill Gates";
Name = 123;
Name = true;
js是一種動態語言,變數的真正型別需要在執行的時候才能具體確定,所以上面的Name的值為布林值:true
沒有泛型的時候,所有的物件都是以object為基礎(object是所有物件的基類),如果要使用時必須進行強制型別轉換。對於值型別的轉換,則會導致不斷拆箱、裝箱的過程,會造成系統不停地分配記憶體、垃圾回收、資源回收,對系統消耗很大。
ArrayList list1 = new ArrayList(); list1.Add(1); //裝箱 int il1 = (int)list1[0];//拆箱 foreach (var item in list1) { } Console.WriteLine(i2); //執行拆箱
這個時候該泛型上場了
二、泛型的概念
泛型是 2.0 版 C# 語言和公共語言執行庫 (CLR) 中的一個新功能。泛型將型別引數的概念引入 .NET Framework,型別引數使得設計如下類和方法成為可能:這些類和方法將一個或多個型別的指定推遲到客戶端程式碼宣告並例項化該類或方法的時候。例如,通過使用泛型型別引數 T,您可以編寫其他客戶端程式碼能夠使用的單個類,而不致引入執行時強制轉換或裝箱操作的成本或風險。
(1)使用泛型時不需要通過object類進行強制型別轉換以及裝箱、拆箱。
List<int> list2 = new List<int>();
list2.Add(44); //不執行裝箱
int il2 = list2[0];//不執行拆箱
foreach (int i2 in list2)
Console.WriteLine(i2); //不執行拆箱
(3)泛型最早是用於集合中的,如List<>、Directory<Tkey,Tvalue>。泛型不僅僅可用於集合,還可以用於委託、介面和方法。
泛型類
public class Person<T> where T:class
{
public string name { get; set; }
public char sex { get; set; }
public Person()
{
}
public Person(string name, char sex)
{
this.name = name;
}
}
泛型介面
public interface IComparable<T> where T:class
{
T Max(T msg);
void Say(T msg);
}
泛型方法
public void Poligise<T>(T msg)
{
Console.WriteLine(msg);
}
泛型委託
public delegate void MDelegate<T>(T msg);
系統內有一些自帶的委託,如果沒什麼特殊的要求,我們最好還是採用系統泛型。如Action、Func泛型
三、泛型的優點:
1.高效能
使用泛型有效的減少了資料型別轉換以及由此產生的裝箱、拆箱,同時也減少了垃圾回收的次數,使程式具有較高的效能。
2.型別安全
ArrayList list = new ArrayList();
list.Add(44);
list.Add("mystring");
list.Add(new MyClass());
foreach (int i in list)
Console.WriteLine(i);
上面的程式碼不能有效避免異常的出現。而下面的程式碼在編譯階段就可以有效避免可能出現的異常:直接編譯不通過
List<int> list2 = new List<int>();
list2.Add(44);
//list2.Add("mystring");
//list2.Add(new MyClass());
3.程式碼的重用、多型
List<T>這個泛型類在使用時可以根據需要用不同的型別例項化
List<int> list=new List<int>();
list.Add(44);
List<string> stringList=new List<string>();
stringList.Add(“mystring”);
List<MyClass> myclassList=new List<MyClass>();
myClassList.Add(new MyClass());
上面只是簡單地介紹了一下泛型 的知識,泛型的具體使用會在下面的文章給出。