泛型會宣告型別引數—泛型的消費者需要提供型別引數來把佔位符型別填充
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。使用default關鍵字來獲取泛型型別引數的預設值當使用多個型別引數的時候,每個型別引數都是用t作為字首,隨後跟著具有乙個描述性的乙個名字。
//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可以使用任意的字母代替。表示定義了一種不確定的資料型別,這種不確定的資料型別必須在使用這個類 比如建立物件 的時候才能確定下來。如果希望縮小泛型的範圍,延後泛型的確定時間,讓泛型在呼叫方法的時候確定,那麼我們可以使用泛型...