C#と諸々

C#がメインで他もまぁ諸々なブログです
おかしなこと書いてたら指摘してくれると嬉しいです(´・∀・`)
つーかコメント欲しい(´・ω・`)

2010/06/25 01:08

ガード句っぽい選択

あー本題からそれてるような気もしますが。
あと型名勝手に変えちゃいましたが。

class Generation
{
    public static readonly Generation Over60  = new Generation(60, null);
    public static readonly Generation Over50  = new Generation(50, 59);
    public static readonly Generation Over40  = new Generation(40, 49);
    public static readonly Generation Over30  = new Generation(30, 39);
    public static readonly Generation Over20  = new Generation(20, 29);
    public static readonly Generation Under20 = new Generation(null, 19);

    public static Generation GetGeneration(int age)
    {
        return
            new[]
            {
                Over60,
                Over50,
                Over40,
                Over30,
                Over20,
                Under20,
            }
            .Single(item => item.IsIncludeing(age));
    }


    private Generation(int? lowerLimit, int? upperLimit)
    {
        LowerLimit = lowerLimit;
        UpperLimit = upperLimit;
    }

    public readonly int? LowerLimit;
    public readonly int? UpperLimit;

    public bool IsIncludeing(int age)
    {
        bool isWithinLowerLimit = LowerLimit.HasValue ? (LowerLimit <= age) : true;
        bool isWithinUpperLimit = UpperLimit.HasValue ? (age <= UpperLimit) : true;
        return isWithinLowerLimit && isWithinUpperLimit;
    }
}


元ネタにあるような特定の使い方だけしかしない内は、
こんなクラス化なんてやりすぎですが、
色々な使い方が出てきたときにはこういう方向に進んでいくことかと思います。

ついでに、Static フィールド の種類を増やす時に変更箇所が一箇所で済むよう
リフレクションとカスタム属性を導入してみます。

class Generation
{
    class ItemAttribute : Attribute { }

    [Item]public static readonly Generation Over60  = new Generation(60, null);
    [Item]public static readonly Generation Over50  = new Generation(50, 59);
    [Item]public static readonly Generation Over40  = new Generation(40, 49);
    [Item]public static readonly Generation Over30  = new Generation(30, 39);
    [Item]public static readonly Generation Over20  = new Generation(20, 29);
    [Item]public static readonly Generation Under20 = new Generation(null, 19);
    private static ReadOnlyCollection<Generation> _items = CreateItems();

    private static ReadOnlyCollection<Generation> CreateItems()
    {
        var query =
            from field in typeof(Generation).GetFields(BindingFlags.Static | BindingFlags.Public)
            where (field.IsDefined(typeof(ItemAttribute), false))
            select (field.GetValue(null) as Generation);

        return new ReadOnlyCollection<Generation>(query.ToList());
    }

    public static Generation GetGeneration(int age)
    {
        return _items.Single(item => item.IsIncludeing(age));
    }


    private Generation(int? lowerLimit, int? upperLimit)
    {
        LowerLimit = lowerLimit;
        UpperLimit = upperLimit;
    }

    public readonly int? LowerLimit;
    public readonly int? UpperLimit;

    public bool IsIncludeing(int age)
    {
        bool isWithinLowerLimit = LowerLimit.HasValue ? (LowerLimit <= age) : true;
        bool isWithinUpperLimit = UpperLimit.HasValue ? (age <= UpperLimit) : true;
        return isWithinLowerLimit && isWithinUpperLimit;
    }
}


若干やりすぎた感があります。


スポンサーサイト