13

私がやりたいのは、ラムダ構文と「params」を組み合わせて、一連のオブジェクトに対してアクションを実行することです。

たくさんのコントロールを非表示にしたいとしましょう。

少しいじった後、私は拡張メソッドになりました:

public static void On<T>(this Action<T> actionToCarryOut,params T[] listOfThings)
{
    foreach (var thing in listOfThings)
    {
        actionToCarryOut(thing);
    }
}

次に、アクションを作成できます。

Action<Control> makeInvisible = c => c.Visible = false;

そしてそれを呼び出します:

makeInvisible.On(control1,control2, control3,control4);

ただし、これはあまり良い構文ではありません。ひどくぎこちなく感じます。

基本クラスに「Apply」メソッドを作成できます。

protected void Apply<T>(Action<T> action, params T[] appliedTo)
{
    foreach (var item in appliedTo)
    {
        action(item);
    }
}

そして、次のように呼び出します。

Apply<Control>(
    c => c.Visible = false,
    control1,
    control2,
    control3,);

しかし、それはメソッドを必要とするすべての基本クラスでメソッドを繰り返すことを意味し、型推論の利点を失います。

これを行うための不器用な方法はありますか?

編集:これまでに見た中で最も優れた方法は流暢なアプローチであり、(いくつかの調整を加えて)次のように書くことができます:

Apply.Method((Control c) => c.Visible = false).To(
    control1, 
    control2, 
    control3, 
    control4};

単純な「foreach」を使用する場合の 107 文字と比較して、これは 91 文字です。結局のところ、「foreach」が実際には最良のアプローチであると私は信じています!

4

4 に答える 4

2

または、次のようにすることもできます。

control1.Visible = false;
control2.Visible = false;
control3.Visible = false;
control4.Visible = false;

これにより、コード行が少なくなり、実行が速くなります。ただし、例のケースよりも簡単ではないケースの拡張が必要な​​場合はどうですか。

public static void ForEach<T>(this IEnumerable<T> source, Action<T> action)
{
    foreach(var t in source)
    {
        action(t);
    }
}

次に、オリジナルを少し作り直すことができます

public static void Act<T>(Action<T> action, params T[] targets)
{
    targets.ForEach(action);
}

許可し、

Act(ctl => ctl.Visible = false, control1, control2, control3, control4); 

しかし、私はお勧めします

var controls = new[] { control1, control2, control3, control4 };

foreach (var control in controls)
{
    control.Visible = false;
}

どの拡張メソッドよりも読みやすいです。または、1 行にまとめると非常になじみがあります。

foreach (var control in new[] { control1, control2, control3, control4 })
    control.Visible = false;

これらの最後の例は、この一見便利な拡張機能がフレームワークから省略されている理由を示していると思います。

于 2013-07-16T13:12:57.303 に答える