5

過去数週間、イベントについて混乱してきました。デリゲートがどのように機能するかは理解していますが、それがどのように機能するかは詳細ではありませんが、それ delegate datatypeが単一のキャスト デリゲートであることを知るには十分です。 delegate voidメソッドへの参照のリストであるマルチキャスト デリゲートです。

デリゲート型がクラスにコンパイルされることは知っていますが、残念ながらメソッドがどのように参照されるのかはまだわかりません。例えば

delegate void TestDelegate();
TestDelegate testDelegate = new TestDelegate(myObject.SomeMethod) ;

質問 1: myObject がターゲットで、SomeMethod が参照するメソッドだと思いますが、入力を 1 つだけ渡しています。myObject.SomeMethod は文字列にコンパイルされ、文字列はピリオドで分割されますか? ばかげている私は知っています。

質問 2: マルチキャスト デリゲートに追加する場合

multicastdelegate+=newmethodtobereference
multicastdelegate() ;

呼び出しリスト内のすべてのメソッドが呼び出されるか、または通知されますか? それが本当なら、なぜイベントやeventキーワードが必要なのですか? これはイベントとして機能していることを単に開発者に伝えるためですか? 本気で迷っているので、この段階で進めたいと思います笑。これは、イベント キーワードが必要かどうかをテストするために今日書いたサンプル コードです。

using System;
namespace LambdasETs
{
    public delegate void IsEvenNumberEventHandler(int numberThatIsEven);

    public class IsEvenNumberFound
    {
        public  IsEvenNumberEventHandler IsEvenNumberEvent;
        private int number;

        public void InputNumber(int n)
        {
            if(number %2 ==0)
            {
                if (IsEvenNumberEvent != null)
                {
                    IsEvenNumberEvent(n);
                }
            }
        }


        public static void Main()
        {
            IsEvenNumberFound isEvenNumberFound = new IsEvenNumberFound();

            isEvenNumberFound.IsEvenNumberEvent += IsEvenNumberAction;

             isEvenNumberFound.InputNumber(10);

            Console.ReadLine();

        }

        public static void IsEvenNumberAction(int number)
        {
            Console.WriteLine("{0} is an even number!", number);
        }
    }


}

event キーワードをフィールドに追加しpublic IsEvenNumberEventHandler IsEvenNumberEvent;ても違いはありません。初心者が理解できるように説明してください。

4

2 に答える 2

6

プロパティがフィールドのアクセサーであるように、イベントはデリゲートのアクセサーです。ほぼ同じ目的で、他のコードがデリゲート オブジェクトをいじるのを防ぎます。知らないコードの束がコールバックをサブスクライブしているときに null を設定するようなものです。イベントは、+= 演算子と -= 演算子を使用したイベント ハンドラーの追加と削除のみにアクセスを制限し、外部コードはプライベート デリゲート オブジェクトにまったくアクセスできません。

また、 add および remove アクセサーを使用してサブスクリプションをカスタマイズします。通常、コンパイラによって生成されたデフォルトのアクセサーに満足しているため、そうする必要はあまりありません。デリゲートを格納する隠しバッキング フィールドを含めます。ただし、たとえばフレームワーク コードでは珍しくありません。System.Windows.Forms.Control がサポートする多くのイベントのすべてのイベント ハンドラーと同様に、それらはすべて 1 つの EventHandlerList に格納されます。または、WPF に相当する EventHandlersStore.

于 2012-05-27T16:43:01.220 に答える
3

しかし、デリゲートのデータ型が単一のキャスト デリゲートであることを知っていれば十分です。delegate void はマルチキャスト デリゲート (メソッドへの参照のリスト) です。

違います。すべての「通常の」デリ​​ゲートは、戻り値の型が void でない場合でもマルチキャストです。

質問 1: myObject がターゲットで、SomeMethod が参照するメソッドだと思いますが、入力を 1 つだけ渡しています。myObject.SomeMethod は文字列にコンパイルされ、文字列はピリオドで分割されますか? ばかげている私は知っています。

いいえ、myObject.SomeMethodメソッド グループです。このデリゲート インスタンスの作成方法には、少しのコンパイラ マジックが必要です。

multicastdelegate+=newmethodtobereference

が通常のデリゲート変数である場合multicastdelegate、これは、multicastdelegate = multicastdelegate + newmethodtobereference複数のメソッドを呼び出す新しいデリゲートを作成し、それを に割り当てることと同じmulticastdelegateです。


ここで、主な質問に移ります: イベントの目的は何ですか?

イベントにはデリゲート型があります。プロパティと同様に動作します。それらの目的はカプセル化です。特に、コンシューマーは subscribe( +=) と unsubscribe( -=) のみを許可し、イベントの値を読み取ることは許可しません。

プロパティは、 と の 2 つのメソッドを組み合わせたものgetですset

イベントは と の 2 つのパブリック メソッドの組み合わせでsubscribeありunsubscribe、フィールドのようなイベントの場合は、プライベート ゲッターに似たものでもあります。

于 2012-05-27T16:42:12.683 に答える