C 泛型型別 泛型方法

2021-10-07 07:54:09 字數 4298 閱讀 6174

泛型會宣告型別引數—泛型的消費者需要提供型別引數來把佔位符型別填充

public

class

stack

var stack=

newstack

<

int>()

;stack.

push(2

);stack.

push(3

);int x=stack.

pop();

//2int y=stack.

pop();

//3

stack open type(開放型別)

stack closed type(封閉型別)

在執行時,所有的泛型型別例項都是封閉的(佔位符已被填充了)

沒有出現泛型之前,不同的型別實現相同的功能會寫一些重複的**。

為了解決這一點,通常會用object型別來實現一些通用的功能(因為所有的引用型別都繼承自object)。但是使用object型別時,有時候會發生一些型別轉化,出現裝箱、拆箱的操作,損失效能,因此泛型應運而生

public

class

objectstack

需要裝箱和向下轉換,這種轉化在編譯時無法進行檢查:

stack.

push

("s");

//不是object型別但可以push進入

int i=

(int

)stack.

pop();

//讀取時型別轉換錯誤,編譯時不會提示

stack.

push(20

);//裝箱操作,將值型別轉化成引用型別

varvalue=(

int)stack.

pop();

//拆箱操作,將引用型別轉化為值型別

static

void

swap

<

t>

(ref

t a,

reft b)

int x =5;

int y =10;

swap

<

int>

(ref x,

ref y)

;//型別引數也可以省略,編譯器可根據傳入的引數隱式推斷出型別

//也可以寫成:

swap

(ref x,

ref y)

;

在泛型型別裡面的方法,除非也引入了型別引數,否則是不會歸為泛型方法,即方法名後必須跟才是泛型方法

//不是泛型方法,儘管引數有泛型

public

void

getvalue

(t entity)

//是泛型方法

public

void

getvalue

<

t>

(t entity)

只有型別和方法可以引入型別引數,屬性、索引器、事件、字段、建構函式、操作符等不可以宣告型別引數,但是他們可以使用他們所在的泛型型別的型別引數

public

tthis

[int index]

=> data[index]

;//合法

public

stack

<

t>()

//建構函式不能引入型別引數,不合法

在宣告==class、struct、inteface、delegate的時候可以引入型別引數

其它的例如屬性,就不可以引入型別引數,但是可以使用型別引數

public

struct nullable

}

3.泛型型別/泛型方法可以有多個型別引數:

class

dictionary

var mydic=

newdictionary

<

int,

string

>()

;

4.泛型型別/泛型方法的名稱可以被過載,條件是引數型別的個數不同:

class

aclass

aclass

a

按約定,泛型型別/泛型方法如果只有乙個型別引數,那麼就叫t。

當使用多個型別引數的時候,每個型別引數都是用t作為字首,隨後跟著具有乙個描述性的乙個名字。

使用default關鍵字來獲取泛型型別引數的預設值

//t是引用型別,預設值是null

//t是值型別,預設值是0

static

void

zap<

t>

(t array)

}

預設情況下,泛型的型別引數可以是任何型別

如果只允許使用特定的引數型別,就可以指定約束

where t:base0-

class

//某個父類的子類

where t:

inte***ce

//實現了某個介面

where t:

class

//t必須是引用型別

where t:

struct

//t必須是值型別

where t:

new(

)//t必須有乙個無參的建構函式

where u:t //某個類必須繼承t

class

someclass

inte***ce

inte***ce1

class

genericclass

where t:someclass,

inte***ce1

where u:

new(

)

泛型約束可以作用域型別或方法的定義

public

inte***ce

icomparable

//泛型約束作用於方法

static t max

<

t>

(t a,

t b)

where t:icomparable

struct nullable

where t:

struct

static

void

initialize

<

t>

(t array)

where t:

new()}

//裸型別約束

class

stack

}

泛型型別class 可以有子類,在子類裡,可以繼續讓父類的型別引數保持開放

class

stack

class

specialstack

:stack

在子類裡,也可以使用具體的型別來關閉(封閉)父類的型別引數

class intstack:stack<

int>

子型別也可以引入新的型別引數:

class

list

class keyedlist

:list

技術上講,所有子類的型別引數都是新鮮的。你可以認為子類先把父類的型別引數給關閉了,然後又開啟了。為這個先關閉後開啟的型別引數帶來新的名稱或含義

class

list

class

keyedlist

:list

在封閉型別引數的時候,該型別可以把它自己作為具體的型別

public

inte***ce

iequatable

public

class

balloon

:iequatable

public

int cc

public

bool

equals

(balloon b)

}

針對每乙個封閉型別,靜態資料是唯一的

class

bobclass

test

}

泛型 泛型類 泛型方法 泛型擦除

1 是什麼?一種允許我們在不確定引數型別時候使用的型別。例如我不知道a方法應該會傳string還是int,我就用個泛型先佔坑。2 為什麼要用泛型?泛型可以在編譯期自動確定具體型別,檢查型別是否匹配,可以提高 的重用率,減少冗餘編碼。3 泛型與object的區別?像上面說的我不知道方法a的引數型別,其...

泛型 (2)泛型類 泛型方法 泛型介面

一 泛型類 定義person類 package cn.itcast.p2.bean public class person implements comparable public person string name,int age public int compareto person p ov...

泛型類,泛型方法,泛型介面

泛型,就是一種不確定的資料型別。如果在類後面加上 這個類就變成了泛型類。這個 t可以使用任意的字母代替。表示定義了一種不確定的資料型別,這種不確定的資料型別必須在使用這個類 比如建立物件 的時候才能確定下來。如果希望縮小泛型的範圍,延後泛型的確定時間,讓泛型在呼叫方法的時候確定,那麼我們可以使用泛型...