null チェックをいちいち書かないで action を実行する方法

  • 1
    いいね
  • 1
    コメント

コード

public class Hoge() {

    public void Example() {
        Action            act   = null;
        Action<int>       act2  = null;
        Func<string>      func  = null;
        Func<int, string> func2 = null;
        UnityAction       uact  = null;
        UnityAction<int>  uact2 = null;

        // act(); // NullReferenceException

        act.NullSafe();
        act2.NullSafe( 1 );
        Debug.Log( "func:"  + func.NullSafe()   + ";" ); // "func:;"
        Debug.Log( "func2:" + func2.NullSafe(1) + ";" ); // "func2:;"
        uact.NullSafe();
        uact2.NullSafe( 1 );
    }
}

public static class ActionExtensions {

    public static void NullSafe( this Action action ) {
        if (action!=null) { action(); }
    }

    public static void NullSafe<T>( this Action<T> action, T arg ) {
        if (action!=null) { action(arg); }
    }
}

public static class FuncExtensions {

    public static TResult NullSafe<TResult>( this Func<TResult> func ) {
        return func!=null ? func() : default(TResult);
    } 

    public static TResult NullSafe<T, TResult>( this Func<T, TResult> func, T arg ) {
        return func!=null ? func(arg) : default(TResult);
    }
}

public static class UnityActionExtensions {

    public static void NullSafe( this UnityAction action ) {
        if (action!=null) { action(); }
    }

    public static void NullSafe<T>( this UnityAction<T> action, T arg ) {
        if (action!=null) { action( arg ); }
    }
}

経緯

Unity いじってて
if (action!=null) { action(); } って書くのめんどくせ
と思ったので拡張メソッドを書いた
が、ジェネリック部分で詰まったので例によって Stackoverflow を参考にした

http://stackoverflow.com/questions/872323/method-call-if-not-null-in-c-sharp

別に拡張しなくても
action?.Invoke()
という書き方ができるみたいだけど
これは C# 6.0 から使える書き方で、Unity では不可っぽいので素直に拡張しちゃおうね~

え? いちいち .NullSafe() とか書くのめんどい?
if 書くよりマシだろ!

備考

検索してる時は英語ページしかでてこなくて、なんでや!
と憤ったが
ひととおり記事を書き終わった後に日本語ページを見つけた

【C#】Actionデリゲートのnullチェックを省略するための拡張メソッド
http://baba-s.hatenablog.com/entry/2014/04/09/182626

そうか null チェックか・・・ それで検索すればよかったか・・・
俺はアホか・・・(´・ω・`)

あんまり関係ないおまけ

C# には ?? 演算子 とかいうのがある(読み方不明)
action が null の時、新しい action を代入しとく
という処理は
action = action ?? delegate { Debug.Log("action"); };
という感じで実現できる

今回の件に使えるかと思ったけど、別になにも使えなかった