LoginSignup
33
31

More than 5 years have passed since last update.

C#6.0時代のイベント実装方法

Posted at

はじめに

C#6.0では、以前から望まれていた機能が多く実装され、以前よりも「かゆいところに手が届く」言語になりました。それによって、以前は意外と面倒だったイベントの実装も、C#6.0からはスマートに実装できるようになりました。

本投稿では、C#6.0時代のスマートなイベント実装方法を解説します。

従来のやり方

データを持たないイベント

public event EventHandler MyEvent;
protected virtual void OnMyEvent(EventArgs e)
{
  if(e != null)
    MyEvent(this, e);
}

データを持つイベント

public event EventHandler<MyEventArgs MyEvent;
protected virtual void OnMyEvent(MyEventArgs e)
{
  if(e != null)
    MyEvent(this, e);
}

c#6.0時代のイベント

データを持たないイベント

public event EventHandler MyEvent;
protected virtual void OnMyEvent()
{
  MyEvent?.Invoke(this, EventArgs.Empty);
}

データを持つイベント

public event EventHandler<MyEventArgs MyEvent;
protected virtual void OnMyEvent(MyEventArgs e)
{
  MyEvent?.Invoke(this, e);
}

解説

C#6.0でのイベントの実装は、null条件演算子の登場によって簡潔になりました。

まずは、C#6.0とは関係ない部分ではありますが、OnMyEventの引数について。イベントがデータを持つ必要がない場合、EventArgsを使用することになります。この場合、EventArgsをわざわざ引数に取る必要はなく、EventArgs.Emptyを使用すれば十分です

new EventArgs()を使用してもよいのですが、EventArgs.Emptystatic readonlyなフィールドであり、インスタンスを一つしか作成しないため、こちらのほうがパフォーマンスに優れています。

次に、今回のメインとなるnull条件演算子についてです。null条件演算子は単なるメンバへのアクセスに非常に似ていおり、違いは、レシーバがnullの場合にメンバへのアクセスを行わずnullを返す、ということのみです。これにより「nullでなければxxxする」という処理が完結に記述できるようになりました。

// C#6.0より前
if(obj != null)
  obj.hoge()
// C#6.0
obj?.hoge()

しかし、イベントの呼び出しはMyEvent(e)のように行うため、このままではnull条件演算子が使用できません。これに対する解決策は以下の二通りが考えられます。なお、ReSharperが後者のコードを生成するため、私は後者を使用しています。

this?.MyEvent(e)
MyEvent.Invoke(this, e);

まとめ

ここで紹介したように、C#6.0からはイベントが簡潔に実装できるようになりました。C#6.0には他にも、例外フィルタや自動実装プロパティの初期化など、ちょっと面倒だったコードが簡潔に記述できるようになりました。

まずます便利になったC#で、楽しいプログラミングライフを!

33
31
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
33
31