泛型使型別引數化,從而實現了演算法上的**重用。
同時由於去掉了轉換中裝箱和拆箱的操作,使用泛型還可以提高程式的執行速度。
我們先看看c#自帶的使用了泛型的類:
1using
system.collections.generic;23
namespace
study417
}18 }
通過使用泛型,我們可以重複利用list提供的功能,而不用每個型別對應去寫乙個list的類。
下面我們自己使用泛型編寫乙個簡單的類,如下:
1using
system;23
namespace
study417
}1819public
class test20
26get 27}
28}29 }
test類中的尖括號裡面的t即為泛型,其可以表示任意的型別。
我們上面示例中的t可以使用任意的型別,那麼如果我們只希望t是某型別或某型別的子類該怎麼辦呢?
publicclass testwhere t : icomparable
如果這樣寫,則表示t必須是實現了icomparable介面的物件。
多個型別的寫法如下:
publicclass testwhere t : icomparable where k : icloneable
如上所示,乙個型別如果要新增約束就需要寫乙個where進行對應,所以有多個就會有多個where關鍵字出現。
如果需要使用new建立乙個型別,則需要在約束裡新增new()的字串,如下:
1using
system;23
namespace
study414
}1516public
class testwhere t : icomparable, new
()17
23get 24}
2526
public
test()
2730}31
32public
class
data : icomparable
3340
}41 }
但是如果是值型別,則不需要這麼寫,但是要約束t為值型別,如下:
1using
system;23
namespace
study414
}1516public
class testwhere t : struct
1723
get 24}
2526
public
test()
2730
}31 }
當我們需要對泛型t置空時不能直接寫「***=null;」因為只有當 t 為引用型別時,語句 t = null 才有效;只有當 t 為數值型別而不是結構時,語句 t = 0 才能正常使用。所以我們使用default關鍵字就可以解決這個問題,如下:
_mycomparable = default(t);
子類也有相同的泛型時:
1public
class a234
public
class b: a5
當然,你可以使用另外的名稱,只要能對應上即可:
1public
class a234
public
class b: a5
子類指定好型別:
1public
class a234
public
class b : a
5
子類新增新型別:
1public
class a234
public
class b: a5
如果要在方法上新增類上沒有指定的型別,可以直接在方法上新增泛型:
1using
system;23
namespace
study414
}1516public
class test1722}
23 }
委託上也可以使用泛型,定義方法和在方法上使用泛型一致,如下:
1using
system;23
namespace
study413
}1415public
class
test
1627
28private
int addint(int a, int
b)29
3233
private
float addfloat(float a, float
b)3437}
38 }
泛型介面的使用和泛型類一致,大家可以檢視微軟自己的文件:
泛型同樣可以使用在靜態欄位和方法中,由於靜態欄位和方法在記憶體中始終只存在乙個,所以當我們使用了泛型的時候,編譯器會幫我們自動生成對應的方法。
泛型靜態的使用和動態一致就跳過不說了。
我們在呼叫泛型方法時可以省略泛型型別的書寫,完全交由編譯器根據我們的型別來進行判斷,這樣可以減小**量同時也更清晰:
1using
system;23
namespace
study418
19private
static
int compareto(t a, t b) where
t : icomparable
2023
}24 }
我們先看乙個例子:
1using
system;
2using
system.collections.generic;34
namespace
study519
}2021public
classa22
{}23
24public
class
b : a
25{}
26 }
我們發現雖然b繼承於a,但是list和list之間是不能相互轉換的。
為了解決這個問題,微軟在c#4.0中新增了對泛型的可變性的支援。
協變性指的是泛型型別引數可以從乙個派生類隱式地轉換為其基類。
協變使用out關鍵字標識,如下:
publicinte***ce myinte***ce
示例:
1using
system;
2using
system.collections.generic;34
namespace
study515
}1617public
inte***ce myinte***ce
18{}
1920
public
class myclass: myinte***ce21
{}22
23public
classa24
{}25
26public
class
b : a
27{}
28 }
逆變性指的是泛型型別引數可以從乙個基類隱式的轉換為其派生類。
publicinte***ce myinte***ce
示例:
1using
system;
2using
system.collections.generic;34
namespace
study515
}1617public
inte***ce myinte***ce
18{}
1920
public
class myclass: myinte***ce21
{}22
23public
classa24
{}25
26public
class
b : a
27{}
28 }
只有介面和委託支援協變和逆變,類或方法都不支援協變和逆變;
協變和逆變只支援引用型別,值型別不支援協變和逆變;
必須顯示的使用out或in來標記協變和逆變;
委託的協變和逆變不要在多播委託中使用;
協變和逆變不能同時使用,只能選擇一種;
TypeScript學習筆記(五) 泛型
本篇將介紹在typescript如何使用泛型。在typescript裡,宣告泛型方法有以下兩種方式 1 function generics func1 arg t t 4 或者5 let generics func2 arg t t function arg 呼叫方式也有兩種 1 generics ...
C 學習筆記 泛型
泛型將型別引數的概念引入了.net,當我們需要設計類和方法,並將它們的型別制定推遲到客戶端 宣告,並例項化該型別和方法時,可以使用泛型。泛型使之前的想法成為了可能。使用泛型避免了執行時強制轉換或裝箱操作帶來的風險。簡單來說,首先制定乙個特定符號代替實際型別,當建立該型別的例項時,才指定它的實際型別。...
C 泛型學習筆記
泛型概述 使用泛型型別可以最大限度地重用 保護型別的安全以及提高效能。泛型最常見的用途是建立集合類。net framework 類庫在 system.collections.generic 命名空間中包含幾個新的泛型集合類。應盡可能地使用這些類來 代替普通的類,如 system.collection...