C# 如何使这段代码更加枯燥?
假设我们有这些复选框:C# 如何使这段代码更加枯燥?,c#,dry,C#,Dry,假设我们有这些复选框: FooCheckBox BarCheckBox Bazzcheckbox 这些方法包括: 福 酒吧 巴兹 我只想在选中correponding复选框时调用每个方法。代码可能如下所示: void DoWork() { if (FooCheckBox.Checked) { Foo(); Console.WriteLine("Foo was called"); } if (BarCheckBox.Chec
- FooCheckBox
- BarCheckBox
- Bazzcheckbox
- 福
- 酒吧
- 巴兹
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个方法,你还有很多。您将如何重写上面的代码以使其更完整?您可以使用字典了解哪些操作引用了哪些复选框。然后您可以执行以下操作:
foreach(KeyValuePair<CheckBox, Action> kvp in Dict)
{
if(kvp.Key.Checked)
kvp.Value.Invoke();
}
foreach(Dict中的KeyValuePair kvp)
{
如果(kvp.Key.Checked)
Value.Invoke();
}
对于您介绍的案例,请保持原样;您不希望在没有充分理由的情况下过度抽象,因为这会降低代码库的可维护性。当然,背景很重要,这最终是一种判断
也就是说,我会这样做。创建一个集合,其中每个项都包含控件和操作委托。然后循环并对每个项目执行逻辑
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);
}
}
可以通过以下方式进行:
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");
}
}
void DoWork()
{
Func toT=
(a,s)=>新元组(a,s);
var-map=新字典
{
{FooCheckBox,toT(Foo,Foo”)},
{BarCheckBox,toT(Bar,“Bar”)},
{Baz,toT(Baz,Baz”)},
};
foreach(map.Keys中的变量x)
如果(x.Checked)
{
map[x].Item1();
Console.WriteLine(调用了map[x].Item2+);
}
}
但我认为有时不太干燥也可以。我会创建一个
字典,其中包含
并循环遍历每个值:
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);
}
}
}
字典复选框=新建字典();
void Init()
{
复选框。添加(FooCheckBox,Foo);
复选框。添加(条形复选框,条形);
复选框。添加(BazCheckBox,Baz);
}
无效销钉()
{
foreach(复选框中的KeyValuePair复选框)
{
if(checkbox.Key.Checked)
{
checkbox.Value();
WriteLine(“{0}被调用”,checkbox.Text);
}
}
}
为了简单起见,我会选择
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);
}
}
但是,如果消息部分这么简单,您可以对它做些什么,我可能会根据本地上下文进行一些错误检查。Action
表示没有参数,并将void作为返回类型。@odyodys OP.Correct建议的3种方法也是如此。他的方法调用不包含任何参数或返回类型。尽管如果需要的话,您可以很容易地用函数代替动作。更适合于像这样的代码改进问题。
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);
}
}