




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
第C#泛型的使用及示例詳解///paramname="tParameter"/param
publicstaticvoidShowT(TtParameter)whereT:People
Console.WriteLine($"{tParameter.Id}_{tParameter.Name}");
tParameter.Hi();
}
注意:
基類約束時,基類不能是密封類,即不能是sealed類。sealed類表示該類不能被繼承,在這里用作約束就無任何意義,因為sealed類沒有子類。
2、接口約束
///summary
///接口約束
////summary
///typeparamname="T"/typeparam
///paramname="t"/param
///returns/returns
publicstaticTGetT(Tt)whereT:ISports
t.Pingpang();
returnt;
}
3、引用類型約束class
引用類型約束保證T一定是引用類型的。
///summary
///引用類型約束
////summary
///typeparamname="T"/typeparam
///paramname="t"/param
///returns/returns
publicstaticTGetT(Tt)whereT:class
returnt;
}
4、值類型約束struct
值類型約束保證T一定是值類型的。
///summary
///值類型類型約束
////summary
///typeparamname="T"/typeparam
///paramname="t"/param
///returns/returns
publicstaticTGetT(Tt)whereT:struct
returnt;
}
5、無參數(shù)構(gòu)造函數(shù)約束new()
///summary
///new()約束
////summary
///typeparamname="T"/typeparam
///paramname="t"/param
///returns/returns
publicstaticTGetT(Tt)whereT:new()
returnt;
}
泛型約束也可以同時約束多個,例如:
publicstaticvoidShowT(TtParameter)
whereT:People,ISports,IWork,new()
Console.WriteLine($"{tParameter.Id}_{tParameter.Name}");
tParameter.Hi();
tParameter.Pingpang();
tParameter.Work();
}
注意:有多個泛型約束時,new()約束一定是在最后。
六、泛型的協(xié)變和逆變
協(xié)變和逆變是在.NET4.0的時候出現(xiàn)的,只能放在接口或者委托的泛型參數(shù)前面,out協(xié)變covariant,用來修飾返回值;in:逆變contravariant,用來修飾傳入?yún)?shù)。
先看下面的一個例子:
定義一個Animal類:
usingSystem;
usingSystem.Collections.Generic;
usingSystem.Linq;
usingSystem.Text;
usingSystem.Threading.Tasks;
namespaceMyGeneric
publicclassAnimal
publicintId{get;set;}
}
然后在定義一個Cat類繼承自Animal類:
usingSystem;
usingSystem.Collections.Generic;
usingSystem.Linq;
usingSystem.Text;
usingSystem.Threading.Tasks;
namespaceMyGeneric
publicclassCat:Animal
publicstringName{get;set;}
}
在Main()方法可以這樣調(diào)用:
//直接聲明Animal類
Animalanimal=newAnimal();
//直接聲明Cat類
Catcat=newCat();
//聲明子類對象指向父類
Animalanimal2=newCat();
//聲明Animal類的集合
ListAnimallistAnimal=newListAnimal
//聲明Cat類的集合
ListCatlistCat=newListCat
那么問題來了:下面的一句代碼是不是正確的呢?
ListAnimallist=newListCat
可能有人會認為是正確的:因為一只Cat屬于Animal,那么一群Cat也應(yīng)該屬于Animal啊。但是實際上這樣聲明是錯誤的:因為ListCat和ListAnimal之間沒有父子關(guān)系。
這時就可以用到協(xié)變和逆變了。
//協(xié)變
IEnumerableAnimalList1=newListAnimal
IEnumerableAnimalList2=newListCat
F12查看定義:
可以看到,在泛型接口的T前面有一個out關(guān)鍵字修飾,而且T只能是返回值類型,不能作為參數(shù)類型,這就是協(xié)變。使用了協(xié)變以后,左邊聲明的是基類,右邊可以聲明基類或者基類的子類。
協(xié)變除了可以用在接口上面,也可以用在委托上面:
FuncAnimalfunc=newFuncCat(()=null);
除了使用.NET框架定義好的以為,我們還可以自定義協(xié)變,例如:
///summary
///out協(xié)變只能是返回結(jié)果
////summary
///typeparamname="T"/typeparam
publicinterfaceICustomerListOutoutT
TGet();
publicclassCustomerListOutT:ICustomerListOutT
publicTGet()
returndefault(T);
}
使用自定義的協(xié)變:
//使用自定義協(xié)變
ICustomerListOutAnimalcustomerList1=newCustomerListOutAnimal
ICustomerListOutAnimalcustomerList2=newCustomerListOutCat
在來看看逆變。
在泛型接口的T前面有一個In關(guān)鍵字修飾,而且T只能方法參數(shù),不能作為返回值類型,這就是逆變。請看下面的自定義逆變:
///summary
///逆變只能是方法參數(shù)
////summary
///typeparamname="T"/typeparam
publicinterfaceICustomerListIninT
voidShow(Tt);
publicclassCustomerListInT:ICustomerListInT
publicvoidShow(Tt)
}
使用自定義逆變:
//使用自定義逆變
ICustomerListInCatcustomerListCat1=newCustomerListInCat
ICustomerListInCatcustomerListCat2=newCustomerListInAnimal
協(xié)變和逆變也可以同時使用,看看下面的例子:
///summary
///inT逆變
///outT協(xié)變
////summary
///typeparamname="inT"/typeparam
///typeparamname="outT"/typeparam
publicinterfaceIMyListininT,outoutT
voidShow(inTt);
outTGet();
outTDo(inTt);
publicclassMyListT1,T2:IMyListT1,T2
publicvoidShow(T1t)
Console.WriteLine(t.GetType().Name);
publicT2Get()
Console.WriteLine(typeof(T2).Name);
returndefault(T2);
publicT2Do(T1t)
Console.WriteLine(t.GetType().Name);
Console.WriteLine(typeof(T2).Name);
returndefault(T2);
}
使用:
IMyListCat,AnimalmyList1=newMyListCat,Animal
IMyListCat,AnimalmyList2=newMyListCat,Cat//協(xié)變
IMyListCat,AnimalmyList3=newMyListAnimal,Animal//逆變
IMyListCat,AnimalmyList4=newMyListAnimal,Cat//逆變+協(xié)變
七、泛型緩存
在前面我們學習過,類中的靜態(tài)類型無論實例化多少次,在內(nèi)存中只會有一個。靜態(tài)構(gòu)造函數(shù)只會執(zhí)行一次。在泛型類中,T類型不同,每個不同的T類型,都會產(chǎn)生一個不同的副本,所以會產(chǎn)生不同的靜態(tài)屬性、不同的靜態(tài)構(gòu)造函數(shù),請看下面的例子:
usingSystem;
usingSystem.Collections.Generic;
usingSystem.Linq;
usingSystem.Text;
usingSystem.Threading.Tasks;
namespaceMyGeneric
publicclassGenericCacheT
staticGenericCache()
Console.WriteLine("ThisisGenericCache靜態(tài)構(gòu)造函數(shù)");
_TypeTime=string.Format("{0}_{1}",typeof(T).FullName,DateTime.Now.ToString("yyyyMMddHHmmss.fff"));
privatestaticstring_TypeTime="";
publicstaticstringGetCache()
return_TypeTime;
}
然后新建一個測試類,用來測試GenericCache類的執(zhí)行順序:
usingSystem;
usingSystem.Collections.Generic;
usingSystem.Linq;
usingSystem.Text;
usingSystem.Threading;
usingSystem.Threading.Tasks;
namespaceMyGeneric
publicclassGenericCacheTest
publicstaticvoidShow()
for(inti=0;ii++)
Console.WriteLine(GenericCacheint.GetCache());
Thread.Sleep(10);
Console.WriteLine(GenericCachelong.GetCache());
Thread.Sleep(10);
Console.WriteLine(GenericCacheDateTime.GetCache());
Thread.Sleep(10);
Console.WriteLine(GenericCachestring.GetCache());
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 服裝設(shè)計從靈感到設(shè)計的流程
- 2024年7月高級育嬰員測試題與答案(附解析)
- 6月保健按摩師模擬練習題含答案(附解析)
- 航標器材在航道安全保障系統(tǒng)中的應(yīng)用考核試卷
- 安全用電知識培訓教材
- 《S制度執(zhí)行力》課件
- 道路安全措施施工方案
- 計劃生育與生育政策與人口流動趨勢考核試卷
- 移動通信技術(shù)在零售行業(yè)的應(yīng)用考核試卷
- 四年級孩子性教育指南
- 2025年濟南市中區(qū)九年級中考數(shù)學一??荚囋囶}(含答案)
- 16J914-1 公用建筑衛(wèi)生間
- 冷卻塔使用說明書
- 蔬菜捆扎機機械部分的設(shè)計說明書
- 腌臘肉制品生產(chǎn)車間工藝布置圖
- 配電柜安裝規(guī)則GGD
- 漁夫和金魚的故事.ppt
- 大金空調(diào)設(shè)定代碼表
- DCDC變換器電力電子課程設(shè)計報告
- GB 19295-2021 食品安全國家標準 速凍面米與調(diào)制食品(高清版)
- 國際籃聯(lián)三對三籃球比賽記錄表
評論
0/150
提交評論