かってにコードいじって自己満足に浸る(3) 別

手元に下記のようなメソッドがある。
身バレ防止でだいぶ簡略にしてあるが実物はもっと改装が深くて条件が複雑である

        public bool Judge(int p)
        {
            if (p == 4 || p == 7 || p == 13)
                return false;

            return true;
        }

別に動作には問題ないのだが機能追加でthis.value<40の場合には(p == 4 || p == 7 || p == 13)ではなく(p == 3 || p == 9)にする必要がある。
さて、どう改修したものか?

まず機能追加する前にやれることをやっておく。
比較対象を全部配列にうつしてContainsメソッドで判定する

        public bool Judge(int p)
        {
            int[] v = new[] { 4, 7, 13 }; //配列
            if(v.Contains(p)) //判定はContainsメソッドで
                return false;

            return true;
        }

これで今回の機能追加で変更する必要があるのはvの中身であろうということがうすうすわかる

        public bool Judge(int p)
        {
            int[] v = new[] { 4, 7, 13 };
            if (this.value1 < 40)  //vの中身を変更
                v = new[] { 3, 9 };

            if(v.Contains(p))
                return false;

            return true;
        }

v設定部分をメソッド抽出

        public bool Judge(int p)
        {
            int[] v = NewMethod1();

            if (v.Contains(p))
                return false;

            return true;
        }

        private int[] NewMethod1()
        {
            int[] v = new[] { 4, 7, 13 };
            if (this.value1 < 40)
                v = new[] { 3, 9 };
            return v;
        }

vをインライン化
NewMethod1()の中身を整理

        public bool Judge(int p)
        {
            if (NewMethod1().Contains(p))
                return false;

            return true;
        }

        private int[] NewMethod1()
        {
            if (this.value1 < 40)
                return new[] { 3, 9 };
            else
                return new[] { 4, 7, 13 };
        }

Judgeメソッドのreturn部分を整理

        public bool Judge(int p)
        {
            return !NewMethod1().Contains(p);
        }

        private int[] NewMethod1()
        {
            if (this.value1 < 40)
                return new[] { 3, 9 };
            else
                return new[] { 4, 7, 13 };
        }

かってにコードいじって自己満足に浸る(3)

手元に下記のようなメソッドがある。
身バレ防止でだいぶ簡略にしてあるが実物はもっと改装が深くて条件が複雑である

        public bool Judge(int p)
        {
            if (p == 4 || p == 7 || p == 13)
                return false;

            return true;
        }

別に動作には問題ないのだが機能追加でthis.value<40の場合には(p == 4 || p == 7 || p == 13)ではなく(p == 3 || p == 9)にする必要がある。

さて、どう改修したものか?

素直に書くと

        public bool Judge(int p)
        {
            if (this.value1 < 40)
            {
                if (p == 3 || p == 9)
                    return false;
            }
            else
            {
                if (p == 4 || p == 7 || p == 13)
                    return false;
            }
            return true;
        }

だが、if文が二手に分かれるのがいやなので動作を変えないように注意深く変更していく。

1 まずは比較対象を配列におさめる

            int[] v; //配列
            if (this.value1 < 40)
            {
                v = new int[] { 3, 9 };//配列
                if (p == 3 || p == 9)
                    return false;
            }
            else
            {
                v = new int[] { 4, 7, 13 };//配列
                if (p == 4 || p == 7 || p == 13)
                    return false;
            }
            return true;

2 条件判定部分をv.Contain(p)に置き換える

            int[] v;
            if (this.value1 < 40)
            {
                v = new int[] { 3, 9 };
                if (v.Contains(p)) //置き換えた
                    return false;
            }
            else
            {
                v = new int[] { 4, 7, 13 };
                if (v.Contains(p)) //置き換えた
                    return false;
            }
            return true;

3 if{}の中身およびelse{}の中身で共通する末端部分をくくりだす

            int[] v;
            if (this.value1 < 40)
            {
                v = new int[] { 3, 9 };
            }
            else
            {
                v = new int[] { 4, 7, 13 };
            }
            if (v.Contains(p)) //くくりだされました
                return false;
            return true;

4 vを設定している箇所をメソッドの抽出

        public bool Judge(int p)
        {
            int[] v = NewMethod1(); //抽出

            if (v.Contains(p))
                return false;
            return true;
        }

        private int[] NewMethod1() //抽出されました
        {
            int[] v;
            if (this.value1 < 40)
            {
                v = new int[] { 3, 9 };
            }
            else
            {
                v = new int[] { 4, 7, 13 };
            }

            return v;
        }

5 return部分がうっとうしいのでついでに書き換える
6 vをインライン化して消去

        public bool Judge(int p)
        {
            return !NewMethod1().Contains(p);
        }

        private int[] NewMethod1()
        {
            int[] v;
            if (this.value1 < 40)
            {
                v = new int[] { 3, 9 };
            }
            else
            {
                v = new int[] { 4, 7, 13 };
            }

            return v;
        }

