<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                原文鏈接:https://blog.csdn.net/khqxf/article/details/88554247 有了泛型,可減少object對象的使用,對object進行裝箱/拆箱時,性能不及泛型 1. 允許多種類型共享一組代碼。在聲明泛型時,給出類型參數,然后用不同類型創建實例。也就是在事先使用類型占位符,在實例化時才指出真實類型。 2. **泛型五種類型**:類、接口、結構、委托和方法。泛型是類型的模板,而類型是對象的模板。 3. 利用泛型實現棧的操作: ``` //泛型的基本用法 using System; namespace test28 { class Program { //利用泛型實現棧的操作 class Myclass<T> //聲明泛型,T,S為類型占位符 { T[] StackArray; int StackPointer = 0; public void Push(T x) { if(!IsStackFull) StackArray[StackPointer++] = x; } public T Pop() { return (!IsStackEmpty)?StackArray[--StackPointer]:StackArray[0]; } const int MaxStack = 10; bool IsStackFull {get{return StackPointer >= MaxStack;}} bool IsStackEmpty {get{return StackPointer <= 0;}} public Myclass() { StackArray = new T[MaxStack]; } public void Print() { for(int i = StackPointer -1;i>=0;i--) { Console.WriteLine(" Info:{0}",StackArray[i]); } } } static void Main(string[] args) { Myclass<int> StackInt = new Myclass<int>(); Myclass<string> StackString = new Myclass<string>(); StackInt.Push(6); StackInt.Push(8); StackInt.Push(10); StackInt.Print(); StackString.Push("加油!2019!"); StackString.Push("自動化1401班!"); StackString.Print(); } } } ``` **類型參數的約束**:使用where子句對類型參數進行約束,where子句之間沒有標點符號,如果某個類型參數有多個約束,在每一個where子句中用逗號間隔。`where TypeParams:constraint,constraint,...`示例如下 ``` class Myclass<T1,T2> where T1:Custom where T2:IComparable { ... } ``` 5 約束類型和次序 類名:只有這個類型的類或者從它繼承的類才能用作類型實參 class:任何引用類型,包括類、數組、委托和接口都可以用作類型實參。 struct:任何值類型都可以用作類型實參。 接口名:只有這個接口或者實現這個接口的類型才可以用作類型實參。 new():任何帶有無參公共構造函數的類型都可以用作類型實參,即為構造函數約束。 6 where子句的約束必須有一定的順序,最多只能有一個主約束;可以有任意多的接口名約束;如果存在構造函數約束,則必須放在最后。 ``` class SortedList<S> where S:IComparable<S>{....} class LinkedList<M,N> where M:IComparable<M> where N:IComparable{....} class MyDictionary<KeyType,ValueType> where Keytype:IEnumerable, new() {...} ``` 7、泛型方法:它有兩個參數列表,位于圓括號里的方法參數列表,位于尖括號里的類型參數列表。要聲明泛型方法,要在方法名之后一次是類型參數列表和方法列表,在方法參數列表后是可選的約束子句 ``` public void PrintData<S,T>(S p,T t) where S:Person { ... } ``` 8 調用泛型方法: 在方法調用時提供類型實參,Mymethod<short,int>();Mymethod<int,long>();當然,這里也可用推斷類型,倘若方法參數列表的類型已知,編輯器可以推斷出類型參數列表的情況,這是就可以將類型參數列表給忽略,int myint = 5;Mymethod<int>(myint);可簡寫為Mymethod(myint); 泛型方法示例 ``` class Simple //非泛型類 { static public void ReverseAndPrint<T>(T[] arr) //泛型方法 { Array.Reverse(arr); foreach(T item in arr) { Console.WriteLine("{0},",item.ToString()); } Console.WriteLine(" "); } } class Program { static void Main() { //創建各種類型的數組 var intArray = new int[]{3,5,7,9}; var stringArray = new string[]{"first","second","third"}; var doubleArray = new double[]{3.456,4.567,5.678}; Simple.ReverseAndPrint<int>(intArray); //調用方法 Simple.ReverseAndPrint(intArray); //推斷引用 Simple.ReverseAndPrint<string>(stringArray); //調用方法 Simple.ReverseAndPrint(intArray); //推斷引用 Simple.ReverseAndPrint<double>(doubleArray); //調用方法 Simple.ReverseAndPrint(doubleArray); //推斷引用 } } ``` 擴展方法和泛型類:將泛型類與擴展方法結合,允許我們將類中的靜態方法關聯到不同的泛型上,還可以像調用類結構實例那樣調用方法。泛型類的擴展方法必須聲明為static;必須是靜態類的成員;第一個參數類型必須為this,后面是擴展的泛型類的名稱,示例如下: ``` //擴展方法和泛型類 using System; namespace test30 { static class ExtendHoleder { public static void Print<T>(this Holder<T> h) { T[] vals = h.GetValues(); Console.WriteLine("{0},\t{1},\t{2}",vals[0],vals[1],vals[2]); } } class Holder<T> { T[] vals = new T[3]; public Holder(T t0,T t1,T t2) {vals[0]=t0;vals[1]=t1;vals[2]=t2;} public T[] GetValues(){return vals;} } class Program { static void Main(string[] args) { var intHolder = new Holder<int>(3,5,7); var stringHolder = new Holder<string>("a1","b2","c3"); intHolder.Print(); stringHolder.Print(); } } } ``` 泛型結構:與泛型類相似,泛型結構可以有類型參數和約束。泛型結構的規則和條件與泛型類是一樣的。示例如下 ``` //泛型結構 using System; namespace test31 { struct PieceOfData<T> { public PieceOfData(T value){_data = value;} private T _data; public T Data { get{return _data;} set{_data = value;} } } class Program { static void Main(string[] args) { var intData = new PieceOfData<int>(16); var stringData = new PieceOfData<string>("hi nihao!"); Console.WriteLine("intData ={0}",intData.Data); Console.WriteLine("stringData ={0}",stringData.Data); } } } ``` 泛型委托:泛型委托與非泛型委托相似,只是類型參數決定了能接受什么樣的方法。要聲明泛型委托,在委托名之后要有類型參數列表和委托參數列表;類型參數包括返回值、形參列表和約束子句。示例如下,泛型委托與泛型類。 ``` //泛型委托的簡單示例 using System; namespace test32 { delegate T PrintT<T>(T t); //聲明泛型委托,返回類型和參數列表類型都是T public class Myclass<T> //聲明泛型類 { public T Method(T t) //方法的參數和返回類型與委托匹配 { return t; } } class Program { static void Main(string[] args) { Myclass<string> mycl = new Myclass<string>(); PrintT<string> prt = new PrintT<string>(mycl.Method); //等價于PrintT<string> prt = mycl.Method; 創建委托對象并賦值給委托變量 Console.WriteLine(prt("越努力越幸運,加油,自動化1401班!")); //執行委托 } } } ``` 泛型委托示例二,注意,此示例是泛型委托和非泛型類的使用。 ``` //泛型委托示例二 using System; namespace test33 { delegate T3 SumNum<T1,T2,T3>(T1 t1,T2 t2); //聲明泛型委托,返回類型為T3,類型參數為T1,T2,T3,委托參數為T1,T2 public class Myclass //聲明非泛型類 { private int _data; public string Method(int t1,int t2) //泛型方法的參數與返回類型與委托匹配 { _data = t1 + t2; return _data.ToString(); } } class Program { static void Main(string[] args) { Myclass mycl = new Myclass(); SumNum<int,int,string> sumn = new SumNum<int,int,string>(mycl.Method); //創建委托對象并賦值給委托變量 Console.WriteLine(sumn(4,5)); //執行委托 } } } ``` 泛型接口:泛型接口的類型參數決定了接口成員的參數類型和返回類型。在接口名后跟類型參數;泛型接口既可以在泛型類中實現也可以在非泛型類中實現;實現不同類型參數的泛型接口是不同的接口;泛型接口的實現必須唯一,不能重復實現相同的接口。 泛型接口示例: ``` //泛型接口示例一 using System; namespace test34 { class Program { public interface Multify<T> //聲明泛型接口 {T Mulfy(T t);} public class Myclass<T>: Multify<T> //在泛型類中實現泛型接口 { public T Mulfy(T t) { return t; } } static void Main(string[] args) { Myclass<int> mycl = new Myclass<int>(); Console.WriteLine(mycl.Mulfy(16)); } } } ``` 代碼過于簡單,只是為了演示,結果是16 協變與逆變:協變允許將派生類的委托對象賦值給基類變量,逆變則與之相反;當然協變和逆變都可用于接口;協變的(委托或接口)類型參數必須聲明為輸出參數(關鍵字out),逆變的類型參數必須聲明為輸入參數(關鍵字in),在實現委托方法時,如果是協變,則方法的參數傳入派生類的引用,實現派生類的方法;如果是逆變,傳入基類的引用,實現基類的成員;協變的委托沒有委托參數,逆變的委托有委托參數。 委托的協變和逆變示例: ``` using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace test35 { class Myclass //聲明基類 { public string[] color = {"red","blue","yellow","orange","green"}; } class Myderived : Myclass {} //聲明派生類 class Program { delegate void Mydele<out T>(); //聲明泛型委托,協變時不能有委托參數,類型參數有out修飾 delegate void Mydele1<in T>(T t); //聲明泛型委托,逆變時有委托參數,類型參數有in修飾 public static void Method() //協變,方法要與委托Mydele相匹配,在方法中實現派生類 { Myderived mydr = new Myderived(); Array.Reverse(mydr.color); //將數組倒序排列 foreach(string item in mydr.color) { Console.WriteLine(item); } } public static void Method1(Myclass mycl) //逆變,要與委托Mydele1相匹配,傳入基類的引用,實現基類的成員 { foreach(string item in mycl.color) { Console.WriteLine(item); } } static void Main(string[] args) { Console.WriteLine("................協變................"); Mydele<Myderived> mydel = Method; //創建委托對象 Mydele<Myclass> mycl = mydel; //協變時,將派生類的委托對象賦值給基類的委托變量是可行的 mycl(); //執行委托 Console.WriteLine("................逆變................"); Mydele1<Myclass> mycll = Method1; //創建委托對象 Mydele1<Myderived> mydell = mycll; //逆變時,將基類的委托對象賦值給派生類的委托變量是可行的 mydell(new Myderived()); //執行委托,傳入派生類的對象 } } } ``` 19. 接口的協變示例: ``` using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace test36 { //接口的協變 class Animal{public string Name;} //聲明基類 class Dog:Animal{}; //聲明派生類 interface IMyIfc<out T> //聲明泛型接口 { T GetFirst(); } class SimpleReturn<T>:IMyIfc<T> //聲明泛型類,實現泛型接口 { public T[] items = new T[2]; public T GetFirst(){return items[0];} } class Program { static void DoSomething(IMyIfc<Animal> returner) //傳入接口的引用 { Console.WriteLine(returner.GetFirst().Name); } static void Main(string[] args) { SimpleReturn<Dog> dogReturner = new SimpleReturn<Dog>(); dogReturner.items[0] = new Dog(){Name = "WorkHarding"}; IMyIfc<Animal> animalReturner = dogReturner; DoSomething(dogReturner); } } } ``` 接口的逆變示例: ``` using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace test37 { //接口的逆變 class Mybase { public string[] str = {"red","orange","yellow","green","blue","violet"}; } class Myderived : Mybase{} interface IMyIfc<in T> //定義泛型接口,并且接口沒有返回類型 { string GetFirst(); } class MyColor<T>:IMyIfc<T> //在泛型類中實現接口 { public string[] Color = new string[6] ; public string GetFirst() { Myderived mydr = new Myderived(); for(int i = 0;i<6;i++) { Color[i] = mydr.str[i]; } return Color[0]; } } class Program { public static void Choice(IMyIfc<Myderived> t) //傳入接口的引用 { Console.WriteLine(t.GetFirst()); } static void Main(string[] args) { MyColor<Mybase> myco = new MyColor<Mybase>(); IMyIfc<Myderived> t = myco; Choice(myco); } } } ```
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看