我想要做的是将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"可能实际上是最好的方法!
您可以使用这样的扩展方法:
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)
为什么不将其作为常规静态方法而不是扩展来调用呢?
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)