版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
C#程序設(shè)計(jì)
工程教程計(jì)算機(jī)“十二五〞規(guī)劃教材工程十四C#程序設(shè)計(jì)
工程教程計(jì)算機(jī)“十二五〞規(guī)劃教材工程十四C#程序設(shè)計(jì)工程教程學(xué)習(xí)任務(wù)掌握泛型的概念以及泛型類和泛型方法的應(yīng)用。
了解泛型約束的概念和使用方法。掌握泛型集合的應(yīng)用。工程十四泛型——提高代碼重用的最好方法C#程序設(shè)計(jì)工程教程學(xué)習(xí)任務(wù)工程十四泛型——提高代碼重2C#程序設(shè)計(jì)工程教程任務(wù)安排任務(wù)一熟悉泛型根底知識(shí)任務(wù)二泛型約束任務(wù)三泛型集合類工程十四泛型——提高代碼重用的最好方法C#程序設(shè)計(jì)工程教程任務(wù)安排工程十四泛型——提高代碼重3C#程序設(shè)計(jì)工程教程任務(wù)一熟悉泛型根底知識(shí)任務(wù)說(shuō)明預(yù)備知識(shí)在本任務(wù)中我們先來(lái)學(xué)習(xí)泛型的根底知識(shí)。一、為什么要使用泛型泛型用一個(gè)通過(guò)的數(shù)據(jù)類型T來(lái)代替object,在類實(shí)例化時(shí)指定T的類型,運(yùn)行時(shí)〔Runtime〕自動(dòng)編譯為本地代碼,運(yùn)行效率和代碼質(zhì)量都有很大提高,并且保證數(shù)據(jù)類型平安。使用泛型來(lái)定義棧publicclassStack<T>{privateT[]m_item;publicTPop(){...}publicvoidPush(Titem){...}publicStack(inti){this.m_item=newT[i];}}C#程序設(shè)計(jì)工程教程任務(wù)一熟悉泛型根底知識(shí)任務(wù)說(shuō)明預(yù)備知4C#程序設(shè)計(jì)工程教程在實(shí)例化時(shí)用一個(gè)實(shí)際的類型來(lái)代替數(shù)據(jù)類型T,如下所示:Stack<int>a=newStack<int>(100);//實(shí)例化只能保存int類型的類a.Push(10);//a.Push("8888"); //這一行編譯不通過(guò),因?yàn)轭恆只接收int類型的數(shù)據(jù)intx=a.Pop();Stack<string>b=newStack<string>(100);//實(shí)例化只能保存string類型的類//b.Push(10); //這一行編譯不通過(guò),因?yàn)轭恇只接收string類型的數(shù)據(jù)b.Push("8888");stringy=b.Pop();泛型類有如下優(yōu)點(diǎn):①類型平安②無(wú)需裝箱和折箱③無(wú)需類型轉(zhuǎn)換C#程序設(shè)計(jì)工程教程在實(shí)例化時(shí)用一個(gè)實(shí)際的類型來(lái)代替數(shù)據(jù)類型5C#程序設(shè)計(jì)工程教程二、泛型類與泛型方法〔一〕泛型類聲明泛型類的語(yǔ)法格式如下:類修飾符Class類名<T>:基類/接口{//相關(guān)代碼}泛型類可以在其定義中包含多個(gè)泛型類型,用逗號(hào)分隔開,例如:PublicClassMyGenericClass<T1,T2,T3>{//……}定義這些類型之后,可以將它們用作成員變量的類型、屬性或方法成員的返回類型等。另外,在泛型類中也可以使用普通數(shù)據(jù)類型,可以包含非泛型方法。C#程序設(shè)計(jì)工程教程二、泛型類與泛型方法〔一〕泛型類聲明泛型6C#程序設(shè)計(jì)工程教程C#在編譯泛型類時(shí),先生成中間代碼〔IL〕,通用類型T只是一個(gè)占位符。在實(shí)例化類時(shí),根據(jù)用戶指定的數(shù)據(jù)類型代替T并由即時(shí)編譯器〔JIT〕生本錢地代碼,這個(gè)本地代碼中已經(jīng)使用了實(shí)際的數(shù)據(jù)類型,等同于用實(shí)際類型寫的類,所以不同的封閉類〔這里封閉類是指由相同數(shù)據(jù)類型參數(shù)實(shí)例化的類〕的本地代碼是不一樣的。例如:Stack<int>和Stack<string>是兩個(gè)完全沒有任何關(guān)系的封閉類,你可以將它們看成類A和類B。C#程序設(shè)計(jì)工程教程C#在編譯泛型類時(shí),先生成中間7C#程序設(shè)計(jì)工程教程〔二〕泛型方法除了方法之外,其他的類成員如字段、屬性和方法等不能有自定義的泛型類型。聲明泛型方法的格式如下:修飾符返回類型方法名<泛型類型形參表>(形參表);{//其它語(yǔ)句}下面我們來(lái)看一段應(yīng)用泛型方法的代碼:publicclassStack2{publicvoidPush<T>(Stack<T>s,paramsT[]p){foreach(Ttinp){s.Push(t);}}}C#程序設(shè)計(jì)工程教程〔二〕泛型方法除了方法之外,其他8C#程序設(shè)計(jì)工程教程Stack2類可以一次將多個(gè)數(shù)據(jù)壓入Stack中。其中Push是一個(gè)泛型方法,調(diào)用這個(gè)方法的例如如下:Stack<int>x=newStack<int>(100);Stack2x2=newStack2();x2.Push(x,1,2,3,4,6);strings="";for(inti=0;i<5;i++){s+=x.Pop().ToString();} //至此,s的值為64321C#程序設(shè)計(jì)工程教程Stack2類可以一次將多個(gè)數(shù)據(jù)9C#程序設(shè)計(jì)工程教程〔三〕泛型中的靜態(tài)成員變量在泛型類中,靜態(tài)成員變量在相同封閉類間共享,不同的封閉類間不共享。例如:Stack<int>a=newStack<int>();Stack<int>b=newStack<int>();Stack<long>c=newStack<long>();類實(shí)例a和b是同一類型,他們之間共享靜態(tài)成員變量;但類實(shí)例c卻和a、b是完全不同的類型,所以不能和a、b共享靜態(tài)成員變量。C#程序設(shè)計(jì)工程教程〔三〕泛型中的靜態(tài)成員變量在泛型10C#程序設(shè)計(jì)工程教程〔四〕泛型類中的靜態(tài)構(gòu)造函數(shù)靜態(tài)構(gòu)造函數(shù)只能有一個(gè),且不能有參數(shù),且只能在.NET運(yùn)行時(shí)自動(dòng)被調(diào)用,不能人工調(diào)用。我們把泛型中的不同的封閉類理解為不同的類,那么泛型中的靜態(tài)構(gòu)造函數(shù)的原理和非泛型類是一樣的。靜態(tài)的構(gòu)造函數(shù)只在以下兩種情況被激發(fā):①特定的封閉類第一次被實(shí)例化。②特定封閉類中任一靜態(tài)成員變量被調(diào)用。C#程序設(shè)計(jì)工程教程〔四〕泛型類中的靜態(tài)構(gòu)造函數(shù)靜態(tài)構(gòu)11C#程序設(shè)計(jì)工程教程〔五〕泛型類中的方法重載通過(guò)一個(gè)例子來(lái)進(jìn)行學(xué)習(xí):publicclassNode<T,V>{
publicTadd(Ta,Vb)//第一個(gè)add
{
returna;
}
publicTadd(Va,Tb)//第二個(gè)add
{
returnb;
}
publicintadd(inta,intb)//第三個(gè)add
{
returna+b;
}}當(dāng)使用下面的調(diào)用代碼時(shí)Node<string,int>node=newNode<string,int>();objectx=node.add(2,"11");這兩行調(diào)用代碼可正確編譯,因?yàn)閭魅氲膕tring和int,使三個(gè)add方法具有不同的簽名,當(dāng)然能找到唯一匹配的add方法。但如果T和V都傳入int類型,三個(gè)add方法將具有同樣的簽名,請(qǐng)看下面代碼:Node<int,int>node=newNode<int,int>();objectx=node.add(2,11);此時(shí),這個(gè)類仍然能通過(guò)編譯,且能調(diào)用成功。因?yàn)橄到y(tǒng)會(huì)優(yōu)先匹配了第三個(gè)add方法。如果刪除了第三個(gè)add,上面的調(diào)用代碼那么無(wú)法編譯通過(guò),提示方法產(chǎn)生混淆無(wú)法在第一個(gè)add和第二個(gè)add之間選擇。C#的泛型是在實(shí)例的方法被調(diào)用時(shí)檢查重載是否產(chǎn)生混淆,而不是在泛型類本身編譯時(shí)檢查;當(dāng)一般方法與泛型方法具有相同的簽名時(shí),會(huì)覆蓋泛型方法。C#程序設(shè)計(jì)工程教程〔五〕泛型類中的方法重載通過(guò)一個(gè)例子來(lái)進(jìn)12C#程序設(shè)計(jì)工程教程任務(wù)實(shí)施——利用泛型類顯示信息任務(wù)說(shuō)明本案例主要完成的是通過(guò)下拉列表的ValueMember字段隱藏一些數(shù)據(jù)。數(shù)據(jù)類型只有在運(yùn)行時(shí)才知道,即可能是根本數(shù)據(jù)類型,也可能是類類型,需要用泛型類實(shí)現(xiàn)這個(gè)功能。實(shí)施步驟步驟1 創(chuàng)立一個(gè)Windows窗體應(yīng)用程序,將其命名為MySchool。向Form1窗體中添加一個(gè)Button控件,修改其Text值為“泛型類〞。然后向該工程中添加一個(gè)窗體,將其命名為FrmGenericClass,修改其Text值為“泛型類〞,并在此窗體中添加2個(gè)Label控件和2個(gè)ComboBox控件,并設(shè)置label1、label2的Text值分別為“學(xué)生集合〞、“教師集合〞。修改Form1窗體中Button控件的name值為“btnGenericClass〞,雙擊該按鈕添加其click事件代碼,如下所示:privatevoidbtnGenericClass_Click(objectsender,EventArgse) //調(diào)用泛型類窗體{
FrmGenericClassfrm=newFrmGenericClass();frm.Show();}C#程序設(shè)計(jì)工程教程任務(wù)實(shí)施——利用泛型類顯示信息任務(wù)說(shuō)明13C#程序設(shè)計(jì)工程教程步驟2 在應(yīng)用程序下添加Student類,完整代碼如下:namespaceMySchool{publicclassStudent{publicStudent():this("張三",20){}publicStudent(stringname,intage){this.Name=name;this.Age=age;}privatestringname;publicstringName{get{returnname;}set{name=value;}}privateintage;publicintAge{get{returnage;}set{if(value>0&&value<100){age=value;}else{age=18;}}}publicvoidSayHi()(“大家好,我是{0}同學(xué),今年{1}歲了“,,this.age);MessageBox.Show(message);}}}C#程序設(shè)計(jì)工程教程步驟2 在應(yīng)用程序下添加Studen14C#程序設(shè)計(jì)工程教程步驟3 在應(yīng)用程序下添加Teacher類,完整代碼如下:namespaceMySchool{publicclassTeacher{publicTeacher(stringname):this(name,2,5000){}publicTeacher(stringname,intservingYears):this(name,servingYears,5000){}publicTeacher(stringname,intservingYears,intsalary){=name;this.servingYears=servingYears;this.salary=salary;}privatestringname;publicstringName{get{returnname;}set{name=value;}}C#程序設(shè)計(jì)工程教程步驟3 在應(yīng)用程序下添加Teache15C#程序設(shè)計(jì)工程教程privateintsalary;publicintSalary{get{returnsalary;}set{salary=value;}}privateintservingYears;publicintServingYears{get{returnservingYears;}set{servingYears=value;}}publicvoidSayHi(){stringmessage=string.Format("大家好,我是{0}老師。我已經(jīng)在教育戰(zhàn)線奮斗了{(lán)1}年了!",,this.servingYears);MessageBox.Show(message);}}}C#程序設(shè)計(jì)工程教程privateintsala16C#程序設(shè)計(jì)工程教程步驟4 該工程中添加一個(gè)類文件,為其添加泛型類ComboBoxItem,詳細(xì)代碼如下所示:namespaceMySchool{//定義泛型類publicclassComboBoxItem<T>{privatestringitemText;publicstringItemText{get{returnitemText;}set{itemText=value;}}privateTitemValue;publicTItemValue{get{returnitemValue;}set{itemValue=value;}}}}C#程序設(shè)計(jì)工程教程步驟4 該工程中添加一個(gè)類文件,為其17C#程序設(shè)計(jì)工程教程步驟5 在FrmGenericClass窗體的Load事件中添加代碼如下:privatevoidFrmGenericClass_Load(objectsender,EventArgse){Studentzhang=newStudent("張三",20);Studentli=newStudent("李四",19);Studentwang=newStudent("王五",20);Teachernie=newTeacher("聶樹成",4);Teachertian=newTeacher("田天",2);//創(chuàng)立Combox項(xiàng),運(yùn)行時(shí)確定泛型類支持的數(shù)據(jù)類型ComboBoxItem<Student>itemzhang=newComboBoxItem<Student>();itemzhang.ItemText=zhang.Name;itemzhang.ItemValue=zhang;ComboBoxItem<Student>itemli=newComboBoxItem<Student>();itemli.ItemText=li.Name;itemli.ItemValue=li;ComboBoxItem<Student>itemwang=newComboBoxItem<Student>();itemwang.ItemText=wang.Name;itemwang.ItemValue=wang;C#程序設(shè)計(jì)工程教程步驟5 在FrmGenericCla18C#程序設(shè)計(jì)工程教程//創(chuàng)立支持學(xué)生類型的Items集合List<ComboBoxItem<Student>>items=newList<ComboBoxItem<Student>>();items.Add(itemzhang);items.Add(itemli);items.Add(itemwang);//在cboStudents下拉列表框顯示學(xué)生cboStudents.DataSource=items;cboStudents.DisplayMember="ItemText";cboStudents.ValueMember="ItemValue";//創(chuàng)立支持教師類型的Combox項(xiàng)ComboBoxItem<Teacher>itemtian=newComboBoxItem<Teacher>();itemtian.ItemText=tian.Name;itemtian.ItemValue=tian;ComboBoxItem<Teacher>itemnie=newComboBoxItem<Teacher>();itemnie.ItemText=nie.Name;itemnie.ItemValue=nie;//創(chuàng)立Items集合,支持教師類型List<ComboBoxItem<Teacher>>itemsT=newList<ComboBoxItem<Teacher>>();itemsT.Add(itemtian);itemsT.Add(itemnie);C#程序設(shè)計(jì)工程教程//創(chuàng)立支持學(xué)生類型的Items集合19C#程序設(shè)計(jì)工程教程//在cboTeachers下拉列表框顯示教師this.cboTeachers.DataSource=itemsT;cboTeachers.DisplayMember="ItemText";cboTeachers.ValueMember="ItemValue";}privatevoidcboStudents_SelectedIndexChanged(objectsender,EventArgse){if(cboStudents.SelectedIndex>0){Studentstu=(Student)cboStudents.SelectedValue;stu.SayHi();}}privatevoidcboTeachers_SelectedIndexChanged(objectsender,EventArgse){if(cboTeachers.SelectedIndex>0){TeacherTea=(Teacher)cboTeachers.SelectedValue;Tea.SayHi();}}C#程序設(shè)計(jì)工程教程//在cboTeachers下拉列表框顯20C#程序設(shè)計(jì)工程教程步驟6 按【Ctrl+F5】鍵程序運(yùn)行,在彈出的對(duì)話框中單擊“泛型類〞按鈕,將彈出“泛型類〞對(duì)話框,在此對(duì)話框中選擇不同的值,系統(tǒng)將彈出不同的信息提示,如以下圖所示。C#程序設(shè)計(jì)工程教程步驟6 按【Ctrl+F5】鍵程序運(yùn)21C#程序設(shè)計(jì)工程教程任務(wù)二
泛型約束任務(wù)說(shuō)明在定義泛型類時(shí),我們可以對(duì)用戶實(shí)例化類時(shí)所使用的類型參數(shù)的種類施加限制,如果用戶嘗試使用某個(gè)約束所不允許的類型來(lái)實(shí)例化類,那么會(huì)產(chǎn)生編譯錯(cuò)誤。在C#中這些限制就稱為約束,本節(jié)我們就來(lái)學(xué)習(xí)與此相關(guān)的知識(shí)。預(yù)備知識(shí)約束的方式是指定T的祖先,即繼承的接口或類。因?yàn)镃#的單根繼承性,所以約束可以有多個(gè)接口,但最多只能有一個(gè)類,并且類必須在接口之前。定義約束需要使用關(guān)鍵字where,如下所示:publicclassNode<T,V>whereT:Stack,IComparablewhereV:Stack{//...}T必須是從Stack和IComparable繼承的類型,V必須是Stack類型或從Stack繼承的類型,否那么將無(wú)法通過(guò)編譯器的類型檢查。C#程序設(shè)計(jì)工程教程任務(wù)二泛型約束任務(wù)說(shuō)明在定義泛22C#程序設(shè)計(jì)工程教程下面我們來(lái)看幾種常見的約束:〔1〕結(jié)構(gòu)約束結(jié)構(gòu)約束的格式如下:T〔類型〕:struct表示類型參數(shù)必須是值類型。〔2〕類約束T〔類型〕:class表示類型參數(shù)必須是引用類型,包括任何類、接口、委托或數(shù)組類型。publicstructA{}publicclassB{}classC<T>whereT:struct{//T是一個(gè)值類型}C<A>c=newC<A>();//正確,A是一個(gè)值類型C<B>c=newC<B>();//錯(cuò)誤,B是一個(gè)引用類型C#程序設(shè)計(jì)工程教程下面我們來(lái)看幾種常見的約束:〔1〕結(jié)構(gòu)約23C#程序設(shè)計(jì)工程教程〔3〕新建約束T〔類型〕:new()表示類型參數(shù)必須具有無(wú)參數(shù)的公共構(gòu)造方法。當(dāng)與其他約束一起使用時(shí),new()約束必須最后指定。例如:classA{publicvoidA(){}}classB{publicvoidB(inti){}}classC<T>whereT:new(){Tt=newT();}C<A>c=newC<A>();//正確,A有無(wú)參構(gòu)造方法C<B>c=newC<B>();//錯(cuò)誤,B沒有無(wú)參構(gòu)造方法C#程序設(shè)計(jì)工程教程〔3〕新建約束T〔類型〕:new()24C#程序設(shè)計(jì)工程教程〔4〕基類約束T〔類型〕:<基類名>用來(lái)限制參數(shù)類型從特定的類中派生,例如:classA{publicvoidF1(){}}classB{publicvoidF2(){}}classC<S,T>whereS:AwhereT:B{//可以在類型為S的變量上調(diào)用F1//可以在類型為T的變量上調(diào)用F2}C#程序設(shè)計(jì)工程教程〔4〕基類約束T〔類型〕:<基類名>用來(lái)25C#程序設(shè)計(jì)工程教程〔5〕接口約束T〔類型〕:<接口名>表示類型參數(shù)必須是指定的接口或?qū)崿F(xiàn)指定的接口??梢灾付ǘ鄠€(gè)接口約束。約束接口也可以是泛型的。例如:interfaceIPrintable{voidPrint();}interfaceIComparable<T>{intComparableTo(Tv);}interfaceIKeyProvider<T>{TGetKey();}classDictionary<K,V>whereK:IComparable<K>whereV:IPrintable,IKeyProvider<K>{//可以在類型為K的變量上調(diào)用CompareTo//可以在類型為V的變量上調(diào)用Print和GetKey}C#程序設(shè)計(jì)工程教程〔5〕接口約束T〔類型〕:<接口名>26C#程序設(shè)計(jì)工程教程〔6〕裸類約束〔nakedtypeconstraint〕T〔類型〕:U(被約束對(duì)象)表示為T提供的類型參數(shù)必須是為U提供的參數(shù),或者是派生自為U提供的參數(shù)。例如:ClassMyGenericClass<T1,T2>whereT2:T1{//…}其中,T2必須與T1的類型相同,或者繼承自T1。C#程序設(shè)計(jì)工程教程〔6〕裸類約束〔nakedtypec27C#程序設(shè)計(jì)工程教程任務(wù)實(shí)施——泛型約束應(yīng)用任務(wù)說(shuō)明在本任務(wù)中創(chuàng)立Animal、Cow和Chicken等動(dòng)物類,然后通過(guò)泛型類Farm來(lái)訪問(wèn)其他類的方法,F(xiàn)arm類被約束為Anima1類型。實(shí)施步驟步驟1 新建一Windows窗體應(yīng)用程序,命名為“MyAnimal〞。向窗體中添加一個(gè)Button控件,設(shè)置其Text值為“泛型類型約束〞。步驟2 在應(yīng)用程序下添加抽象Animal類,完整代碼如下:namespaceMyAnimal{publicabstractclassAnimal{publicAnimal(){}publicAnimal(stringnewName){name=newName;}protectedstringname;C#程序設(shè)計(jì)工程教程任務(wù)實(shí)施——泛型約束應(yīng)用任務(wù)說(shuō)明在28C#程序設(shè)計(jì)工程教程publicstringName{get{returnname;}set{name=value;}}//喂飼料publicvoidFeed(){MessageBox.Show("已經(jīng)有飼料了",name);}//動(dòng)物發(fā)出叫聲publicabstractvoidMakeANoise();}}C#程序設(shè)計(jì)工程教程publicstringName29C#程序設(shè)計(jì)工程教程步驟3 在應(yīng)用程序下添加Chicken類,繼承于Animal類,完整代碼如下:publicclassChicken:Animal{publicChicken(stringnewName):base(newName){}publicvoidLayEgg(){MessageBox.Show("下了一個(gè)蛋",name);}publicoverridevoidMakeANoise(){MessageBox.Show("嘎!嘎!嘎嘎",name);}}C#程序設(shè)計(jì)工程教程步驟3 在應(yīng)用程序下添加Chicke30C#程序設(shè)計(jì)工程教程步驟4 在應(yīng)用程序下添加Cow類,繼承于Animal類,完整代碼如下:publicclassCow:Animal{publicCow(stringnewName):base(newName){}publicvoidMilk(){MessageBox.Show("產(chǎn)一桶奶",name);}publicoverridevoidMakeANoise(){MessageBox.Show("哞!哞!哞!",name);}}C#程序設(shè)計(jì)工程教程步驟4 在應(yīng)用程序下添加Cow類,繼31C#程序設(shè)計(jì)工程教程步驟5 在應(yīng)用程序下添加SuperCow類,繼承于Cow類,完整代碼如下:publicclassSuperCow:Cow{publicSuperCow(stringnewName):base(newName){}publicvoidFly(){MessageBox.Show("飛翔",name);}publicoverridevoidMakeANoise(){MessageBox.Show("我是奶牛超人",name);}}C#程序設(shè)計(jì)工程教程步驟5 在應(yīng)用程序下添加SuperC32C#程序設(shè)計(jì)工程教程步驟6 在應(yīng)用程序下添加Farm類,定義為泛型類并約束Animal類,代碼如下:publicclassFarm<T>whereT:Animal{privateList<T>animals=newList<T>(); //List<T>的相關(guān)知識(shí)詳見任務(wù)三publicList<T>Animals{get{returnanimals;}}publicIEnumerator<T>GetEnumerator(){returnanimals.GetEnumerator();}publicvoidMakeNoises(){foreach(Tanimalinanimals){animal.MakeANoise();}}C#程序設(shè)計(jì)工程教程步驟6 在應(yīng)用程序下添加Farm類,33C#程序設(shè)計(jì)工程教程publicvoidFeedTheAnimals(){foreach(Tanimalinanimals){animal.Feed();}}publicFarm<Cow>GetCows(){Farm<Cow>cowFarm=newFarm<Cow>();foreach(Tanimalinanimals){if(animalisCow){cowFarm.Animals.Add(animalasCow);}}returncowFarm;}}C#程序設(shè)計(jì)工程教程publicvoidFeedTheA34C#程序設(shè)計(jì)工程教程步驟7 雙擊按鈕,在其Click事件中添加如下代碼:privatevoidbutton1_Click(objectsender,EventArgse){Farm<Animal>farm=newFarm<Animal>();farm.Animals.Add(newCow("Jack牛"));farm.Animals.Add(newChicken("Vera雞"));farm.Animals.Add(newChicken("Sally雞"));farm.Animals.Add(newSuperCow("Kevin超人牛"));farm.MakeNoises();Farm<Cow>dairyFarm=farm.GetCows();dairyFarm.FeedTheAnimals();foreach(CowcowindairyFarm){if(cowisSuperCow){(cowasSuperCow).Fly();}}}步驟8 按【Ctrl+F5】鍵運(yùn)行程序,查看運(yùn)行結(jié)果。C#程序設(shè)計(jì)工程教程步驟7 雙擊按鈕,在其Click事件35C#程序設(shè)計(jì)工程教程任務(wù)三
泛型集合類任務(wù)說(shuō)明泛型的一個(gè)重要應(yīng)用就是泛型集合。在工程十中我們學(xué)習(xí)集合時(shí)提到過(guò)泛型集合類,它位于命名空間中。本節(jié)我們就來(lái)學(xué)習(xí)有關(guān)泛型集合類的知識(shí)。預(yù)備知識(shí)下表以對(duì)照的方式列舉了最為常用的泛型集合類和同功能的非泛型集合。C#程序設(shè)計(jì)工程教程任務(wù)三泛型集合類任務(wù)說(shuō)明泛型的36C#程序設(shè)計(jì)工程教程一、List<T>泛型集合類List<T>類的用法非常類似于ArrayList,兩者的異同如下表所示。C#程序設(shè)計(jì)工程教程一、List<T>泛型集合類List<T37C#程序設(shè)計(jì)工程教程定義List<T>語(yǔ)法:List<T>對(duì)象名=newList<T>();List<T>中相關(guān)方法和屬性的說(shuō)明如下表所示。C#程序設(shè)計(jì)工程教程定義List<T>語(yǔ)法:List<T>38C#程序設(shè)計(jì)工程教程二、Dictionary<TKey,TValue>泛型集合類泛型集合Dictionary<TKey,TValue>,具有泛型的全部特性。編譯時(shí)檢查類型約束,獲取元素時(shí)無(wú)須類型轉(zhuǎn)換,并且它存儲(chǔ)數(shù)據(jù)的方式和哈希表類似,也是通過(guò)Key/Value〔鍵/值〕保存元素的。定義Dictionary<TKey,TValue>泛型集合的格式如下:Dictionary<K,V>對(duì)象名=newDictionary<K,V>();<K,V>中的K表示集合中Key的類型,V表示Value的類型。C#程序設(shè)計(jì)工程教程二、Dictionary<TKey,TV39C#程序設(shè)計(jì)工程教程任務(wù)實(shí)施1——List<T>泛型集合應(yīng)用任務(wù)說(shuō)明本案例利用泛型集合List<T>的知識(shí)輸出學(xué)生相關(guān)信息,案例效果是單擊“泛型集合List<T>〞按鈕,將順序顯示學(xué)生的相關(guān)信息,如以下圖所示。C#程序設(shè)計(jì)工程教程任務(wù)實(shí)施1——List<T>泛型集合應(yīng)用40C#程序設(shè)計(jì)工程教程實(shí)施步驟步驟1 翻開任務(wù)一中的“MySchool〞Windows應(yīng)用程序,向窗體Form1中添加一個(gè)Button按鈕,將其Text值設(shè)為為“泛型集合List<T>〞,name值為“btnList〞。再添加一個(gè)按鈕,將其Text值修改為“刪除泛型集合〞,name值為“btnDelete〞。在類Form1中創(chuàng)立幾個(gè)對(duì)象,代碼如下:List<Student>students; //泛型集合類List<T>對(duì)象Studentzhang; //學(xué)生對(duì)象Studentli; //學(xué)生對(duì)象Studentwang; //學(xué)生對(duì)象步驟2 雙擊“泛型集合List<T>〞按鈕,在其單擊事件中添加如下代碼:privatevoidbtnList_Click(objectsender,EventArgse){students=newList<Student>();Studentzhang=newStudent("張三",20);Studentli=newStudent("李四",19);Studentwang=newStudent("王五",20);C#程序設(shè)計(jì)工程教程實(shí)施步驟步驟1 翻開任務(wù)一中的“My41C#程序設(shè)計(jì)工程教程Teachernie=newTeacher("聶樹成",4);
students.Add(zhang);students.Add(li);students.Add(wang);//打印集合數(shù)目
MessageBox.Show(string.Format(“班級(jí)共包括{0}個(gè)成員。",students.Count.ToString()));foreach(Studentstuinstudents){stu.SayHi();}}privatevoidbtnDelete_Click(objectsender,EventArgse){Studentstu=students[0];//通過(guò)索引訪問(wèn)stu.SayHi();students.RemoveAt(0);//通過(guò)索引或者對(duì)象刪除students.Remove(li);foreach(Studentsuinstudents){su.SayHi();}}步驟3 雙擊“刪除泛型集合〞按鈕,在其單擊事件中添加如下代碼:步驟4 按【Ctrl+F5】鍵運(yùn)行程序。C#程序設(shè)計(jì)工程教程Teachernie=newTe42C#程序設(shè)計(jì)工程教程任務(wù)實(shí)施2——Dictionary<TKey,TValue>泛型集合應(yīng)用任務(wù)說(shuō)明本案例利用泛型集合Dictionary的知識(shí)輸出學(xué)生相關(guān)信息,案例實(shí)現(xiàn)的最終效果是單擊“泛型集合Dictionary<TKey,TValue>〞按鈕,將順序顯示學(xué)生的相關(guān)信息。程序運(yùn)行結(jié)果如以下圖所示。C#程序設(shè)計(jì)工程教程任務(wù)實(shí)施2——Dictionary<TK43C#程序設(shè)計(jì)工程教程實(shí)施步驟步驟1 翻開“任務(wù)實(shí)施1〞中的MySchool應(yīng)用程序,向窗體Form1中添加一個(gè)Button按鈕,并將其Text值修改為“泛型集合Dictionary<TKey,TValue>〞,name值修改為“btnList〞。雙擊該按鈕,為其單擊事件添加如下代碼:privatevoidbtnDictionary_Click(objectsender,EventArgse){//定義一個(gè)Dictionary泛型集合stusDictionary<String,Student>stus=newDictionary<string,Student>();Studentzhang=newStudent("張三",20);Studentli=newStudent("李四",19);Studentwang=newStudent("王五",20);Teachernie=newTeacher("聶樹成",4);#region添加元素演示stus.Add(zhang.Name,zhang);stus.Add(li.Name,li);stus.Add(wang.Name,wang);//stus.Add(nie.Name,nie); //假設(shè)添加教師信息,編譯時(shí)立即報(bào)錯(cuò)C#程序設(shè)計(jì)工程教程實(shí)施步驟步驟1 翻開“任務(wù)實(shí)施1〞中44C#程序設(shè)計(jì)工程教程//打印集合數(shù)目MessageBox.Show(string.Format("共包括{0}個(gè)學(xué)員。",stus.Count.ToString()));#endregion#region存取單個(gè)元素演示Studentstu2=stus["張三"];stu2.SayHi();#endregion#region元素遍歷演示foreach(Studentstudentinstus.Values){student.SayHi();}#endregion#region刪除元素演示//打印集合數(shù)目MessageBox.Show(string.Format("共包括{0}個(gè)學(xué)員。",stus.Count.ToString()));stus.Remove("張三");//打印集合數(shù)目MessageBox.Show(string.Format("共包括{0}個(gè)學(xué)員。",stus.Count.ToString()));#endregion}步驟2 按【Ctrl+F5】鍵運(yùn)行程序。C#程序設(shè)計(jì)工程教程//打印集合數(shù)目步驟2 按【Ctrl45C#程序設(shè)計(jì)
工程教程計(jì)算機(jī)“十二五〞規(guī)劃教材工程十四C#程序設(shè)計(jì)
工程教程計(jì)算機(jī)“十二五〞規(guī)劃教材工程十四C#程序設(shè)計(jì)工程教程學(xué)習(xí)任務(wù)掌握泛型的概念以及泛型類和泛型方法的應(yīng)用。
了解泛型約束的概念和使用方法。掌握泛型集合的應(yīng)用。工程十四泛型——提高代碼重用的最好方法C#程序設(shè)計(jì)工程教程學(xué)習(xí)任務(wù)工程十四泛型——提高代碼重47C#程序設(shè)計(jì)工程教程任務(wù)安排任務(wù)一熟悉泛型根底知識(shí)任務(wù)二泛型約束任務(wù)三泛型集合類工程十四泛型——提高代碼重用的最好方法C#程序設(shè)計(jì)工程教程任務(wù)安排工程十四泛型——提高代碼重48C#程序設(shè)計(jì)工程教程任務(wù)一熟悉泛型根底知識(shí)任務(wù)說(shuō)明預(yù)備知識(shí)在本任務(wù)中我們先來(lái)學(xué)習(xí)泛型的根底知識(shí)。一、為什么要使用泛型泛型用一個(gè)通過(guò)的數(shù)據(jù)類型T來(lái)代替object,在類實(shí)例化時(shí)指定T的類型,運(yùn)行時(shí)〔Runtime〕自動(dòng)編譯為本地代碼,運(yùn)行效率和代碼質(zhì)量都有很大提高,并且保證數(shù)據(jù)類型平安。使用泛型來(lái)定義棧publicclassStack<T>{privateT[]m_item;publicTPop(){...}publicvoidPush(Titem){...}publicStack(inti){this.m_item=newT[i];}}C#程序設(shè)計(jì)工程教程任務(wù)一熟悉泛型根底知識(shí)任務(wù)說(shuō)明預(yù)備知49C#程序設(shè)計(jì)工程教程在實(shí)例化時(shí)用一個(gè)實(shí)際的類型來(lái)代替數(shù)據(jù)類型T,如下所示:Stack<int>a=newStack<int>(100);//實(shí)例化只能保存int類型的類a.Push(10);//a.Push("8888"); //這一行編譯不通過(guò),因?yàn)轭恆只接收int類型的數(shù)據(jù)intx=a.Pop();Stack<string>b=newStack<string>(100);//實(shí)例化只能保存string類型的類//b.Push(10); //這一行編譯不通過(guò),因?yàn)轭恇只接收string類型的數(shù)據(jù)b.Push("8888");stringy=b.Pop();泛型類有如下優(yōu)點(diǎn):①類型平安②無(wú)需裝箱和折箱③無(wú)需類型轉(zhuǎn)換C#程序設(shè)計(jì)工程教程在實(shí)例化時(shí)用一個(gè)實(shí)際的類型來(lái)代替數(shù)據(jù)類型50C#程序設(shè)計(jì)工程教程二、泛型類與泛型方法〔一〕泛型類聲明泛型類的語(yǔ)法格式如下:類修飾符Class類名<T>:基類/接口{//相關(guān)代碼}泛型類可以在其定義中包含多個(gè)泛型類型,用逗號(hào)分隔開,例如:PublicClassMyGenericClass<T1,T2,T3>{//……}定義這些類型之后,可以將它們用作成員變量的類型、屬性或方法成員的返回類型等。另外,在泛型類中也可以使用普通數(shù)據(jù)類型,可以包含非泛型方法。C#程序設(shè)計(jì)工程教程二、泛型類與泛型方法〔一〕泛型類聲明泛型51C#程序設(shè)計(jì)工程教程C#在編譯泛型類時(shí),先生成中間代碼〔IL〕,通用類型T只是一個(gè)占位符。在實(shí)例化類時(shí),根據(jù)用戶指定的數(shù)據(jù)類型代替T并由即時(shí)編譯器〔JIT〕生本錢地代碼,這個(gè)本地代碼中已經(jīng)使用了實(shí)際的數(shù)據(jù)類型,等同于用實(shí)際類型寫的類,所以不同的封閉類〔這里封閉類是指由相同數(shù)據(jù)類型參數(shù)實(shí)例化的類〕的本地代碼是不一樣的。例如:Stack<int>和Stack<string>是兩個(gè)完全沒有任何關(guān)系的封閉類,你可以將它們看成類A和類B。C#程序設(shè)計(jì)工程教程C#在編譯泛型類時(shí),先生成中間52C#程序設(shè)計(jì)工程教程〔二〕泛型方法除了方法之外,其他的類成員如字段、屬性和方法等不能有自定義的泛型類型。聲明泛型方法的格式如下:修飾符返回類型方法名<泛型類型形參表>(形參表);{//其它語(yǔ)句}下面我們來(lái)看一段應(yīng)用泛型方法的代碼:publicclassStack2{publicvoidPush<T>(Stack<T>s,paramsT[]p){foreach(Ttinp){s.Push(t);}}}C#程序設(shè)計(jì)工程教程〔二〕泛型方法除了方法之外,其他53C#程序設(shè)計(jì)工程教程Stack2類可以一次將多個(gè)數(shù)據(jù)壓入Stack中。其中Push是一個(gè)泛型方法,調(diào)用這個(gè)方法的例如如下:Stack<int>x=newStack<int>(100);Stack2x2=newStack2();x2.Push(x,1,2,3,4,6);strings="";for(inti=0;i<5;i++){s+=x.Pop().ToString();} //至此,s的值為64321C#程序設(shè)計(jì)工程教程Stack2類可以一次將多個(gè)數(shù)據(jù)54C#程序設(shè)計(jì)工程教程〔三〕泛型中的靜態(tài)成員變量在泛型類中,靜態(tài)成員變量在相同封閉類間共享,不同的封閉類間不共享。例如:Stack<int>a=newStack<int>();Stack<int>b=newStack<int>();Stack<long>c=newStack<long>();類實(shí)例a和b是同一類型,他們之間共享靜態(tài)成員變量;但類實(shí)例c卻和a、b是完全不同的類型,所以不能和a、b共享靜態(tài)成員變量。C#程序設(shè)計(jì)工程教程〔三〕泛型中的靜態(tài)成員變量在泛型55C#程序設(shè)計(jì)工程教程〔四〕泛型類中的靜態(tài)構(gòu)造函數(shù)靜態(tài)構(gòu)造函數(shù)只能有一個(gè),且不能有參數(shù),且只能在.NET運(yùn)行時(shí)自動(dòng)被調(diào)用,不能人工調(diào)用。我們把泛型中的不同的封閉類理解為不同的類,那么泛型中的靜態(tài)構(gòu)造函數(shù)的原理和非泛型類是一樣的。靜態(tài)的構(gòu)造函數(shù)只在以下兩種情況被激發(fā):①特定的封閉類第一次被實(shí)例化。②特定封閉類中任一靜態(tài)成員變量被調(diào)用。C#程序設(shè)計(jì)工程教程〔四〕泛型類中的靜態(tài)構(gòu)造函數(shù)靜態(tài)構(gòu)56C#程序設(shè)計(jì)工程教程〔五〕泛型類中的方法重載通過(guò)一個(gè)例子來(lái)進(jìn)行學(xué)習(xí):publicclassNode<T,V>{
publicTadd(Ta,Vb)//第一個(gè)add
{
returna;
}
publicTadd(Va,Tb)//第二個(gè)add
{
returnb;
}
publicintadd(inta,intb)//第三個(gè)add
{
returna+b;
}}當(dāng)使用下面的調(diào)用代碼時(shí)Node<string,int>node=newNode<string,int>();objectx=node.add(2,"11");這兩行調(diào)用代碼可正確編譯,因?yàn)閭魅氲膕tring和int,使三個(gè)add方法具有不同的簽名,當(dāng)然能找到唯一匹配的add方法。但如果T和V都傳入int類型,三個(gè)add方法將具有同樣的簽名,請(qǐng)看下面代碼:Node<int,int>node=newNode<int,int>();objectx=node.add(2,11);此時(shí),這個(gè)類仍然能通過(guò)編譯,且能調(diào)用成功。因?yàn)橄到y(tǒng)會(huì)優(yōu)先匹配了第三個(gè)add方法。如果刪除了第三個(gè)add,上面的調(diào)用代碼那么無(wú)法編譯通過(guò),提示方法產(chǎn)生混淆無(wú)法在第一個(gè)add和第二個(gè)add之間選擇。C#的泛型是在實(shí)例的方法被調(diào)用時(shí)檢查重載是否產(chǎn)生混淆,而不是在泛型類本身編譯時(shí)檢查;當(dāng)一般方法與泛型方法具有相同的簽名時(shí),會(huì)覆蓋泛型方法。C#程序設(shè)計(jì)工程教程〔五〕泛型類中的方法重載通過(guò)一個(gè)例子來(lái)進(jìn)57C#程序設(shè)計(jì)工程教程任務(wù)實(shí)施——利用泛型類顯示信息任務(wù)說(shuō)明本案例主要完成的是通過(guò)下拉列表的ValueMember字段隱藏一些數(shù)據(jù)。數(shù)據(jù)類型只有在運(yùn)行時(shí)才知道,即可能是根本數(shù)據(jù)類型,也可能是類類型,需要用泛型類實(shí)現(xiàn)這個(gè)功能。實(shí)施步驟步驟1 創(chuàng)立一個(gè)Windows窗體應(yīng)用程序,將其命名為MySchool。向Form1窗體中添加一個(gè)Button控件,修改其Text值為“泛型類〞。然后向該工程中添加一個(gè)窗體,將其命名為FrmGenericClass,修改其Text值為“泛型類〞,并在此窗體中添加2個(gè)Label控件和2個(gè)ComboBox控件,并設(shè)置label1、label2的Text值分別為“學(xué)生集合〞、“教師集合〞。修改Form1窗體中Button控件的name值為“btnGenericClass〞,雙擊該按鈕添加其click事件代碼,如下所示:privatevoidbtnGenericClass_Click(objectsender,EventArgse) //調(diào)用泛型類窗體{
FrmGenericClassfrm=newFrmGenericClass();frm.Show();}C#程序設(shè)計(jì)工程教程任務(wù)實(shí)施——利用泛型類顯示信息任務(wù)說(shuō)明58C#程序設(shè)計(jì)工程教程步驟2 在應(yīng)用程序下添加Student類,完整代碼如下:namespaceMySchool{publicclassStudent{publicStudent():this("張三",20){}publicStudent(stringname,intage){this.Name=name;this.Age=age;}privatestringname;publicstringName{get{returnname;}set{name=value;}}privateintage;publicintAge{get{returnage;}set{if(value>0&&value<100){age=value;}else{age=18;}}}publicvoidSayHi()(“大家好,我是{0}同學(xué),今年{1}歲了“,,this.age);MessageBox.Show(message);}}}C#程序設(shè)計(jì)工程教程步驟2 在應(yīng)用程序下添加Studen59C#程序設(shè)計(jì)工程教程步驟3 在應(yīng)用程序下添加Teacher類,完整代碼如下:namespaceMySchool{publicclassTeacher{publicTeacher(stringname):this(name,2,5000){}publicTeacher(stringname,intservingYears):this(name,servingYears,5000){}publicTeacher(stringname,intservingYears,intsalary){=name;this.servingYears=servingYears;this.salary=salary;}privatestringname;publicstringName{get{returnname;}set{name=value;}}C#程序設(shè)計(jì)工程教程步驟3 在應(yīng)用程序下添加Teache60C#程序設(shè)計(jì)工程教程privateintsalary;publicintSalary{get{returnsalary;}set{salary=value;}}privateintservingYears;publicintServingYears{get{returnservingYears;}set{servingYears=value;}}publicvoidSayHi(){stringmessage=string.Format("大家好,我是{0}老師。我已經(jīng)在教育戰(zhàn)線奮斗了{(lán)1}年了!",,this.servingYears);MessageBox.Show(message);}}}C#程序設(shè)計(jì)工程教程privateintsala61C#程序設(shè)計(jì)工程教程步驟4 該工程中添加一個(gè)類文件,為其添加泛型類ComboBoxItem,詳細(xì)代碼如下所示:namespaceMySchool{//定義泛型類publicclassComboBoxItem<T>{privatestringitemText;publicstringItemText{get{returnitemText;}set{itemText=value;}}privateTitemValue;publicTItemValue{get{returnitemValue;}set{itemValue=value;}}}}C#程序設(shè)計(jì)工程教程步驟4 該工程中添加一個(gè)類文件,為其62C#程序設(shè)計(jì)工程教程步驟5 在FrmGenericClass窗體的Load事件中添加代碼如下:privatevoidFrmGenericClass_Load(objectsender,EventArgse){Studentzhang=newStudent("張三",20);Studentli=newStudent("李四",19);Studentwang=newStudent("王五",20);Teachernie=newTeacher("聶樹成",4);Teachertian=newTeacher("田天",2);//創(chuàng)立Combox項(xiàng),運(yùn)行時(shí)確定泛型類支持的數(shù)據(jù)類型ComboBoxItem<Student>itemzhang=newComboBoxItem<Student>();itemzhang.ItemText=zhang.Name;itemzhang.ItemValue=zhang;ComboBoxItem<Student>itemli=newComboBoxItem<Student>();itemli.ItemText=li.Name;itemli.ItemValue=li;ComboBoxItem<Student>itemwang=newComboBoxItem<Student>();itemwang.ItemText=wang.Name;itemwang.ItemValue=wang;C#程序設(shè)計(jì)工程教程步驟5 在FrmGenericCla63C#程序設(shè)計(jì)工程教程//創(chuàng)立支持學(xué)生類型的Items集合List<ComboBoxItem<Student>>items=newList<ComboBoxItem<Student>>();items.Add(itemzhang);items.Add(itemli);items.Add(itemwang);//在cboStudents下拉列表框顯示學(xué)生cboStudents.DataSource=items;cboStudents.DisplayMember="ItemText";cboStudents.ValueMember="ItemValue";//創(chuàng)立支持教師類型的Combox項(xiàng)ComboBoxItem<Teacher>itemtian=newComboBoxItem<Teacher>();itemtian.ItemText=tian.Name;itemtian.ItemValue=tian;ComboBoxItem<Teacher>itemnie=newComboBoxItem<Teacher>();itemnie.ItemText=nie.Name;itemnie.ItemValue=nie;//創(chuàng)立Items集合,支持教師類型List<ComboBoxItem<Teacher>>itemsT=newList<ComboBoxItem<Teacher>>();itemsT.Add(itemtian);itemsT.Add(itemnie);C#程序設(shè)計(jì)工程教程//創(chuàng)立支持學(xué)生類型的Items集合64C#程序設(shè)計(jì)工程教程//在cboTeachers下拉列表框顯示教師this.cboTeachers.DataSource=itemsT;cboTeachers.DisplayMember="ItemText";cboTeachers.ValueMember="ItemValue";}privatevoidcboStudents_SelectedIndexChanged(objectsender,EventArgse){if(cboStudents.SelectedIndex>0){Studentstu=(Student)cboStudents.SelectedValue;stu.SayHi();}}privatevoidcboTeachers_SelectedIndexChanged(objectsender,EventArgse){if(cboTeachers.SelectedIndex>0){TeacherTea=(Teacher)cboTeachers.SelectedValue;Tea.SayHi();}}C#程序設(shè)計(jì)工程教程//在cboTeachers下拉列表框顯65C#程序設(shè)計(jì)工程教程步驟6 按【Ctrl+F5】鍵程序運(yùn)行,在彈出的對(duì)話框中單擊“泛型類〞按鈕,將彈出“泛型類〞對(duì)話框,在此對(duì)話框中選擇不同的值,系統(tǒng)將彈出不同的信息提示,如以下圖所示。C#程序設(shè)計(jì)工程教程步驟6 按【Ctrl+F5】鍵程序運(yùn)66C#程序設(shè)計(jì)工程教程任務(wù)二
泛型約束任務(wù)說(shuō)明在定義泛型類時(shí),我們可以對(duì)用戶實(shí)例化類時(shí)所使用的類型參數(shù)的種類施加限制,如果用戶嘗試使用某個(gè)約束所不允許的類型來(lái)實(shí)例化類,那么會(huì)產(chǎn)生編譯錯(cuò)誤。在C#中這些限制就稱為約束,本節(jié)我們就來(lái)學(xué)習(xí)與此相關(guān)的知識(shí)。預(yù)備知識(shí)約束的方式是指定T的祖先,即繼承的接口或類。因?yàn)镃#的單根繼承性,所以約束可以有多個(gè)接口,但最多只能有一個(gè)類,并且類必須在接口之前。定義約束需要使用關(guān)鍵字where,如下所示:publicclassNode<T,V>whereT:Stack,IComparablewhereV:Stack{//...}T必須是從Stack和IComparable繼承的類型,V必須是Stack類型或從Stack繼承的類型,否那么將無(wú)法通過(guò)編譯器的類型檢查。C#程序設(shè)計(jì)工程教程任務(wù)二泛型約束任務(wù)說(shuō)明在定義泛67C#程序設(shè)計(jì)工程教程下面我們來(lái)看幾種常見的約束:〔1〕結(jié)構(gòu)約束結(jié)構(gòu)約束的格式如下:T〔類型〕:struct表示類型參數(shù)必須是值類型?!?〕類約束T〔類型〕:class表示類型參數(shù)必須是引用類型,包括任何類、接口、委托或數(shù)組類型。publicstructA{}publicclassB{}classC<T>whereT:struct{//T是一個(gè)值類型}C<A>c=newC<A>();//正確,A是一個(gè)值類型C<B>c=newC<B>();//錯(cuò)誤,B是一個(gè)引用類型C#程序設(shè)計(jì)工程教程下面我們來(lái)看幾種常見的約束:〔1〕結(jié)構(gòu)約68C#程序設(shè)計(jì)工程教程〔3〕新建約束T〔類型〕:new()表示類型參數(shù)必須具有無(wú)參數(shù)的公共構(gòu)造方法。當(dāng)與其他約束一起使用時(shí),new()約束必須最后指定。例如:classA{publicvoidA(){}}classB{publicvoidB(inti){}}classC<T>whereT:new(){Tt=newT();}C<A>c=newC<A>();//正確,A有無(wú)參構(gòu)造方法C<B>c=newC<B>();//錯(cuò)誤,B沒有無(wú)參構(gòu)造方法C#程序設(shè)計(jì)工程教程〔3〕新建約束T〔類型〕:new()69C#程序設(shè)計(jì)工程教程〔4〕基類約束T〔類型〕:<基類名>用來(lái)限制參數(shù)類型從特定的類中派生,例如:classA{publicvoidF1(){}}classB{publicvoidF2(){}}classC<S,T>whereS:AwhereT:B{//可以在類型為S的變量上調(diào)用F1//可以在類型為T的變量上調(diào)用F2}C#程序設(shè)計(jì)工程教程〔4〕基類約束T〔類型〕:<基類名>用來(lái)70C#程序設(shè)計(jì)工程教程〔5〕接口約束T〔類型〕:<接口名>表示類型參數(shù)必須是指定的接口或?qū)崿F(xiàn)指定的接口??梢灾付ǘ鄠€(gè)接口約束。約束接口也可以是泛型的。例如:interfaceIPrintable{voidPrint();}interfaceIComparable<T>{intComparableTo(Tv);}interface
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年度綠色出行解決方案民間擔(dān)保借款合同4篇
- 男方協(xié)議離婚書2025年度電子版制作與版權(quán)保護(hù)合同3篇
- 二零二五年度智能電網(wǎng)設(shè)備研發(fā)與銷售合同范本4篇
- 二零二五版內(nèi)資股協(xié)議轉(zhuǎn)讓知識(shí)產(chǎn)權(quán)保護(hù)合同4篇
- 二零二五年度爬架租賃與施工現(xiàn)場(chǎng)環(huán)境保護(hù)合同2篇
- 2025年度城市公園綠地日常養(yǎng)護(hù)維修服務(wù)合同規(guī)范3篇
- 二零二五年度名筑印象住宅電梯品牌代理銷售合同4篇
- 二零二五年內(nèi)蒙古文化旅游融合發(fā)展合同規(guī)范4篇
- 2025年度瓷磚鋪貼與新型建筑材料研發(fā)合同4篇
- 二零二五年度山莊生態(tài)旅游合作開發(fā)合同范本2篇
- 二零二五年度無(wú)人駕駛車輛測(cè)試合同免責(zé)協(xié)議書
- 2025年湖北華中科技大學(xué)招聘實(shí)驗(yàn)技術(shù)人員52名歷年高頻重點(diǎn)提升(共500題)附帶答案詳解
- 黑龍江省哈爾濱市2024屆中考數(shù)學(xué)試卷(含答案)
- 高三日語(yǔ)一輪復(fù)習(xí)助詞「と」的用法課件
- 毛渣采購(gòu)合同范例
- 無(wú)子女離婚協(xié)議書范文百度網(wǎng)盤
- 2023中華護(hù)理學(xué)會(huì)團(tuán)體標(biāo)準(zhǔn)-注射相關(guān)感染預(yù)防與控制
- 五年級(jí)上冊(cè)小數(shù)遞等式計(jì)算200道及答案
- 2024年廣東高考政治真題考點(diǎn)分布匯 總- 高考政治一輪復(fù)習(xí)
- 燃?xì)夤艿滥甓葯z驗(yàn)報(bào)告
- GB/T 44052-2024液壓傳動(dòng)過(guò)濾器性能特性的標(biāo)識(shí)
評(píng)論
0/150
提交評(píng)論