ホームページ  >  記事  >  バックエンド開発  >  C# の委任の += と -= の詳細な説明

C# の委任の += と -= の詳細な説明

Y2J
Y2Jオリジナル
2017-04-21 14:15:254220ブラウズ

この記事では、C# のデリゲーションの += と -= について詳しく紹介します。この記事では、C# デリゲーションの理解と使用法をさらに深めるために、+= と -= が実行中に何をするのかについて詳しく説明します。次に

前に書いています

なぜ突然委任について話したいのですか?その理由は、昨日仕事を降りる途中にこの問題について考えていたことから始まりました。複数の委任メソッドを登録した場合、実行はすべて失われますか?自然を探索するために、それを研究するためのデモを作成しました。

+=

デリゲートは 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 の説明

指定されたマルチキャスト (結合可能な) デリゲートと現在のマルチキャスト (結合可能な) デリゲートの呼び出しリストを連結します。

おそらく、現在のデリゲートを指定されたマルチキャスト デリゲート セットに追加することを意味します。

一周して、戻り値を持つデリゲートは実行されましたか?それはデバッグを通じてのみ確認できます。 (ぐるぐる回って、エディタに戻ってきます)

F11 を続けると、実際に Add メソッド

を入力していることがわかります。実際に実行されますが、マルチキャスト デリゲートを通過するときコレクション、前の値は上書きされます。

これで、次の結論を導き出すことができます。戻り値のないデリゲートの場合は、登録した数と同じ数のメソッドが実行されますが、戻り値のあるデリゲートの場合は、登録された数と同じ数のメソッドが実行されます。メソッドですが、最後のメソッドの戻り値を返します。

-=

+=と言ったからには、後始末をする側として-=も言わなければなりません。プロジェクトで += を使用する場合は、-= を使用して解放する必要があります。それでは内部的には何をしているのでしょうか?また、上記のコードを使用し、結果を出力した後、-= を使用してリソースを解放します。

-= を使用すると、デリゲートの静的メソッド Remove が内部的に呼び出されることがわかります。

-= を使用すると、最終的にデリゲートが null に設定され、null のもう 1 つの意味は、ガベージ コレクターがリサイクルするのを待つことができます。

概要

この質問は非常に基本的なものですが、当時同僚が尋ねたので、私は仕事を終える途中、社内でどのように実装されているのか考え続けました。逆コンパイルして調べてみてください。しかし、CombineImpl メソッドでは満足のいく結果が得られないようです。具体的な実装は見たことがありません。お役に立てれば!

以上がC# の委任の += と -= の詳細な説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。