イベントによるクラス間通信

2023年2月22日

引数を渡さない

コード

Sender sender = new Sender();
Receiver receiver = new Receiver(sender);

sender.SendMessage("Hello, world!");

public class Sender
{
    // イベントを宣言する
    public event EventHandler<EventArgs> OnSend;

    public void SendMessage(string message)
    {
        Console.WriteLine($"Sender: {message}");

        // 登録されたイベントハンドラを呼び出す
        OnSend?.Invoke(this, EventArgs.Empty);
    }
}

public class Receiver
{
    public Receiver(Sender sender)
    {
        // イベントハンドラを登録する
        sender.OnSend += OnMessageReceived;
    }

    private void OnMessageReceived(object sender, EventArgs e)
    {
        Console.WriteLine("Receiver: Message received");
    }
}

実行結果

Sender: Hello, world!
Receiver: Message received

SenderクラスはOnSendというイベントを宣言しています。SendMessageメソッドが呼ばれたとき、OnSendイベントに登録されているイベントハンドラを呼び出します。

Receiverクラスは、Senderクラスのインスタンスを引数として受け取り、そのSenderクラスのOnSendイベントに自身のOnMessageReceivedメソッドを登録します。OnMessageReceivedメソッドは、Senderクラスからメッセージが送信されたときに呼び出され、"Receiver: Message received"というメッセージをコンソールに出力します。

最後に、Senderクラスのインスタンスを作成し、それを引数としてReceiverクラスのインスタンスを作成します。そして、SendMessageメソッドを呼び出し、"Hello, world!"というメッセージを送信します。ReceiverクラスのOnMessageReceivedメソッドが呼び出され、"Receiver: Message received"というメッセージが表示されます。

このように、イベントハンドリングを使うことで、異なるクラス間でコードを疎結合にすることができます。SenderクラスはReceiverクラスの存在を知らずに、メッセージを送信することができます。また、ReceiverクラスはSenderクラスの内部実装を知る必要がなく、単にOnMessageReceivedメソッドを実装するだけで、Senderクラスから送信されたメッセージを受け取ることができます。

int型の引数を渡す

コード

Sender sender = new Sender();
Receiver receiver = new Receiver(sender);

sender.SendMessage("Hello, world!");

public class Sender
{
    // イベントを宣言する
    public event EventHandler<int> OnSend;

    public void SendMessage(string message)
    {
        Console.WriteLine($"Sender: {message}");

        // 登録されたイベントハンドラを呼び出す
        OnSend?.Invoke(this, 3);
    }
}

public class Receiver
{
    public Receiver(Sender sender)
    {
        // イベントハンドラを登録する
        sender.OnSend += OnMessageReceived;
    }

    private void OnMessageReceived(object sender, int e)
    {
        Console.WriteLine($"Receiver: Message received {e}");
    }
}

実行結果

Sender: Hello, world!
Receiver: Message received 3

eventは、C#でイベントを実装するためのキーワードです。EventHandler<T>は、イベントの型の1つで、Tにはイベントに渡されるデータの型が指定されます。EventHandler<T>は、以下のように定義されます。

public delegate void EventHandler<TEventArgs>(object sender, TEventArgs e);

EventHandler<T>は、2つの引数を受け取ります。最初の引数は、イベントが発生したオブジェクトであり、通常はthisを指定します。2番目の引数は、イベントに関連するデータであり、Tで指定された型のオブジェクトです。

例えば、以下のようなイベントがあるとします。

public event EventHandler<int> OnCountChanged;

OnCountChangedは、引数としてint型のデータを受け取るイベントです。OnCountChangedを発生させるときは、以下のように呼び出します。

OnCountChanged?.Invoke(this, 10);

この例では、OnCountChangedイベントが発生したオブジェクトはthisであり、受け取るint型のデータは10です。イベントを受け取る側は、以下のように記述します。

public void HandleCountChanged(object sender, int e)
{
    Console.WriteLine($"Count changed to {e}.");
}

// OnCountChangedイベントを受け取るためのハンドラを登録
OnCountChanged += HandleCountChanged;

HandleCountChangedメソッドは、OnCountChangedイベントが発生したときに呼び出されます。最初の引数にはイベントが発生したオブジェクト、2番目の引数にはイベントに関連するデータが渡されます。

C#,イベント,学習

Posted by hidepon