C# 定義泛型類(lèi)
要?jiǎng)?chuàng)建泛型類(lèi),只需要在類(lèi)定義中包含尖括號(hào)語(yǔ)法:
class MyGenericClass<T> { ... }
其中T可以是任意標(biāo)識(shí)符,只要遵循通常的C#命名規(guī)則即可,例如,不以數(shù)字開(kāi)頭等。但一般只使用T。泛型類(lèi)可在其定義中包含任意多個(gè)類(lèi)型參數(shù),參數(shù)之間用逗號(hào)分隔,例如:
class MyGenericClass<Tl, T2, T3> { ... }
定義了這些類(lèi)型后,就可以在類(lèi)定義中像使用其他類(lèi)型那樣使用它們??梢园阉鼈冇米鞒蓡T變量的類(lèi)型、屬性或方法等成員的返回類(lèi)型以及方法的參數(shù)類(lèi)型等。例如:
class MyGenericClass<Tl, T2, T3>
{
private T1 innerTlObject;
public MyGenericClass(T1 item)
{
innerTlObject = item;
}
public T1 InnerTlObject
{
get { return innerTlObjact; }
}
}
其中,類(lèi)型T1的對(duì)象可以傳遞給構(gòu)造函數(shù),只能通過(guò)InnerTlObject屬性對(duì)這個(gè)對(duì)象進(jìn)行只讀訪問(wèn)。注意,不能假定為類(lèi)提供了什么類(lèi)型。例如,下面的代碼就不會(huì)編譯:
class MyGenericClass<Tl, T2, T3>
{
private T1 innerTlObject;
public MyGenericClass()
{
innerTlObject = new T1 ();
}
public T1 InnerTlObject
{
get { return innerTlObject; }
}
}
我們不知道T1是什么,也就不能使用它的構(gòu)造函數(shù),它甚至可能沒(méi)有構(gòu)造函數(shù),或者沒(méi)有可公共訪問(wèn)的默認(rèn)構(gòu)造函數(shù)。如果不使用涉及高級(jí)技術(shù)的復(fù)雜代碼,則只能對(duì)T1進(jìn)行如下假設(shè):可以把它看成繼承自System.Object的類(lèi)型或可以封箱到System.Object中的類(lèi)型。
顯然,這意味著不能對(duì)這個(gè)類(lèi)型的實(shí)例進(jìn)行非常有趣的操作,或者對(duì)為MyGenericClass泛型類(lèi)提供的其他類(lèi)型進(jìn)行有趣的操作。不使用反射技術(shù),就只能使用下面的代碼:
public string GetAllTypesAsString()
{
return "T1 = " + typeof (Tl) .ToString() + T2 = " + typeof (T2) .ToString() + ", T3 = " + typeof (T3) .ToStringO ;
}
可以做一些其他工作,尤其是對(duì)集合進(jìn)行操作,因?yàn)樘幚韺?duì)象組是非常簡(jiǎn)單的,不需要對(duì)對(duì)象類(lèi)型進(jìn)行任何假設(shè),這是為什么存在泛型集合類(lèi)的一個(gè)原因。
另一個(gè)需要注意的限制是,在比較為泛型類(lèi)型提供的類(lèi)型值和null時(shí),只能使用運(yùn)算符=或!=。例如,下面的代碼會(huì)正常工作:
public bool Compare{Tl opl, Tl op2)
{
if (opl != null && op2 != null)
{
return true;
}
else
{
return false;
}
}
其中,如果Tl是一個(gè)值類(lèi)型,則總是假定它是非空的,于是在上面的代碼中,Compare總是返回true。但是,下面試圖比較兩個(gè)實(shí)參opl和op2的代碼將不能編譯:
public bool Compare{Tl opl, Tl op2)
{
if (opl ~ op2)
{
return true;
}
else
{
return false;
}
}
其原因是這段代碼假定Tl支持==運(yùn)算符。這說(shuō)明,要對(duì)泛型執(zhí)行實(shí)際操作,需要更多地了解類(lèi)中使用的類(lèi)型。
點(diǎn)擊加載更多評(píng)論>>