用于将操作应用于不同数量的对象的C#语法

And*_*ker 13 c#

我想要做的是将lambda语法与"params"结合起来对一系列对象执行操作.

假设我想让一堆控件不可见.

经过一番摆弄后,我最终得到了一个扩展方法:

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

然后我可以创建一个动作:

Action<Control> makeInvisible = c => c.Visible = false;
Run Code Online (Sandbox Code Playgroud)

然后调用它:

makeInvisible.On(control1,control2, control3,control4);
Run Code Online (Sandbox Code Playgroud)

这不是很好的语法 - 它感觉非常笨拙.

我可以在我的基类中创建一个方法"Apply":

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

然后像这样调用它:

Apply<Control>(
    c => c.Visible = false,
    control1,
    control2,
    control3,);
Run Code Online (Sandbox Code Playgroud)

但这意味着在我需要的每个基类中重复该方法,并且我失去了类型推断的优势.

这样做有一种不那么笨拙的方式吗?

编辑:到目前为止我见过的最好的方法是流畅的方法,(通过一些调整)将允许我写:

Apply.Method((Control c) => c.Visible = false).To(
    control1, 
    control2, 
    control3, 
    control4};
Run Code Online (Sandbox Code Playgroud)

这是91个字符,而使用简单的"foreach"则为107个字符.这让我相信"foreach"可能实际上是最好的方法!

p.s*_*w.g 7

您可以使用这样的扩展方法:

static void ForEach<T>(this IEnumerable<T> items, Action<T> action)
{
    foreach (var item in items)
    {
        action(item);
    }
}
Run Code Online (Sandbox Code Playgroud)

然后把它称为:

new Control[] { control1, control2, control3 }.ForEach(makeInvisible);
Run Code Online (Sandbox Code Playgroud)

或者干脆

new Control[] { control1, control2, control3 }.ForEach(x => x.Visible = false);
Run Code Online (Sandbox Code Playgroud)

如果control1..n所有类型相同,则可以省略基类:

new[] { control1, control2, control3 }.ForEach(x => x.Visible = false);
Run Code Online (Sandbox Code Playgroud)

  • 老实说,我不明白这种语法是如何更好的. (4认同)
  • @Romoku这只是一个选择.哪种语法"更好"只是风格问题. (4认同)

D S*_*ley 4

为什么不将其作为常规静态方法而不是扩展来调用呢?

public static class Apply
{
    public static void To<T>(this Action<T> actionToCarryOut,params T[] listOfThings)
    {
        foreach (var thing in listOfThings)
        {
            actionToCarryOut(thing);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

然后像这样调用它:

Apply.To<Control>(c => c.Visible = false,control1,control2, control3,control4);
Run Code Online (Sandbox Code Playgroud)

编辑

这是使用 Fluent 语法的版本:

public class Apply<T>
{
    private Action<T> _action;

    public Apply(Action<T> action) { _action = action; }

    public static Apply<T> Method(Action<T> actionToCarryOut)
    {
        return new Apply<T>(actionToCarryOut);
    }

    public void To(params T[] listOfThings)
    {
        foreach (var thing in listOfThings)
        {
            _action(thing);
        }
    }

}
Run Code Online (Sandbox Code Playgroud)

用法:

Apply<Control>.Method(c => c.Visible = false).To(control1,control2, control3,control4);
Run Code Online (Sandbox Code Playgroud)