9

イベントは常にデリゲートに関連付けられていることを知っています。しかし、私はイベントの中心的な使用法をいくつか見逃しており、それを理解しようとしています.

以下のように簡単なイベント プログラムを作成しましたが、問題なく動作します。

namespace CompleteRef3._0
{
delegate void someEventDelegate();

class EventTester
{
    public event someEventDelegate someEvent;

    public void doEvent()
    {
        if (someEvent != null) someEvent();
    }

}

class Program
{
    static void EventHandler1()
    {
        Console.WriteLine("Event handler 1 called..");
    }

    static void EventHandler2()
    {
        Console.WriteLine("Event handler 2 called..");
    }
    static void EventHandler3()
    {
        Console.WriteLine("Event handler 3 called..");
    }


    static void Main(string[] args)
    {
        EventTester evt = new EventTester();
        evt.someEvent += EventHandler1;
        evt.someEvent += EventHandler2;
        evt.someEvent += EventHandler3;
        evt.doEvent();
        Console.ReadKey();

    }
}
}

イベント宣言をデリゲートに置き換えました。つまり、public event someEventDelegate someEvent;という行を置き換えました。someEventDelegateでsomeEvent; 上記のプログラムで、それでも同じ結果が得られます。さて、デリゲートだけが達成できるのに、なぜイベントを使用する必要があるのか​​、私は混乱しました。イベントの実際の用途は何ですか?

イベントのない変更されたプログラムは次のとおりです-

namespace CompleteRef3._0
{
delegate void someEventDelegate();

class EventTester
{
    someEventDelegate someEvent;

    public void doEvent()
    {
        if (someEvent != null) someEvent();
    }

}

class Program
{
    static void EventHandler1()
    {
        Console.WriteLine("Event handler 1 called..");
    }

    static void EventHandler2()
    {
        Console.WriteLine("Event handler 2 called..");
    }
    static void EventHandler3()
    {
        Console.WriteLine("Event handler 3 called..");
    }


    static void Main(string[] args)
    {
        EventTester evt = new EventTester();
        evt.someEvent += EventHandler1;
        evt.someEvent += EventHandler2;
        evt.someEvent += EventHandler3;
        evt.doEvent();
        Console.ReadKey();

    }
}
}
4

4 に答える 4

10

もちろん、舞台裏ではイベントがデリゲートをラップする構成要素であるため、デリゲートを使用できます。

ただし、デリゲートの代わりにイベントを使用する理由は、フィールドの代わりにプロパティを使用する場合と同じです(データのカプセル化) 。フィールド(プリミティブフィールドまたはデリゲート)を直接公開することはお勧めできません。

ちなみに、public2番目のスニペットでそれを可能にするために、デリゲートフィールドの前にキーワードを見逃しました。

2番目のスニペットのもう1つの「ちなみに」:デリゲートの場合はDelegate.Combine、「+=」の代わりに使用する必要があります。

于 2013-03-03T06:24:09.873 に答える
8

イベントの主な目的は、サブスクライバーが相互に干渉するのを防ぐことです。イベントを使用しない場合は、次のことができます。

(+ =演算子を使用する代わりに)デリゲートを再割り当てして他のサブスクライバーを置き換え、(デリゲートをnullに設定して)すべてのサブスクライバーをクリアし、デリゲートを呼び出して他のサブスクライバーにブロードキャストします。

出典:一言で言えばC#

于 2013-03-03T06:21:47.417 に答える
0
public class Program
{
    public static void Main()
    {
        Number myNumber = new Number(100000);
        myNumber.PrintMoney();
        myNumber.PrintNumber();
        Console.ReadKey();
    }
}

public class Number
{
    private PrintHelper _printHelper;

    public Number(int val)
    {
        _value = val;

        _printHelper = new PrintHelper();
        //subscribe to beforePrintEvent event
        _printHelper.beforePrintEvent += printHelper_beforePrintEvent;
    }
    //beforePrintevent handler
    void printHelper_beforePrintEvent(string message)
    {
        Console.WriteLine("BeforePrintEvent fires from {0}", message);
    }

    private int _value;

    public int Value
    {
        get { return _value; }
        set { _value = value; }
    }

    public void PrintMoney()
    {
        _printHelper.PrintMoney(_value);
    }

    public void PrintNumber()
    {
        _printHelper.PrintNumber(_value);
    }

}
public class PrintHelper
{
    public delegate void BeforePrintDelegate(string message);
    public event BeforePrintDelegate beforePrintEvent;

    public PrintHelper()
    {

    }

    public void PrintNumber(int num)
    {
        if (beforePrintEvent != null)
            beforePrintEvent.Invoke("PrintNumber");

        Console.WriteLine("Number: {0,-12:N0}", num);

    }

    public void PrintDecimal(int dec)
    {
        if (beforePrintEvent != null)
            beforePrintEvent("PrintDecimal");

        Console.WriteLine("Decimal: {0:G}", dec);
    }

    public void PrintMoney(int money)
    {
        if (beforePrintEvent != null)
            beforePrintEvent("PrintMoney");

        Console.WriteLine("Money: {0:C}", money);
    }

    public void PrintTemperature(int num)
    {
        if (beforePrintEvent != null)
            beforePrintEvent("PrintTemerature");

        Console.WriteLine("Temperature: {0,4:N1} F", num);
    }
    public void PrintHexadecimal(int dec)
    {
        if (beforePrintEvent != null)
            beforePrintEvent("PrintHexadecimal");

        Console.WriteLine("Hexadecimal: {0:X}", dec);
    }
}
于 2019-10-19T14:09:52.610 に答える