集合
集合(Collection)類是專門用于數(shù)據(jù)存儲和檢索的類。
這些類提供了對棧(stack)讹语、隊列(queue)近范、列表(list)和哈希表(hash table)的支持澎现。
大多數(shù)集合類實現(xiàn)了相同的接口(IEnumerable)。
集合(Collection)類服務(wù)于不同的目的押赊,如為元素動態(tài)分配內(nèi)存饺藤,基于索引訪問列表項等等,在 C# 中流礁,Object 類是所有數(shù)據(jù)類型的基類涕俗。
集合--ArrayList
ArrayList:不定長度的,連續(xù)分配的神帅。
示例代碼:
//元素沒有類型限制再姑,任何元素都當(dāng)成object處理,如果是值類型會有裝箱操作
ArrayList arrayList = new ArrayList();
arrayList.Add("object");//可以放string
arrayList.Add(Enumerable.Range(1找御,100).ToArray());//可以放Array
Func<string询刹, int> func = m => 1;
arrayList.Add(func);//可以放Delegate
示例代碼:
//移除數(shù)據(jù)
arrayList.RemoveAt(0);//通過索引坐標(biāo)移除
arrayList.Remove("object");//匹配第一個元素值,滿足就移除
集合--List
List:泛型集合萎坷,內(nèi)存上都是連續(xù)擺放的凹联,不定長,保證類型安全哆档,避免裝箱拆箱(都是統(tǒng)一的類型)蔽挠。
示例代碼:
var list = new List<int>() { 1, 2, 3 };
list.Add(1);
list.AddRange(new List<int> { 4澳淑, 5比原, 6 });//批量添加
list.Any();//判斷是否有數(shù)據(jù)
list.Clear();//清除所有數(shù)據(jù)
list.ForEach((m) => { });//foreach循環(huán),參數(shù)=>viod委托
list.Skip(1).Take(2);//取索引為0之后的兩條數(shù)據(jù)
集合--LinkedList
LinkedList:雙向鏈表 元素不連續(xù)分配杠巡,每個元素都有記錄前后節(jié)點量窘。
示例代碼:
//在頭部和尾部都標(biāo)識了上一個元素和下一個元素所處位置
LinkedList<int> list = new LinkedList<int>();
list.AddLast(1);
list.AddFirst(1);
list.AddBefore(list1, 0);//前面增加
list.AddAfter(list1氢拥, 0);//后面增加
list.Remove(1);
list.Remove(list1);//根據(jù)節(jié)點刪除
list.RemoveFirst();
list.RemoveLast();
list.Clear();
鏈表不能通過元素索引訪問蚌铜。找元素只能遍歷。增刪比較快嫩海,增加或刪除冬殃,只需把這個元素的前后兩個元素指向的元素節(jié)點改一下。
集合--Queue
Queue隊列就是先進(jìn)先出叁怪。它并沒有實現(xiàn) IList审葬,ICollection。所以它不能按索引訪問元素奕谭,不能使用Add和Remove涣觉。
//示例: A不斷寫入任務(wù),B不斷獲取任務(wù)執(zhí)行 血柳,每次拿最近的一個任務(wù)
Queue<string> queue = new Queue<string>();
queue.Enqueue("object");//添加數(shù)據(jù)
queue.Enqueue("object1");
foreach (var item in queue)
{
Console.WriteLine(item);
}
queue.Dequeue();//獲取最先進(jìn)入隊列的元素旨枯,獲得并移除
queue.Peek();//獲取但不移除
Queue的常用方法和屬性:
- Enqueue():在隊列的末端添加元素。
- Dequeue():在隊列的頭部讀取和刪除一個元素混驰,注意這里讀取元素的同時也刪除了這個元素攀隔。如果隊列中不再有任何元素就拋出異常。
- Peek():在隊列的頭讀取一個元素栖榨,但是不刪除它昆汹。
- Count:返回隊列中的元素個數(shù)。
- TrimExcess():重新設(shè)置隊列的容量婴栽,因為調(diào)用Dequeue方法讀取刪除元素后不會重新設(shè)置隊列的容量满粗。
- Contains():確定某個元素是否在隊列中。
- CopyTo():把元素隊列復(fù)制到一個已有的數(shù)組中愚争。
- ToArray():返回一個包含元素的新數(shù)組映皆。
集合--Stack
Stack:棧也是鏈表, 先進(jìn)后出轰枝,先產(chǎn)生的數(shù)據(jù)最后使用捅彻。
示例代碼:
Stack<string> stack = new Stack<string>();
stack.Push("object");//添加數(shù)據(jù)
stack.Push("object1");
stack.Pop();//獲取最后進(jìn)入隊列的元素 獲得并移除
stack.Peek();//獲取不移除
C#中(線程)棧的內(nèi)存釋放也是一樣,先實例化的對象最后釋放(在棧中聲明的變量鞍陨,最先聲明的最后GC)步淹。
集合--HashTable
Hashtable是System.Collections命名空間提供的一個容器,用于處理和表現(xiàn)類似key-value的鍵值對,其中key通崇择桑可用來快速查找键闺,同時key是區(qū)分大小寫,value用于存儲對應(yīng)于key的值澈驼。
Hashtable中keyvalue鍵值對均為object類型辛燥,所以Hashtable可以支持任何類型的key-value鍵值對。
示例代碼:
Hashtable ht=new Hashtable(); //創(chuàng)建一個Hashtable實例
ht.Add("E","e");//添加keyvalue鍵值對
ht.Add("A","a");
ht.Add("C","c");
ht.Add("B","b");
string s=(string)ht["A"];
if(ht.Contains("E")) //判斷哈希表是否包含特定鍵,其返回值為true或false
Console.WriteLine("the E key exist");
ht.Remove("C");//移除一個keyvalue鍵值對
Console.WriteLine(ht["A"]);//此處輸出a
ht.Clear();//移除所有元素
Console.WriteLine(ht["A"]); //此處將不會有任何輸出
集合--Dictionary
Dictionary:相當(dāng)于泛型版本的HashTable缝其。在使用Dictionary前挎塌,你必須對它的鍵類型和值類型進(jìn)行聲明。
Dictionary的描述:
1氏淑、從一組鍵(Key)到一組值(Value)的映射,每一個添加項都是由一個值及其相關(guān)連的鍵組成
2硕噩、任何鍵都必須是唯一的
3假残、鍵不能為空引用null(VB中的Nothing),若值為引用類型炉擅,則可以為空值
4辉懒、Key和Value可以是任何類型(string,int谍失,custom class 等)
1眶俩、創(chuàng)建及初始化
Dictionary<int,string>myDictionary=newDictionary<int,string>();
2、添加元素
myDictionary.Add(1,"C#");
myDictionary.Add(2,"C++");
myDictionary.Add(3,"ASP.NET");
myDictionary.Add(4,"MVC");
Hashtable和Dictionary區(qū)別:
1快鱼、Dictionary<K,V>在使用中是順序存儲的颠印,而Hashtable由于使用的是哈希算法進(jìn)行數(shù)據(jù)存儲,是無序的抹竹。
2线罕、Dictionary的key和value是泛型存儲,Hashtable的key和value都是object窃判。
3钞楼、Dictionary是泛型存儲,不需要進(jìn)行類型轉(zhuǎn)換袄琳,Hashtable由于使用object询件,在存儲或者讀取值時都需要進(jìn)行類型轉(zhuǎn)換,所以比較耗時唆樊。
集合--非泛型集合
泛型集合類是在.NET2.0的時候出來的,也就是說在1.0的時候是沒有這么方便的東西的⊥鹄牛現(xiàn)在基本上我們已經(jīng)不使用這些集合類了,除非在做一些和老代碼保持兼容的工作的時候逗旁。
ArraryList被List<T>替代夯秃。
HashTable 被Dictionary<TKey,TValue>替代。
Queue 被Queue<T>替代。
SortedList 被SortedList<T>替代仓洼。
Stack 被Stack<T>替代介陶。
泛型
泛型(Generic) 允許您延遲編寫類或方法中的編程元素的數(shù)據(jù)類型的規(guī)范,直到實際在程序中使用它的時候色建。換句話說哺呜,泛型允許編寫一個可以與任何數(shù)據(jù)類型一起工作的類或方法』粒可以通過數(shù)據(jù)類型的替代參數(shù)編寫類或方法的規(guī)范某残。當(dāng)編譯器遇到類的構(gòu)造函數(shù)或方法的函數(shù)調(diào)用時,它會生成代碼來處理指定的數(shù)據(jù)類型陵吸。
這里是一個泛型類型Stack <T>玻墅,用于堆棧類型T的實例:
Stack<T>聲明單個類型參數(shù)T:
public class Stack<T> {
int position;
T[] data = new T[100];
public void Push (T obj) {
data[position++] = obj;
}
public T Pop() {
return data[--position];
}
}
我們可以使用Stack <T>如下:
Stack<int> stack = new Stack<int>();
stack.Push(5);
stack.Push(10);
int x = stack.Pop(); // x is 10
int y = stack.Pop(); // y is 5
Stack< int> 用類型參數(shù)int填充類型參數(shù)T。
Stack<T> 是一個開放類型壮虫,而Stack <int>是一個閉合類型澳厢。
泛型--關(guān)聯(lián)性泛型集合類
即鍵值對集合,允許通過Key來訪問和維護(hù)集合囚似。
1.Dictionary<TKey剩拢,TValue>
Dictionary<TKey,TValue>可能是我們最常用的關(guān)聯(lián)性集合了饶唤,它的訪問徐伐,添加,刪除數(shù)據(jù)所花費的時間是所有集合類里面最快的募狂,因為它內(nèi)部用了Hashtable作為存儲結(jié)構(gòu)办素,所以不管存儲了多少鍵值對,查詢/添加/刪除所花費的時間都是一樣的祸穷,它的時間復(fù)雜度是O(1)摸屠。
Dictionary<TKey,TValue>優(yōu)勢是查找插入速度快粱哼,那么什么是它的劣勢呢季二?因為采用Hashtable作為存儲結(jié)構(gòu),就意味著里面的數(shù)據(jù)是無序排列的揭措,所以想按一定的順序去遍歷Dictionary<TKey胯舷,TValue>里面的數(shù)據(jù)是要費一點工夫的。
作為TKey的類型必須實現(xiàn)GetHashCode()和Equals() 或者提供一個IEqualityComparer绊含,否則操作可能會出現(xiàn)問題桑嘶。
2.SortedDictioanry<TKey,TValue>
SortedDictionary<TKey躬充,TValue>和Dictionary<TKey逃顶,TValue>大致上是類似的讨便,但是在實現(xiàn)方式上有一點點區(qū)別。SortedDictionary<TKey以政,TValue>用二叉樹作為存儲結(jié)構(gòu)的霸褒。并且按key的順序排列。那么這樣的話SortedDictionary<TKey盈蛮,TValue>的TKey就必須要實現(xiàn)IComparable<TKey>废菱。如果想要快速查詢的同時又能很好的支持排序的話,那就使用SortedDictionary吧抖誉。
3.SortedList<TKey殊轴,TValue>
SortedList<TKey,TValue>是另一個支持排序的關(guān)聯(lián)性集合袒炉。但是不同的地方在于旁理,SortedList實際是將數(shù)據(jù)存存儲在數(shù)組中的。也就是說添加和移除操作都是線性的我磁,時間復(fù)雜度是O(n)孽文,因為操作其中的元素可能導(dǎo)致所有的數(shù)據(jù)移動。但是因為在查找的時候利用了二分搜索十性,所以查找的性能會好一些叛溢,時間復(fù)雜度是O(log n)塑悼。所以推薦使用場景是這樣地:如果你想要快速查找劲适,又想集合按照key的順序排列,最后這個集合的操作(添加和移除)比較少的話厢蒜,就是SortedList了霞势。
泛型--非關(guān)聯(lián)性泛型集合類
非關(guān)聯(lián)性集合就是不用key操作的一些集合類,通嘲哐唬可以用元素本身或者下標(biāo)來操作愕贡。
List<T>
泛型的List 類提供了不限制長度的集合類型,List在內(nèi)部維護(hù)了一定長度的數(shù)組(默認(rèn)初始長度是4)巷屿。所以如果知道我們將要用這個集合裝多少個元素的話固以,可以在創(chuàng)建的時候指定初始值,這樣就避免了重復(fù)的創(chuàng)建新數(shù)組和拷貝值嘱巾。
另外的話由于內(nèi)部實質(zhì)是一個數(shù)組憨琳,所以在List的未必添加數(shù)據(jù)是比較快的,但是如果在數(shù)據(jù)的頭或者中間添加刪除數(shù)據(jù)相對來說更低效一些因為會影響其它數(shù)據(jù)的重新排列旬昭。
LinkedList<T>
LinkedList在內(nèi)部維護(hù)了一個雙向的鏈表篙螟,也就是說我們在LinkedList的任何位置添加或者刪除數(shù)據(jù)其性能都是很快的。因為它不會導(dǎo)致其它元素的移動问拘。一般情況下List已經(jīng)夠我們使用了遍略,但是如果對這個集合在中間的添加刪除操作非常頻繁的話惧所,就建議使用LinkedList。
HashSet<T>
HashSet是一個無序的能夠保持唯一性的集合绪杏。我們也可以把HashSet看作是Dictionary<TKey下愈,TValue>,只不過TKey和TValue都指向同一個對象寞忿。HashSet非常適合在我們需要保持集合內(nèi)元素唯一性但又不需要按順序排列的時候驰唬。
SortedSet<T>
SortedSet和HashSet,就像SortedDictionary和Dictionary一樣腔彰,還記得這兩個的區(qū)別么叫编?SortedSet內(nèi)部也是一個二叉樹,用來支持按順序的排列元素霹抛。
Stack<T>
后進(jìn)先出的隊列
不支持按下標(biāo)訪問
Queu<T>
先進(jìn)先出的隊列
不支持按下標(biāo)訪問
泛型--泛型類型參數(shù)
在泛型類型或方法定義中搓逾,類型參數(shù)是在其實例化泛型類型的一個變量時指定的特定類型的占位符。 泛型類( GenericList<T>)無法按原樣使用杯拐,因為它不是真正的類型霞篡。 若要使用 GenericList<T>,必須通過指定尖括號內(nèi)的類型參數(shù)來聲明并實例化構(gòu)造類型端逼。 此特定類的類型參數(shù)可以是編譯器可識別的任何類型朗兵。
示例代碼:
GenericList<float> list1 = new GenericList<float>();
GenericList<ExampleClass> list2 = new GenericList<ExampleClass>();
GenericList<ExampleStruct> list3 = new GenericList<ExampleStruct>();
在 GenericList<T> 的每個實例中,類中出現(xiàn)的每個 T 在運行時均會被替換為類型參數(shù)顶滩。
泛型--泛型約束
定義泛型類時余掖,可以對調(diào)用端代碼能夠在實例化類時用于類型參數(shù)的幾種類型施加限制。 如果調(diào)用端代碼嘗試使用約束所不允許的類型來實例化類礁鲁,則會產(chǎn)生編譯時錯誤盐欺。 這些限制稱為約束。 通過使用 where 上下文關(guān)鍵字指定約束仅醇。
下表列出了六種類型的約束:
在 GenericList<T> 的每個實例中冗美,類中出現(xiàn)的每個 T 在運行時均會被替換為類型參數(shù)。
where T:類(類型參數(shù)必須是引用類型析二;這一點也適用于任何類粉洼、接口潮饱、委托或數(shù)組類型)
class MyClass<U>
where U : class///約束U參數(shù)必須為“引用類型”
{
}
public void MyMetod<T>(T t)
where T : class
{
}
where T:<基類名>(類型參數(shù)必須是指定的基類或派生自指定的基類)
public class Employee{}
public class GenericList<T>
where T : Employee
泛型--泛型方法
泛型方法在方法的簽名中聲明類型參數(shù)姥饰。
使用泛型方法愚屁,許多基本算法只能以通用方式實現(xiàn)酷誓。
這里是一個泛型的方法示例:
public void ShowT<T>(T t)
{
Console.WriteLine("ShowT print {0},ShowT Parament Type Is {1}", t, t.GetType());
}
Console.WriteLine("*********泛型方法調(diào)用***************");
ShowT<int>(11);
ShowT<DateTime>(DateTime.Now);
ShowT<People>(new People { Id = 11, Name = "Tom" });
Console.ReadKey();
LINQ
LINQ代表語言集成查詢(Language Integrated Query)慷垮,是.Net框架的擴(kuò)展逮走,它允許我們用SQL查詢數(shù)據(jù)庫的方式來查詢數(shù)據(jù)的集合或悲,使用它风喇,你可以從數(shù)據(jù)庫柱衔、程序?qū)ο蟮募弦约癤ML文檔中查詢數(shù)據(jù)樊破。
查詢表達(dá)式由查詢體后的from子句組成愉棱,其子句必須按一定的順序出現(xiàn),并且from子句和select子句這兩部分是必須的哲戚。
參考:https://docs.microsoft.com/zh-cn/dotnet/csharp/programming-guide/concepts/linq/
LINQ提供了一系列的優(yōu)勢奔滑,其中最重要的是其強大的表達(dá)能力,使開發(fā)表達(dá)聲明顺少。一些LINQ的優(yōu)點如下朋其。
- LINQ提供語法高亮,證明有助于找出在設(shè)計時的錯誤脆炎。
- LINQ提供智能感知這意味著很容易寫更精確的查詢梅猿。
- 寫LINQ代碼是相當(dāng)快的,因此開發(fā)時間也被顯著減少秒裕。
- LINQ使得調(diào)試方便袱蚓,因為它在C#語言的集成。
- 兩個表之間的關(guān)系看很容易使用LINQ由于其分層特征几蜻,這使得編寫查詢在更短的時間加入多個表喇潘。
- LINQ允許一個單一的LINQ語法的使用,同時查詢多個不同的數(shù)據(jù)源梭稚,這是主要是因為其統(tǒng)一的基礎(chǔ)颖低。
- LINQ是可擴(kuò)展的,這意味著有可能使用LINQ的知識來查詢新的數(shù)據(jù)源類型弧烤。
- LINQ提供了一個查詢連接多個數(shù)據(jù)源忱屑,以及突破復(fù)雜問題轉(zhuǎn)換為一組短的查詢易于調(diào)試的工具。
- LINQ提供易于改造轉(zhuǎn)換一種數(shù)據(jù)類型到另一種扼褪,如SQL數(shù)據(jù)轉(zhuǎn)換為XML數(shù)據(jù)想幻。
委托
C# 中的委托(Delegate)類似于 C 或 C++ 中函數(shù)的指針粱栖。顧名思義话浇,讓別人幫你辦件事。委托是C#實現(xiàn)回調(diào)函數(shù)的一種機(jī)制闹究。
委托(Delegate)特別用于實現(xiàn)事件和回調(diào)方法幔崖。所有的委托(Delegate)都派生自 System.Delegate 類。
這個實例演示了委托的用法渣淤。委托 printString 可用于引用帶有一個字符串作為輸入的方法赏寇,并不返回任何東西。
我們使用這個委托來調(diào)用兩個方法价认,第一個把字符串打印到控制臺嗅定,第二個把字符串打印到文件
lambda表達(dá)式
Lambda 表達(dá)式是一種可用于創(chuàng)建委托或表達(dá)式目錄樹類型的匿名函數(shù)。
首先定義一個Citys集合用踩,初始化有一些數(shù)據(jù)渠退。然后調(diào)用LINQ的first方法忙迁,查詢出來長度大于7的第一個結(jié)果,看到了吧碎乃,這里用的就是Lambda表達(dá)式姊扔,
如果我們自己寫,還要寫循環(huán)遍歷集合梅誓,然后判斷字符串長度是否大于7恰梢,起碼要寫四五行代碼,而這里只要一行就夠了梗掰,而且LINQ也要寫很長嵌言。
這里用的是最簡單的Lambda表達(dá)式,(input parameters) => expression的形式及穗。
利用委托方法和lambda表達(dá)式將2013替換成2014呀页,當(dāng)然也可以做其他任何操作,是由我們傳入的lambda表達(dá)式?jīng)Q定的
Lambda 的特點
- Lambda 中包含輸入?yún)?shù)的數(shù)量拥坛,必須與委托類型包含的參數(shù)數(shù)量一致蓬蝶。
- Lambda 中的每個輸入?yún)?shù),必須都能夠通過隱式轉(zhuǎn)換為其對應(yīng)的委托參數(shù)類型猜惋。
- Lambda 中的返回值(如果有)丸氛,必須能夠隱式轉(zhuǎn)換為委托的返回類型
反射
什么是反射
反射指程序可以訪問、檢測和修改它本身狀態(tài)或行為的一種能力著摔。
程序集包含模塊缓窜,而模塊包含類型,類型又包含成員谍咆。反射則提供了封裝程序集禾锤、模塊和類型的對象。
可以使用反射動態(tài)地創(chuàng)建類型的實例摹察,將類型綁定到現(xiàn)有對象恩掷,或從現(xiàn)有對象中獲取類型。然后供嚎,可以調(diào)用類型的方法或訪問其字段和屬性黄娘。
反射(Reflection)有下列用途:
它允許在運行時查看特性(attribute)信息。
它允許審查集合中的各種類型克滴,以及實例化這些類型逼争。
它允許延遲綁定的方法和屬(property)。
它允許在運行時創(chuàng)建新類型劝赔,然后使用這些類型執(zhí)行一些任務(wù)誓焦。
反射用到的主要類:
System.Type 類:通過這個類可以訪問任何給定數(shù)據(jù)類型的信息。
System.Reflection.Assembly類:它可以用于訪問給定程序集的信息着帽,或者把這個程序集加載到程序中杂伟。
System.Type類:對于反射起著核心的作用竿秆。但它是一個抽象的基類,Type有與每種數(shù)據(jù)類型對應(yīng)的派生類稿壁,我們使用這個派生類的對象的方法幽钢、字段、屬性來查找有關(guān)該類型的所有信息傅是。獲取給定類型的Type引用有3種常用方式:
Type類的屬性:
Name 數(shù)據(jù)類型名匪燕;
FullName 數(shù)據(jù)類型的完全限定名(包括命名空間名);
Namespace 定義數(shù)據(jù)類型的命名空間名喧笔;
IsAbstract 指示該類型是否是抽象類型帽驯;
IsArray 指示該類型是否是數(shù)組;
IsClass 指示該類型是否是類书闸;
IsEnum 指示該類型是否是枚舉尼变;
IsInterface 指示該類型是否是接口;
IsPublic 指示該類型是否是公有的浆劲;
IsSealed 指示該類型是否是密封類嫌术;
IsValueType 指示該類型是否是值類型;
Type類的方法:
GetConstructors():返回ConstructorInfo類型牌借,用于取得該類的構(gòu)造函數(shù)的信息度气;
GetEvents():返回EventInfo類型,用于取得該類的事件的信息膨报;
GetFields():返回FieldInfo類型磷籍,用于取得該類的字段(成員變量)的信息;
GetInterfaces():返回InterfaceInfo類型现柠,用于取得該類實現(xiàn)的接口的信息院领;
GetMembers():返回MemberInfo類型,用于取得該類的所有成員的信息够吩;
GetMethods():返回MethodInfo類型比然,用于取得該類的方法的信息;
GetProperties():返回PropertyInfo類型废恋,用于取得該類的屬性的信息可以調(diào)用這些成員谈秫,其方式是調(diào)用Type的InvokeMember()方法扒寄,或者調(diào)用MethodInfo鱼鼓, PropertyInfo和其他類的Invoke()方法;
優(yōu)點:
1该编、反射提高了程序的靈活性和擴(kuò)展性迄本。
2、降低耦合性课竣,提高自適應(yīng)能力嘉赎。
3置媳、它允許程序創(chuàng)建和控制任何類的對象,無需提前硬編碼目標(biāo)類公条。
缺點:
1拇囊、性能問題:使用反射基本上是一種解釋操作,用于字段和方法接入時要遠(yuǎn)慢于直接代碼靶橱。因此反射機(jī)制主要應(yīng)用在對靈活性和拓展性要求很高的系統(tǒng)框架上寥袭,普通程序不建議使用。
2关霸、使用反射會模糊程序內(nèi)部邏輯传黄;程序員希望在源代碼中看到程序的邏輯,反射卻繞過了源代碼的技術(shù)队寇,因而會帶來維護(hù)的問題膘掰,反射代碼比相應(yīng)的直接代碼更復(fù)雜。
事件
事件(Event) 基本上說是一個用戶操作佳遣,如按鍵识埋、點擊、鼠標(biāo)移動等等零渐,或者是一些提示信息惭聂,如系統(tǒng)生成的通知。應(yīng)用程序需要在事件發(fā)生時響應(yīng)事件相恃。
事件在類中聲明且生成辜纲,且通過使用同一個類或其他類中的委托與事件處理程序關(guān)聯(lián)。包含事件的類用于發(fā)布事件拦耐。這被稱為 發(fā)布器(publisher) 類耕腾。其他接受該事件的類被稱為 訂閱器(subscriber) 類。事件使用 發(fā)布-訂閱(publisher-subscriber) 模型杀糯。
發(fā)布器(publisher) 是一個包含事件和委托定義的對象扫俺。事件和委托之間的聯(lián)系也定義在這個對象中。發(fā)布器(publisher)類的對象調(diào)用這個事件固翰,并通知其他的對象狼纬。
訂閱器(subscriber) 是一個接受事件并提供事件處理程序的對象。在發(fā)布器(publisher)類中的委托調(diào)用訂閱器(subscriber)類中的方法(事件處理程序)骂际。