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ā)送者身份或者類型對事件進行不同的處理。現(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的文章就介紹到這了。希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Microsoft Expression Web 簡體中文正式版 官方下載地址
Microsoft Expression Web 簡體中文正式版 官方下載地址...2007-07-07
程序中兩個Double類型相加出現(xiàn)誤差的解決辦法
本篇文章介紹了,程序中兩個Double類型相加出現(xiàn)誤差的解決辦法。需要的朋友參考下2013-04-04
C#實體對象序列化成Json并讓字段的首字母小寫的兩種解決方法
這篇文章主要介紹了C#實體對象序列化成Json并讓字段的首字母小寫的兩種方法,在這兩種方法中小編比較推薦使用第二種方法,需要的朋友可以參考下2018-06-06
Unity使用物理引擎實現(xiàn)多旋翼無人機的模擬飛行
這篇文章主要介紹了Unity使用物理引擎實現(xiàn)多旋翼無人機的模擬飛行,包括了詳細的原理介紹和代碼實現(xiàn),對物理引擎感興趣的同學,可以參考下2021-04-04

