深入講解C#中委託的+=和-=

來源:互聯網
上載者:User
這篇文章主要介紹了C#中委託的+=和-=深入研究,本文深入研究+=和-=在執行時都做了哪些事情,加深對C#委託的理解和使用,需要的朋友可以參考下

寫在前面

為什麼會突然想說說委託?原因嗎,起於一個同事的想法,昨天下班的路上一直在想這個問題,如果給委託註冊多個方法,會不會都執行呢?為了一探究性,就弄了個demo研究下。

+=

大家都知道委託都繼承自System.MulticastDelegate,而System.MulticastDelegate又繼承自System.Delegate,可以通過+=為委託註冊多個方法。那麼他們是否都執行了呢?執行的結果又是怎樣的呢?有傳回值和沒傳回值的是否結果是否一樣?那就試著說說+=都幹了哪些事?

測試代碼

代碼如下:

namespace Wolfy.DelegateDemo{    public delegate void ShowMsg(string msg);    public delegate int MathOperation(int a, int b);    class Program    {        static ShowMsg showMsg;        static MathOperation mathOperation;        static void Main(string[] args)        {            showMsg += ShowHello;            showMsg += ShowHello1;            showMsg("大家新年好啊");            mathOperation += Add;              mathOperation += Multiply;            int result = mathOperation(1, 2);            Console.WriteLine(result.ToString());            Console.Read();        }        static void ShowHello(string msg)        {            Console.WriteLine("哈嘍:" + msg);        }        static void ShowHello1(string msg)        {            Console.WriteLine("哈嘍1:" + msg);        }        static int Add(int a, int b)        {            return a + b;        }        static int Multiply(int a, int b)        {            return a * b;        }    }}

你可以猜猜運行結果,如:

可以看到沒有傳回值的都輸出了,有傳回值的只輸出了Mutiply的結果,那麼+=內部做了哪些事?可以看一下反編譯的代碼:

代碼如下:

using System;namespace Wolfy.DelegateDemo{    internal class Program    {        private static ShowMsg showMsg;        private static MathOperation mathOperation;        private static void Main(string[] args)        {            Program.showMsg = (ShowMsg)Delegate.Combine(Program.showMsg, new ShowMsg(Program.ShowHello));            Program.showMsg = (ShowMsg)Delegate.Combine(Program.showMsg, new ShowMsg(Program.ShowHello1));            Program.showMsg("大家新年好啊");            Program.mathOperation = (MathOperation)Delegate.Combine(Program.mathOperation, new MathOperation(Program.Add));            Program.mathOperation = (MathOperation)Delegate.Combine(Program.mathOperation, new MathOperation(Program.Multiply));            Console.WriteLine(Program.mathOperation(1, 2).ToString());            Console.Read();        }        private static void ShowHello(string msg)        {            Console.WriteLine("哈嘍:" + msg);        }        private static void ShowHello1(string msg)        {            Console.WriteLine("哈嘍1:" + msg);        }        private static int Add(int a, int b)        {            return a + b;        }        private static int Multiply(int a, int b)        {            return a * b;        }    }}

通過上面的代碼可以看出+=內部是通過委託的 Combine靜態方法將委託進行組合的,可以看一下委託的這個靜態方法是如何?的。

可以看到最終調用CombineImpl這個方法,這個方法內部很奇怪:

並沒有我們想看到的代碼,那這個方法是幹嘛用的啊?

MSDN的解釋

Concatenates the invocation lists of the specified multicast (combinable) delegate and the current multicast (combinable) delegate.

大概意思就是:將當前的委託加入到指定的多播委託集合中。

繞了一圈那麼有傳回值的委託,到底執行了嗎?那也只能通過調試來看看了。(繞了一圈,又回到了編輯器,唉)

繼續F11你會發現確實進入了Add方法

也確實執行了,但在遍曆多播委託集合的時候,將之前的值給覆蓋了。

那麼現在可以得出這樣的結論了:無傳回值的委託,你給它註冊多少個方法,它就執行多少個方法,而有傳回值的委託,同樣註冊多少個方法就執行多少個方法,但返回的是最後一個方法的傳回值。

-=

既然說了+=,那麼作為收拾爛攤子的-=也不得不說。在項目中使用了+=就要使用-=來釋放。那它內部做了哪些事?同樣使用上面的代碼,在輸出結果後,使用-=來釋放資源。

可以看出,使用-=內部是調用了委託的Remove靜態方法。

使用-=最終是將委託置為null,為null另一個意思就是Null 參考,這樣就可以等待記憶體回收行程進行回收了。

總結

這個問題雖然很基礎,一個同事當時問了,就給他說了一下,在下班的路上一直在想,內部是如何?的?就試著通過反編譯的方式一探究竟。但貌似CombineImpl這個方法,給的結果不太滿意。沒看到具體的實現。希望對你有所協助!

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.