1 | public Control GetParentParent(Control control) |
インスタンスメソッドを呼び出すときに気をつけないといけないことのひとつにオブジェクトがnullかどうかをチェックしなければならないことがあります。チェックを怠るとNullReferenceExceptionが発生してしまいます。しかし、nullチェックをするとコード行数が増え、見通しが悪くなります。
例えばコントロールの親の親を取得するメソッドGetParentParent
はおおよそ右のコードになります。親の親に該当するものがなければnullを返します。オブジェクトをたくさんたどればそれだけ条件分岐が増えていきます。
1 | public static void _<T>(this T obj, Action<T> action) |
これを簡単に書くためにちょっとしたヘルパーメソッドを作成します。コードを短くするために名前をアンダースコアにしてあります。次の1つめの拡張メソッドはobj
がnullの場合action
を実行しません。ジェネリックを使っていますのでaction
とつじつまが合っていればどんな型でも渡せます。2つめのメソッドは値を返すものでobjがnullの場合func
を実行しないで返値の型TResult
の既定値を返します。TResult
がValueTypeでなければnullを返します。インスタンスメソッドの場合はオブジェクトがnullの場合にメソッド呼び出しができませんが、拡張メソッドは静的メソッドを第1引数のメソッド呼び出し形式で呼び出せるシンタックスシュガーに過ぎませんので引数obj
にnullが渡されてもエラーにならないのです。
1 | public Control GetParentParent(Control control) |
このヘルパーメソッドを利用するとGetParentParent
はLINQ同様メソッドチェーン1行で記述できます。
HaskellにはMaybeモナド、Delphi Prismにはコロン演算子がありますが、C#でも上記のヘルパーメソッドで簡潔に書けるようになります。
Visual Basicではアンダースコアが行連結文字になっていますので別の名前を付けなければなりません。
1 | public Control GetParentParent(Control control) |
C# 6.0 (Visual Studio 2015) では Null条件演算子
(?.)が導入されました。