かってにコードいじって自己満足に浸る(2)

手元に下記のようなメソッドがある。
身バレ防止でだいぶ簡略にしてあるが実物はもっと改装が深くて条件が複雑である。

        public void DoAnything()
        {
            if (value1 > 50)
            {
                if (value2 < 30)
                {
                    DoWrite();
                }
            }
        }

別に動作には問題ないのだが個人的にはDoWrite()を実行する条件をメソッドに切り出しておきたいなあ、と思うものである。
従って動作を変えないように注意深く変更していく。

1 まずはフラグ(flg)を用意

            bool flg = false; //フラグ
            if (value1 > 50)
            {
                if (value2 < 30)
                {
                    DoWrite();
                }
            }

2 DoWrite()直前でフラグを立てる

            bool flg = false;
            if (value1 > 50)
            {
                if (value2 < 30)
                {
                    flg = true;//フラグが立ったよ
                    DoWrite();
                }
            }

3 DoWrite()をif(flg){ }で囲う

            bool flg = false;
            if (value1 > 50)
            {
                if (value2 < 30)
                {
                    flg = true;
                    if (flg) //囲う
                    {
                        DoWrite();
                    }
                }
            }

4 if(flg)ブロックを一番外のifブロックの外に追い出す

            bool flg = false;
            if (value1 > 50)
            {
                if (value2 < 30)
                {
                    flg = true;
                }
            }
            if (flg) //追い出されました
            {
                DoWrite();
            }

5 flgの宣言~flgの値を決定している部分をVisualStudioの"メソッドの抽出"

            bool flg = NewMethod(); //メソッドにされてしもた
            if (flg)
            {
                DoWrite();
            }
        private bool NewMethod() //メソッドになりました
        {
            bool flg = false;
            if (value1 > 50)
            {
                if (value2 < 30)
                {
                    flg = true;
                }
            }

            return flg;
        }

6 bool flg = NewMethod();のflgをVisualStudioの"インラインの一時変数"(これVS2010にはないんだよなぁ)

            if (NewMethod())
            {
                DoWrite();
            }

7 完成なう

        public void DoAnything()
        {
            if (NewMethod())
            {
                DoWrite();
            }
        }

        private bool NewMethod()
        {
            bool flg = false;
            if (value1 > 50)
            {
                if (value2 < 30)
                {
                    flg = true;
                }
            }

            return flg;
        }


やってみての感想
・条件が変わったときにNewMethod()の中身だけを変更すればいいことが明確になる。

自己満足完了

かってにコードいじって自己満足に浸る

手元に下記のようなメソッドがある。
末尾returnを強制されてた人が書いたと思われる。
身バレ防止でだいぶ簡略にしてあるが実物はもっと改装が深くて条件が複雑である。

        public bool IsSuccess()
        {
            bool flg = false;
            if (value1 > 50)
            {
                if (value2 < 30)
                {
                    flg = true;
                }
            }
            return flg;
        }

別に動作には問題ないのだが個人的にはfalseになるのわかってるならさっさと脱出してほしいなあ、と思うものである。
従って動作を変えないように注意深く変更していく。

1-① 一番外側のif文にelse節をくっつける。

            bool flg = false;
            if (value1 > 50)
            {
                if (value2 < 30)
                {
                    flg = true;
                }
            }
            else //これつけた
            {

            }
            return flg;

1-② return flg;を一番外側のif節およびelse節の末尾に分配

            bool flg = false;
            if (value1 > 50)
            {
                if (value2 < 30)
                {
                    flg = true;
                }
                return flg; //これつけた
            }
            else
            {
                return flg; //これつけた
            }
            //これ消した return flg;

1-③ else節はfalseしか返さないのでreturn false;と書き換える

            bool flg = false;
            if (value1 > 50)
            {
                if (value2 < 30)
                {
                    flg = true;
                }
                return flg;
            }
            else
            {
                return false;//書き換えた
            }


1-④ 一番最初のif文の条件を反転させてif節とelse節の中身を入れ替える

            bool flg = false;
            if (!(value1 > 50)) //条件反転
            {//中身入れ替え
                return flg;
            }
            else
            {//中身入れ替え
                if (value2 < 30)
                {
                    flg = true;
                }
                return flg;
            }

1-⑤ else{ }を除去 ({}の中は消さない) ※if{}の末尾でreturnしているのでelse{ }があってもなくても同じことである

            bool flg = false;
            if (!(value1 > 50))
            {
                return false;
            }
            if (value2 < 30)
            {
                flg = true;
            }
            return flg;

