読者です 読者をやめる 読者になる 読者になる

名脇役、拡張メソッドを携えて

f:id:yukk_laz:20161023205555p:plain

C#です。こういう、しれっとした拡張メソッドが好きです。

 

文字列を変換して数値にするんだから、文字列型あたりにありそうですよねParse。実際はint.Parse(string);だったりしてヘンテコな感じ。しかも出来たかエラーを検出するにはoutを使わないといけないというなんか微妙なint.TryParse();というまたヘンテコな感じ。だったら作ったほうがいいでさあねえ?

しれっとね、変換して、できなかったらデフォルトの値を代わりに代入したりとかね、してほしいですよね。うむ。

 

public static class IntExtention

{
    public static int Parse(this string tryParseText, int defaultvalue)
    {
        int parseExec; //初期化しなくても動くし、そのほうが代入少なくて済む
        if(int.TryParse(tryParseText, out parseExec))
        {
            return parseExec;

        }
        else
        {
            return defaultvalue;
        }
    }
}

先ほどの画像とほぼ一緒のコードですが、こんなんが利用例になります。

 

任意の静的クラスに、静的メソッドを書くだけなのですが、第一引数にthisをつけると、例えば今回でいうと、第一引数がthis stringとなっているので、『"1145141919810".Parse(810)』みたいに呼び出せます。これが拡張メソッドというやつです。もちろん、拡張メソッド自体はただの静的メソッドと同じようにも扱えます。

しかし欠点があって、拡張メソッドを置く静的クラスを名前空間直下に置く必要があり、名前空間直下ではアクセシビリティはpublicかinternalしか指定できません。必然的にスコープがバカでかく、コードが読みづらくなるので、バグを生みかねません。拡張メソッドを作る場合、拡張メソッド用の名前空間を新しく用意して、そのメソッドを使うところだけその名前空間を呼び出すようにして、できる限りスコープを狭める。それから、メソッドの名前を正確にして、読む・使う側の人にメソッドの意図や動作方法を伝えることが重要ですね。

拡張メソッドを使うと何がいいかと言えば、主語→述語という順番になってなにやってるかがわかりやすいのと、同じメンバに何回も操作をしたいときになんとか.関数.関数.拡張メソッド.関数みたいなツリーを作っても操作手順が透明になったり、LINQの式を並べたときに見た目が揃ったりします。特に二番目のメリットは重大です。

 

System.IO.File.ReadAllText(System.IO.Path.Combine("hoge".Replace("").Trim(""), "\\hogehoge.txt"));

とかカッコやらなんやら、動作する順番がわからなくなってバグが紛れても気づきにくい。これはまだカッコとか少ない方ですが、拡張メソッドCombineを作っておきさえすれば、

"hoge".Replace("").Trim("").Combine("\\hogehoge.txt")

こんな風にたらいまわしにされる様子が鮮やかに。スコープの広さゆえに嫌われやすい文化ですが、使った方がいい場面で使えれば気持ちいいくらい効果てきめんだったりするので、おもしろいものです。おためしを。