国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

C#之委托與事件

2019-11-17 03:12:13
字體:
來源:轉載
供稿:網友

C#之委托與事件

委托與事件

廢話一堆:網上關于委托、事件的文章有很多,一千個哈姆雷特就有一千個莎士比亞,以下內容均是本人個人見解。

1. 委托

1.1 委托的使用

這一小章來學習一下怎么簡單的使用委托,了解一些基本的知識。

這里先看一下其他所要用到的類的信息

/// <summary>

/// 函數用例

/// </summary>

public class ManyMethodClass

{

public ManyMethodClass() { }

/// <summary>

/// 實例函數

/// </summary>

/// <param name="strmes"></param>

public void InstanceMethod(string strmes)

{

Console.WriteLine("實例函數輸出:" + strmes);

}

/// <summary>

/// 靜態函數

/// </summary>

/// <param name="strmes"></param>

public static void StaticMethod(string strmes)

{

Console.WriteLine("靜態函數輸出:" + strmes);

}

}

  • 定義一個委托類型

public delegate void DisplayStringDelegate(string strmes);

  • 實例化委托類型

//綁定實例函數 第一種定義方式(實例函數)

DisplayStringDelegate disstrdele_instance = new DisplayStringDelegate(new ManyMethodClass().InstanceMethod);

//綁定靜態函數 第二種定義方式(靜態函數)

DisplayStringDelegate disstrdele_static = new DisplayStringDelegate(ManyMethodClass.StaticMethod);

//綁定委托實例 第三種定義方式(委托實例)

DisplayStringDelegate disstrdele_delegate = new DisplayStringDelegate(disstrdele_instance);

  • 調用委托實例

disstrdele_instance.Invoke("Hello Word");

disstrdele_static("Hello Word");

disstrdele_delegate("Hello Word");

(ps:這里不同的調用方式效果都是一樣的,在下一節會有講到)

最后讓我們看一下最終的效果圖:

1.2 委托的定義

  • 委托類型是類類型

/// <summary>

/// 委托示例類

/// </summary>

public class DelegateDemonStration

{

public DelegateDemonStration() { }

public delegate void DisplayStringDelegate(string strmes);

}

在上面的示例代碼中,我們定義了一個委托示例類DelegateDemonStration,在DelegateDemonStration的內部我們定義了上一節中講到的委托的類型DisplayStringDelegate,

在這里先不談DisplayStringDelegate它定義簽名類型,先來談談它到底是什么樣的存在。

我們來看一下代碼:

/// <summary>

/// 委托示例類

/// </summary>

public class DelegateDemonStration

{

public DelegateDemonStration() { }

public class DisplayStringDelegate : MulticastDelegate

{

public DisplayStringDelegate(object @object, IntPtr method){}

public virtual IAsyncResult BeginInvoke(string strmes, AsyncCallback callback, object @object);

public virtual void EndInvoke(IAsyncResult result);

public virtual void Invoke(string strmes);

}

}

當我們定義好一個委托類型的時候,在運行時C#編譯器把【public delegate void DisplayStringDelegate(string strmes);】

編譯為【public class DisplayStringDelegate : MulticastDelegate】

所以,各位客官只要記住 在你定義一個委托類型的時候實際上你是定義了一個類

  • 委托實例是函數指針

先讓我們來看一下這一小節所要用到的示例代碼(所用到的對象類型還是上一小節的內容):

DisplayStringDelegate disstrdele = new DisplayStringDelegate(new ManyMethodClass().InstanceMethod);

disstrdele += ManyMethodClass.StaticMethod;//這里是委托類型推斷 綁定函數的一種方式 幾種方式可以自行百度

disstrdele += new DisplayStringDelegate(ManyMethodClass.StaticMethod);

1.第一步 在我們執行DisplayStringDelegate disstrdele = new DisplayStringDelegate(new ManyMethodClass().InstanceMethod);的時候,disstrdele實例是如下圖一樣:

2.第二步 當我們繼續執行代碼 disstrdele += ManyMethodClass.StaticMethod;的時候,請再來看圖:

這是disstrdele多指向了一個函數地址,而它的內部實現并不是外表看起來這樣簡單的:

這里簡要的說一下執行第二步的時候

L_0012:是將第一步的disstrdele實例壓入棧中

L_0013:將一個空引用壓入棧中

L_0014:加載ManyMethodClass.StaticMethod函數地址

L_001a:實例化DisplayStringDelegate委托類型,假如它叫A

L_001f:將disstrdele和A合并

L_0024:將合并好的值轉換成DisplayStringDelegate類型,并且存入L_0013中

L_0029:將L_0013賦值到disstrdele實例

(以上純屬個人理解,如有偏差請幫忙糾正,謝謝)

3.第三步 當我們繼續執行代碼disstrdele += new DisplayStringDelegate(ManyMethodClass.StaticMethod);的時候,過程和第二步相同:

