変数の最大値/最小値を定義する2

biacさんからツッコミがあったので、その2に追記します。

1行で0以上479以下の範囲に変数のとる値を抑える構文を1行で書くならば、

t = Math.Max(minvalue, Math.Min(t, maxvalue)

で可能です。2回Math.を書くのが何か嫌だったのと、一目ではやりたいことが
わかりにくいのかなぁという危惧があったので躊躇しました。
更に、拡張メソッドを使って下のようにする方法もあります。

namespace GpExt {
    public static class GpFilter {
        public static int CutOff(this int target ,int minvalue, int maxvalue) {
            return Math.Max(minvalue, Math.Min(target, maxvalue));
        }
    }
}

と定義したうえで、対象とするtに対して
t = t.CutOff(0, 479);

ただし、拡張メソッドにしてしまうと定義位置が遠くなってしまって見づらいという危惧があります。
そこで、こんな解決方法を考えて見ました。

            const int MinVal = 0;
            const int MaxVal = 479;
            Func<int, int> coff = (target) => Math.Max(MinVal, Math.Min(target, MaxVal));

            t = coff(t);

実際に使用する場所の近い位置で定義できるので、定義内容は見やすくなります。
ただし、coff(t)と、t.CutOff() を比べた場合、処理の流れが左から右に流れるイメージで
扱いたいときには、t.CutOff()の方が綺麗に見えます。

ここまでは、普通の展開であると思います。
ここからは、最近少し悩んでいる内容です。
より実践的なコードを考えたます。X座標とY座標でCutOffしたいと考えます。
最大値・最小値の定数を4つ持つことになるわけです。Func にしてしまえば、
対応できますが、その方向で使用すること、引数に範囲を毎回いれていくことは作業ミスを
誘発しやすい内容になります。
そこで、思い切った書き方に変えてみます。

            Func<int, int> Xcoff = (target) => Math.Max(0, Math.Min(target, 479));
            Func<int, int> Ycoff = (target) => Math.Max(0, Math.Min(target, 799));

定数値をFuncに埋め込んでしまいました。
メソッドの定義部でFuncを定義するという概念で考えれば、強引ですが辻褄は合いそうです。
これが4パターン程度必要になるならば、Func<>を2段にしてもいいのかもしれません。
結局のところ、実践で使ったときのスコープと頻度を考えて、よりすっきりできる方向の記述を採用することになると思います。

  1. No Comments