2番目のif文についても1番目のif文と同じ作業を実施
 2-① else節をつける
 2-② return flg;をif節およびelse節の末尾に分配
 2-③ else節はfalseしか返さないのでreturn false;と書き換える
 2-④ 条件を反転させてif節とelse節の中身を入れ替える
 2-⑤ else{ }を除去 ({}の中は消さない)

            bool flg = false;
            if (!(value1 > 50))
            {
                return false;
            }
            if (!(value2 < 30))
            {
                return false;
            }
            flg = true;
            return flg;

2-⑥ 最後のreturnはtrueしか返さないのでreturn true;に書き換える。
2-⑦ 出番のなくなったflgを除去

            if (!(value1 > 50))
            {
                return false;
            }
            if (!(value2 < 30))
            {
                return false;
            }
            return true;

2-⑧ !(cond)を整理する
2-⑨ if文の中かっこを除去する

            if (value1 <= 50)
                return false;

            if (value2 >= 30)
                return false;

            return true;


やってみての感想
・"条件を反転させてif節とelse節の中身を入れ替える"と"!(cond)を整理する"は若干怖い作業だなと思う。誰か自動化してくれ。
・コードの動きは動画にしたほうが理解されやすいような気がする。
・条件をすっきりさせられた気がする。

自己満足完了

桜花賞なう

今日近所の阪神競馬場行ったんです。

そしたらなんか人がめちゃくちゃいっぱいでラチ沿いに行けないんです。

で、よくみたら桜花賞、とか書いてあるんです。

もうね、アホかと。馬鹿かと。お前らな、3歳牝馬限定OP芝マイル如きで普段来てない阪神競馬場来てんじゃねーよ、ヴォケが。
なんかカップルとかもいるし。二人で仁川かよ。うらやましいな。
よーしオレ武豊単勝買っちゃうぞー、とか言ってるの。もう見てられない。
おまえらな、ペグシルやるからそこ退け。
競馬場ってのはな、もっと殺伐としてるべきなんだよ。
はずれ馬券破ってばらまく奴といつ喧嘩が始まってもおかしくない、
万券取るかお馬で人生アウトか、そんな雰囲気がいいんじゃねーか。素人はすっこんでろ。

 

・・・・とは言いません。本日は多くの皆様に阪神競馬場にご来場ありがとうございますm(_ _)m。ついでに私の配当のために馬券をお買い上げいただきありがとうございます。皆様のはずれが私のあたりです。よろしくおながいいたします。

 

なんちって。

ヌルポとみせかけてヌルリ

ヌルポってC#ではヌルリ(NullReferenceException)なんだね。知ってても何の得もないけど。
それはともかく、ヌルp・・・もといヌルリで落ちるのは恥とでも思われているのか、やたらといたるところでNullチェックを強いられているコードが目の前にある。

    static class Checkers
    {
        public static bool IsNull(object p)
        {
            return p == null;
        }
    }

こんなのがあって、いたるところでCheckers.IsNull(Hoge)みたく使うことを強いられている。
それはまあいいのだが、このCheckers.IsNull(Hoge)の使い方でおやおや?とおもったのがint型のプロパティまでNullチェックしてること(↓コード)。
羹に凝りて膾を吹く、を地でいくような世界。

        private static void Proc2()
        {
            myclass m = new myclass();
            bool result2 = Checkers.IsNull(m.NonNullableValue);     //これはつねにfalse
            Console.WriteLine("{0}", result2);
        }

    class myclass
    {
        public int NonNullableValue { get; set; }
    }

まさかint型プロパティの持ち主のNullチェックもできるのか?とおもったが

        private static void Proc3()
        {
            myclass m2 = null;
            bool result2 = Checkers.IsNull(m2.NonNullableValue);    //ヌルリ
            Console.WriteLine("{0}", result2);
        }

ヌルリで落ちた。うーん、int型プロパティまでNullチェックしようとした人の気持ちがわからん。チェックに引っかかったケースの動作確認どうしたのだろう?

テストのお勉強。


Nanka.Hoge()の戻り値が10であることをテストする際の

Assert.AreEqual(10,Nanka.Hoge());

て書き方に慣れない。「10がNanka.Hoge()と等価である」と読んでしまう。
できうることなら引数を逆にして

Assert.AreEqual(Nanka.Hoge(),10);

と書きたいが戻り値が9だった場合、つまりテスト失敗したときのメッセージが
「<9> が必要ですが、<10> が指定されています。」
となってしまい、<10>のほうが間違ってるように読めてしまうのでまずい。

え?テスト失敗させなきゃいいんじゃんって?

んなあほな。

 

関係ないけどはちロケかわいいよね。あんな娘がいればもう・・・心配だな。

 

 

追記

なんで慣れないのかというと、if文では

if(Nanka.Hoge()==10)て書くじゃん。

if(10==Nanka.Hoge())て書いたらおかしいじゃん。

 

 

関係ないけどはちロケかw・・・もういいか。