終上所述,委托實例都會指向一個函數地址,當然嘍合并過后新的委托實例寧當別論,所以 委托實例是函數指針 或者 委托實例是函數指針列表

1.3 委托實例的調用

我們來看調用的代碼:

disstrdele("Hello Word");

這里的內容是接著上一小節的內容繼續講的,拆分開來講是為了讓大家能看的更清楚。

看一下示意圖吧,

從這里就可以看出來了,雖然disstrdele 實例是合并后的委托實例,它的屁股上掛上了好多函數地址,但是執行這樣函數的入口還只是一個,那就是Delegate.Invoke(string),

如果有人要問它的Invoke(string)內部是怎么實現的,暫時回答不了,因為具體的代碼是動態生成的吧,不過我們可以自己猜想或者想象一下它是怎么實現的。

在這里就不多說了。

看了以上的內容能大概的知道或者分清一些概念性的東西。

這里本人只是講了一把劍是由鐵鑄成的,可以用來切割、刺、劈、砍,至于這把劍怎么用就因人而異了。

2. 事件

2.1 事件是什么?

這一章我們來學習一下事件

照舊我們先來看一下示例代碼:

public class EventDomeStration

{

public EventDomeStration() { }

/// <summary>

/// 定義好的一個示例

/// </summary>

public event DisplayStringDelegate DisplayStringEventHandler;

}

在上面的代碼中,我們定義了一個事件DisplayStringEventHandler,而在它名稱前面的是一個DisplayStringDelegate委托類型(就是我們上一節所說的委托)。

就對于它而言來看一下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)

}

}

從這里可以看到,定義好的一個事件就是一個私有(DisplayStringDelegate委托類型)的字段加上一個事件訪問器,也就是相當于C#代碼的這樣:

public class EventDomeStration

{

public EventDomeStration() { }

private DisplayStringDelegate displaystringdele;

public event DisplayStringDelegate DisplaystringEventHandler

{

add

{

displaystringdele += value;

}

remove

{

displaystringdele -= value;

}

}

在這里本人對事件的定義是:

事件就是所在對象里的屬性,而屬性的類型是委托類型,它是負責架設與外部對象即時通訊(傳遞消息)的橋梁,橋梁本身就是委托。

2.2 事件的使用

出門在外務工,難免要租房子住,每次找房子是件頭疼的事請各位客官一起來看一下,就拿這個來舉個例子。

先定義一個委托:public delegate void 消息反饋(string 反饋房子信息);

首先得有一個中介,暫且叫它為房產中介1, 來看一下它的內部定義:

public class 房產中介1 { public 房產中介1() { } public 房產中介1(string 具體要求) { 房源信息處理(具體要求); } public event 消息反饋 消息通知; public string 客戶要求的信息_1 = string.Empty; private void 房源信息處理(string 客戶要求的信息) { //邏輯處理 //假如是有客戶需要的 則通知客戶 if (消息通知 != null) { 消息通知("有房子,什么樣的,信息等等"); } 客戶要求的信息_1 = 客戶要求的信息; //邏輯處理要是沒有 把信息移交給了中介2 房產中介2 中介2 = new 房產中介2(this); } public void 其它中介消息通知(string 房子信息) { if (消息通知 != null) { 消息通知(房子信息); } } }

中介有了,那現在我想要開始租房子怎么辦?沒關系,找中介。

首先先把“我”定義出來:

public class 我

{

//比如我要租房子

public 我(){ }

public void 我要租房子(string 具體的要求)

{

//找的是房產中介1

房產中介1 中介1 = new 房產中介1(具體的要求);

中介1.消息通知 += new 消息反饋(中介1_消息通知);

}

void 中介1_消息通知(string 房子信息)

{

//我可以從【房子信息】中知道是否有有合適的房子,如果有得話,是什么樣的

}

}

public class 房產中介2

{

public string 客戶要求信息 = string.Empty;

public 房產中介2() { }

public 房產中介2(房產中介1 中介1)

{

房源信息處理(中介1);

}

private void 房源信息處理(房產中介1 中介1)

{

//邏輯處理

//判斷是否有滿足 ->中介1.客戶要求的信息_1值條件的房源

//如果有

中介1.其它中介消息通知("房子有的,房子的信息等等");

}

上面定義了 我、房產中介1、房產中介2,現在 我 要找房子了

我 m

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 吉木乃县| 贡觉县| 聂荣县| 乐山市| 津南区| 泗阳县| 兖州市| 抚州市| 民丰县| 汉寿县| 石门县| 阳城县| 奇台县| 信丰县| 墨玉县| 宁城县| 临洮县| 华宁县| 固阳县| 慈溪市| 莱阳市| 通化市| 梁山县| 社会| 牡丹江市| 隆德县| 体育| 山阳县| 白水县| 惠水县| 丰县| 志丹县| 桦甸市| 专栏| 新津县| 长子县| 新密市| 兴国县| 长乐市| 宁城县| 汉中市|