C#泛型集合類System.Collections.Generic
一、定義泛型類
void Main() { //實例化泛型類時,才指定具體的類型 MyGenericClass<int> MyGeneri = new MyGenericClass<int>(5); Console.WriteLine(MyGeneri.InnerT1Object * 2); } public class MyGenericClass<T>//<T1,T2,T3>表示多個類型參數(shù) { private T innerT1Object; public string LastName; public MyGenericClass(T item)//構(gòu)造函數(shù) { this.innerT1Object = item; } public T InnerT1Object//泛型屬性 { get { return innerT1Object; } } }
注意:
1、不能假定T提供了什么類型。
eg:innerT1Object=new T(),因為T可能根本無公共默認構(gòu)造函數(shù)。除非 class MyGenericClass<T> where T:new()
public class MyGenericClass<T> where T : new() { private T innerT1Object = new T(); }
2、可以把T看作繼承System.Object的類型:typeof(T),T.ToString()
3、在沒有指定約束類型參數(shù)的情況下,比較泛型類型值和null,只能使用==或!=。
不能對兩個類型值變量進行比較。
public bool Compare(T op1, T op2) { if (op1 != null && op2 == null)//正確。如果T為值類型,op1!=null始終成立。 { //… } if (op1 == op2)//錯誤,因為這就假定了T支持==運算符 { //… } }
4、default關(guān)鍵字用于為T賦默認值,而無需考慮其實值類型還是引用類型。
public class MyGenericClass<T> { private T innerT1Object = default(T); }
5、where 關(guān)鍵字用于約束T的類型。
class MyGenericClass<T> where T:Animal
可用的約束有:
- struct :值類型
- class:引用類型
- <baseclass>:此列或者此類的派生類
- <interface>:此接口或者實現(xiàn)此接口
- new():必須具有無參數(shù)的公共構(gòu)造函數(shù)。必須為類型的最后得約束。
- 一個類型參數(shù)可有多個約束:class Myclass<T> where T: constait1,constrait2
- 各類型參數(shù)不同的約束:class Myclass<T1,T2> where T1: constait1,T2:constrait2
- 約束放于繼承符之后:class Myclass<T1>:MyBaseCalss,IMyInterface where T: constait
- 一個類型參數(shù)用作另一個類型參數(shù)的約束,表示T2與T1的類型相同,或T2繼承于T1(裸類型約束)class Myclass<T1,T2> where T2: T1
6、泛型類的靜態(tài)成員只能在類的一個實例中共享:
void Main() { StaticDemo<string>.x=4; StaticDemo<int>.x=5; } public class StaticDemo<T> { public static int x; }
二、從泛型類繼承
1、泛型類至少與基類有相同的約束,或為基類的子集
public class Farm<T> where T : Animal { //... } public class SuperFarm<T> : Farm<T> where T : SuperCow //SuperCow為Animal的子集 { //... }
2、類繼承泛型,必須提供所有的類型信息
public class Cards : List<Card> //派生非泛型 { }
三、定義泛型運算符
public static Farm<T> operator +(Farm<T> farm1, Farm<T> farm2) { }
四、定義泛型結(jié)構(gòu)
public struct MyStruct<T1, T2> { public T1 item1; public T2 item2; }
五、定義泛型接口
interface myInterface<T> where T : Animal { bool Brea(T animal1, T animal2); T oldest { get; } }
實例:
public interface IComparable<T> { int CompareTo(T other); } public class Person : IComparable<Person> { public int CompareTo(Person other) { return this.name.CompareTO(other.name); } }
六、定義泛型方法
1、普通類
public class Defaulter { public T GetDefault<T>() { return default(T); } }
2、泛型類
public class Defaulter<T1> { public T2 GetDefault<T2>() where T2 : T1 //泛型方法的參數(shù)最好不要與其所在的泛型類的類型參數(shù)相同 { return default(T2); } public void Process() { } public void Process<T>(T1 op1)//重載方法1 { } public void Process<T, U>(T1 op1)//重載方法2 { } }
七、定義泛型委托
1、通過泛型委托,委托的參數(shù)可以在以后定義。
public delegate T1 MyDelegate<T1, T2>(T2 op1, T2 op2) where T1 : T2;
2、常用內(nèi)置委托:
(1)、Action<T>: 泛型委托。無返回值。 委托的方法可以有1-16個輸入?yún)?shù)。Action:無參數(shù)無返回值委托。
Action action1 = () => Console.Write("a"); action1(); Action<string> action2 = (p) => Console.Write(p); action2("b");
利用Action實現(xiàn)線程和界面交互:
private void button1_Click(object sender, EventArgs e) { WaitCallback waitCallBack = new WaitCallback(this.AlternationUsingAction); ThreadPool.QueueUserWorkItem(waitCallBack, "Action的使用"); } private void AlternationUsingAction(object text) { this.Invoke((Action)( () => { button1.Text = text.ToString(); } )); }
(2)、Func<T>:必須具有返回值。委托的方法可以有0-16個參數(shù)輸入?yún)?shù),加一個輸出參數(shù)。
Func<int, int, string > Func = (a, b) => (a + b).ToString(); Console.Write(Func(1, 2));
(3)、Predicate<T>:就是只接受一個傳入?yún)?shù),返回值為bool類型。
用于搜索方法
public delegate bool Predicate<T>(T obj);//判斷條件函數(shù) public T Find(Predicate<T> matach);
舉例:
Predicate<string[]> predicate = x => { var result = from p in x where p.Contains("s") select p; return result.ToList().Count > 0; }; string[] _value = { "charlies", "nancy", "alex", "jimmy", "selina" }; Console.WriteLine(predicate(_value) ? "包含." : "不包含");
(4)、Comparision<T>(T obj1,T obj2):比較函數(shù),用于搜索方法。
public delegate int Comparision<T>(T obj1,T obj2)// public void Sort(Comparision<T> comprison)
(5)、EventHandler<TEventArgs>:泛型事件處理函數(shù)。
public delegate void EventHandler<TEventArgs>(object sender, TEventArgs e) where TEventArgs : EventArgs;
3、實例:
public delegate TSummary Action<TInput, TSummary>(TInput t, TSummary u);//定義泛型委托 public static TSummary Accumulate<TInput, TSummary>(IEnumerable <TInput> cols, Action<TInput, TSummary> action) //將委托實例action傳給方法參數(shù)。 { TSummary sum = default(TSummary); foreach (TInput input in cols) { sum = action(input, sum);//執(zhí)行委托方法 } return sum; } void Main() { decimal amount = Accumulate<int, decimal>(new List<int> { 1, 2 }, (a, b) => a + b);//(a, b) => a + b為委托實例 Console.Write(amount); }
八、定義泛型事件
事件與委托就像一對孿生兄弟。既然有泛型委托,那么也應(yīng)該有泛型事件。因為在以前,事件處理函數(shù)的發(fā)送方參數(shù)的類型總是Object。因此事件處理函數(shù)沒有辦法根據(jù)不同的發(fā)送者身份或者類型對事件進行不同的處理?,F(xiàn)在如果使用泛型事件就可以使用強類型的發(fā)送方,不再需要強制轉(zhuǎn)換成Object或反向強制轉(zhuǎn)換。而且也可以根據(jù)發(fā)送方類型的不同對消息進行不同的處理。
例子中演示了發(fā)送方是強類型的情況,在這個例子中使用泛型類Publisher<T>來表示消息的發(fā)布者,用類Receiver來表示消息的訂閱者。
//定義了一個泛型委托,該委托指定了發(fā)送者的具體類型 public delegate void MyEventHandler<T>(Publisher<T> Sender); void Main() { //事件發(fā)布者 Publisher<int> publisherI = new Publisher<int>(); Publisher<double> publisherD = new Publisher<double>(); //事件訂閱者 Receiver receiver = new Receiver(); //開始綁定事件 publisherI.Click += receiver.OnClick; publisherD.Click += receiver.OnClick; //引發(fā)事件 publisherI.SendMessage(); publisherD.SendMessage(); } //消息發(fā)布者類Publisher<T>的代碼 public class Publisher<T> { //定義了一個泛型事件,該事件的發(fā)布者的類型是強類型 public event MyEventHandler<T> Click; //發(fā)送事件函數(shù) public void SendMessage() { Click(this); } } //消息訂閱者類Receiver的代碼 class Receiver { //事件處理函數(shù),該函數(shù)具有強類型的參數(shù)表示發(fā)送者 public void OnClick(Publisher<int> sender) { Console.WriteLine("該事件已經(jīng)寫入日志文件"); } //事件處理函數(shù) public void OnClick(Publisher<double> sender) { Console.WriteLine("該事件已經(jīng)發(fā)送到主管信箱"); } }
九、可空類型System.Nullable<T>
1、聲明和賦值
Nullable<int> x = 4;//可寫成int? x = 4 x = null;//可為可空類型賦值null.
2、判斷為空
int y; if (x.HasValue)//或者x!=null { y = x = value; } else { y = x ?? 0;//或者 x.GetValueOrDefault(); x=null則或者其默認值。 }
3、轉(zhuǎn)換
int? op1=5; int? result=op1 *2; int? op2=5; int result1=op2 *2;//如果op2為null,強制轉(zhuǎn)換int?到int產(chǎn)生異常
十、ArraySegement<T> 數(shù)組片段
int[] arr = { 1, 2, 3, 4, 5, 6, 7, 8 }; ArraySegment<int> segment = new ArraySegment<int>(arr, 2, 3); for (int i = segment.Offset; i < segment.Offset + segment.Count; i++) { Console.WriteLine(segment.Array[i]); }
到此這篇關(guān)于C#泛型集合類System.Collections.Generic的文章就介紹到這了。希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Microsoft Expression Web 簡體中文正式版 官方下載地址
Microsoft Expression Web 簡體中文正式版 官方下載地址...2007-07-07程序中兩個Double類型相加出現(xiàn)誤差的解決辦法
本篇文章介紹了,程序中兩個Double類型相加出現(xiàn)誤差的解決辦法。需要的朋友參考下2013-04-04C#實體對象序列化成Json并讓字段的首字母小寫的兩種解決方法
這篇文章主要介紹了C#實體對象序列化成Json并讓字段的首字母小寫的兩種方法,在這兩種方法中小編比較推薦使用第二種方法,需要的朋友可以參考下2018-06-06Unity使用物理引擎實現(xiàn)多旋翼無人機的模擬飛行
這篇文章主要介紹了Unity使用物理引擎實現(xiàn)多旋翼無人機的模擬飛行,包括了詳細的原理介紹和代碼實現(xiàn),對物理引擎感興趣的同學(xué),可以參考下2021-04-04