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

首頁 > 編程 > C# > 正文

C#中委托的+=和-=深入研究

2020-01-24 02:12:28
字體:
來源:轉載
供稿:網友

寫在前面

為什么會突然想說說委托?原因嗎,起于一個同事的想法,昨天下班的路上一直在想這個問題,如果給委托注冊多個方法,會不會都執行呢?為了一探究性,就弄了個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另一個意思就是空引用,這樣就可以等待垃圾回收器進行回收了。

總結

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

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 新昌县| 吴桥县| 乌拉特中旗| 田东县| 绥宁县| 彰化县| 清镇市| 汶上县| 衡南县| 襄汾县| 大埔县| 治县。| 浏阳市| 敦煌市| 库车县| 绵竹市| 虎林市| 绥阳县| 台东县| 郓城县| 霍州市| 密山市| 遂川县| 富源县| 射洪县| 株洲市| 定远县| 平乐县| 安龙县| 新安县| 汉沽区| 芒康县| 文成县| 台安县| 凤城市| 灵武市| 邵武市| 德阳市| 嘉祥县| 宜春市| 扶余县|