假设我们有这些复选框:
这些方法:
我只想在选中相应的复选框时调用每个方法。代码可能如下所示:
void DoWork()
{
if (FooCheckBox.Checked)
{
Foo();
Console.WriteLine("Foo was called");
}
if (BarCheckBox.Checked)
{
Bar();
Console.WriteLine("Bar was called");
}
if (BazCheckBox.Checked)
{
Baz();
Console.WriteLine("Baz was called");
}
}
现在考虑使用3个复选框和3个方法,而不是更多。您如何重写上面的代码以使其更加DRY?
答案 0 :(得分:7)
我会说你提出的案例,保留原样;你不想在没有充分理由的情况下过度抽象,因为它可以使代码库不易维护。当然,语境很重要,而且最终还是一种判断力。
那就是说,我就是这样做的。创建一个集合,其中每个项目都包含控件和操作委托。然后循环并对每个项目执行逻辑。
var items = new KeyValuePair<CheckBox, Action>[] {
new KeyValuePair<CheckBox,Action>(FooCheckBox, Foo),
new KeyValuePair<CheckBox,Action>(BarCheckBox, Bar),
new KeyValuePair<CheckBox,Action>(BazCheckBox, Baz)
};
foreach (var item in items)
{
if (item.Key.Checked)
{
item.Value.Invoke();
Console.WriteLine("Invoked " + item.Value.Method.Name);
}
}
或者(可能?)更好地使用Linq:
items.Where(item => item.Key.Checked).ToList().ForEach(item => new {
item.Value.Invoke();
Console.WriteLine("Invoked " + item.Value.Method.Name);
});
答案 1 :(得分:6)
您可以使用词典来跟上哪些操作引用哪些复选框。然后你可以做以下事情:
foreach(KeyValuePair<CheckBox, Action> kvp in Dict)
{
if(kvp.Key.Checked)
kvp.Value.Invoke();
}
答案 2 :(得分:4)
为了简单起见,我会选择
void DoWork()
{
DoIfChecked(FooCheckBox, Foo, "Foo as Called");
DoIfChecked(BarCheckBox, Bar, "Bar as Called");
DoIfChecked(BazCheckBox, Baz, "Baz as Called");
}
void DoIfChecked(CheckBox checkBox, Action action, string message)
{
if (checkBox.IsChecked)
{
action();
Console.WriteLine(message);
}
}
但是你可以对消息部分做一些事情,如果它很简单,我可能会根据本地环境进行一些错误检查。
答案 3 :(得分:2)
可以通过以下方式完成:
void DoWork()
{
Func<Action, string, Tuple<Action, string>> toT =
(a, s) => new Tuple<Action, string>(a, s);
var map = new Dictionary<CheckBox, Tuple<Action, string>>
{
{FooCheckBox, toT(Foo, "Foo")},
{BarCheckBox, toT(Bar, "Bar")},
{BazCheckBox, toT(Baz, "Baz")},
};
foreach (var x in map.Keys)
if (x.Checked)
{
map[x].Item1();
Console.WriteLine(map[x].Item2 + " was called");
}
}
但我认为有时候不是很干很好。
答案 4 :(得分:0)
我会使用Dictionary
创建<CheckBox, Func>
并循环显示每个值:
Dictionary<CheckBox, Func> checkboxes = new Dictionary<CheckBox, Func>();
void Init()
{
checkboxes.Add(FooCheckBox, Foo);
checkboxes.Add(BarCheckBox, Bar);
checkboxes.Add(BazCheckBox, Baz);
}
void DoWork()
{
foreach (KeyValuePair<CheckBox, Func> checkbox in checkboxes)
{
if (checkbox.Key.Checked)
{
checkbox.Value();
Console.WriteLine("{0} was called", checkbox.Text);
}
}
}