C 學習筆記(五) 泛型

2021-09-07 00:20:08 字數 4419 閱讀 2939

泛型使型別引數化,從而實現了演算法上的**重用。

同時由於去掉了轉換中裝箱和拆箱的操作,使用泛型還可以提高程式的執行速度。

我們先看看c#自帶的使用了泛型的類:

1

using

system.collections.generic;23

namespace

study417

}18 }

通過使用泛型,我們可以重複利用list提供的功能,而不用每個型別對應去寫乙個list的類。

下面我們自己使用泛型編寫乙個簡單的類,如下:

1

using

system;23

namespace

study417

}1819public

class test20

26get 27}

28}29 }

test類中的尖括號裡面的t即為泛型,其可以表示任意的型別。

我們上面示例中的t可以使用任意的型別,那麼如果我們只希望t是某型別或某型別的子類該怎麼辦呢?

public

class testwhere t : icomparable

如果這樣寫,則表示t必須是實現了icomparable介面的物件。

多個型別的寫法如下:

public

class testwhere t : icomparable where k : icloneable

如上所示,乙個型別如果要新增約束就需要寫乙個where進行對應,所以有多個就會有多個where關鍵字出現。

如果需要使用new建立乙個型別,則需要在約束裡新增new()的字串,如下:

1

using

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為值型別,如下:

1

using

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);

子類也有相同的泛型時:

1

public

class a234

public

class b: a5

當然,你可以使用另外的名稱,只要能對應上即可:

1

public

class a234

public

class b: a5

子類指定好型別:

1

public

class a234

public

class b : a

5

子類新增新型別:

1

public

class a234

public

class b: a5

如果要在方法上新增類上沒有指定的型別,可以直接在方法上新增泛型:

1

using

system;23

namespace

study414

}1516public

class test1722}

23 }

委託上也可以使用泛型,定義方法和在方法上使用泛型一致,如下:

1

using

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 }

泛型介面的使用和泛型類一致,大家可以檢視微軟自己的文件:

泛型同樣可以使用在靜態欄位和方法中,由於靜態欄位和方法在記憶體中始終只存在乙個,所以當我們使用了泛型的時候,編譯器會幫我們自動生成對應的方法。

泛型靜態的使用和動態一致就跳過不說了。

我們在呼叫泛型方法時可以省略泛型型別的書寫,完全交由編譯器根據我們的型別來進行判斷,這樣可以減小**量同時也更清晰:

1

using

system;23

namespace

study418

19private

static

int compareto(t a, t b) where

t : icomparable

2023

}24 }

我們先看乙個例子:

1

using

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關鍵字標識,如下:

public

inte***ce myinte***ce

示例:

1

using

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 }

逆變性指的是泛型型別引數可以從乙個基類隱式的轉換為其派生類。

public

inte***ce myinte***ce

示例:

1

using

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...