廢話一堆:網上關於委托、事件的文章有很多,一千個哈姆雷特就有一千個莎士比亞,以下內容均是本人個人見解。
這一小章來學習一下怎麼簡單的使用委托,了解一些基本的知識。
這裡先看一下其他所要用到的類的信息
{
ManyMethodClass() { }
InstanceMethod( strmes)
{
.WriteLine( + strmes);
}
StaticMethod( strmes)
{
.WriteLine( + strmes);
}
}
( strmes);
disstrdele_instance = ( ().InstanceMethod);
disstrdele_static = (.StaticMethod);
disstrdele_delegate = (disstrdele_instance);
disstrdele_instance.Invoke();
disstrdele_static();
disstrdele_delegate();
(ps:這裡不同的調用方式效果都是一樣的,在下一節會有講到)
最後讓我們看一下最終的效果圖:
{
() { }
( strmes);
}
在上面的示例代碼中,我們定義了一個委托示例類,在的內部我們定義了上一節中講到的委托的類型
在這裡先不談
{
() { }
:
{
( @object, method){}
IAsyncResult BeginInvoke( strmes, callback, @object);
EndInvoke( result);
Invoke( strmes);
}
}
當我們定義好一個委托類型的時候,在運行時C#編譯器把【 ( strmes);】
編譯為【 : 】
在你定義一個委托類型的時候實際上你是定義了一個類
disstrdele = ( ().InstanceMethod);
disstrdele += .StaticMethod;
disstrdele += DisplayStringDelegate(.StaticMethod);
1.第一步 在我們執行 disstrdele = ( ().InstanceMethod);的時候,disstrdele實例是如下圖一樣:
2.第二步 當我們繼續執行代碼 disstrdele += .StaticMethod;的時候,請再來看圖:
這是disstrdele多指向了一個函數地址,而它的內部實現並不是外表看起來這樣簡單的:
這裡簡要的說一下執行第二步的時候
L_0012:是將第一步的disstrdele實例壓入棧中
L_0013:將一個空引用壓入棧中
L_0014:加載.StaticMethod函數地址
L_001a:實例化
L_001f:將disstrdele和A合並
L_0024:將合並好的值轉換成
L_0029:將L_0013賦值到disstrdele實例
(以上純屬個人理解,如有偏差請幫忙糾正,謝謝)
3.第三步 當我們繼續執行代碼disstrdele += DisplayStringDelegate(.StaticMethod);的時候,過程和第二步相同:
終上所述,委托實例都會指向一個函數地址,當然喽合並過後新的委托實例寧當別論,所以 委托實例是 委托實例是
我們來看調用的代碼:
disstrdele();
這裡的內容是接著上一小節的內容繼續講的,拆分開來講是為了讓大家能看的更清楚。
看一下示意圖吧,
從這裡就可以看出來了,雖然disstrdele 實例是合並後的委托實例,它的屁股上掛上了好多函數地址,但是執行這樣函數的入口還只是一個,那就是Delegate.Invoke(string),
如果有人要問它的Invoke(string)內部是怎麼實現的,暫時回答不了,因為具體的代碼是動態生成的吧,不過我們可以自己猜想或者想象一下它是怎麼實現的。
在這裡就不多說了。
看了以上的內容能大概的知道或者分清一些概念性的東西。
這裡本人只是講了一把劍是由鐵鑄成的,可以用來切割、刺、劈、砍,至於這把劍怎麼用就因人而異了。
這一章我們來學習一下事件
{
EventDomeStration() { }
DisplayStringEventHandler;
}
在上面的代碼中,我們定義了一個事件DisplayStringEventHandler,而在它名稱前面的是一個委托類型(就是我們上一節所說的委托)。
就對於它而言來看一下MSIL,看看它究竟是什麼樣的:
.class public auto ansi beforefieldinit EventDomeStration extends [mscorlib]System.Object
{
.field private class DelegateCaseAndEventCase.DisplayStringDelegate DisplayStringEventHandler
.event DelegateCaseAndEventCase.DisplayStringDelegate DisplayStringEventHandler
{
.addon instance void DelegateCaseAndEventCase.EventDomeStration::add_DisplayStringEventHandler(class DelegateCaseAndEventCase.DisplayStringDelegate) .removeon instance void DelegateCaseAndEventCase.EventDomeStration::remove_DisplayStringEventHandler(class DelegateCaseAndEventCase.DisplayStringDelegate) }
}
從這裡可以看到,定義好的一個事件就是一個私有(
{
EventDomeStration() { }
displaystringdele;
DisplaystringEventHandler
{
{
displaystringdele += value;
}
{
displaystringdele -= value;
}
}
}
在這裡本人對事件的定義是:
事件就是所在對象裡的屬性,而屬性的類型是委托類型,它是負責架設與外部對象即時通訊(傳遞消息)的橋梁,橋梁本身就是委托。
出門在外務工,難免要租房子住,每次找房子是件頭疼的事請各位客官一起來看一下,就拿這個來舉個例子。
先定義一個委托: ( 反饋房子信息);
首先得有一個中介,暫且叫它為房產中介1, 來看一下它的內部定義:
{
房產中介1() { }
房產中介1( 具體要求)
{
房源信息處理(具體要求);
}
消息通知;
客戶要求的信息_1 = .Empty;
房源信息處理( 客戶要求的信息)
{
//假如是有客戶需要的 則通知客戶
(消息通知 != )
{
消息通知();
}
客戶要求的信息_1 = 客戶要求的信息;
中介2 = ();
}
其它中介消息通知( 房子信息)
{
(消息通知 != )
{
消息通知(房子信息);
}
}
}