首先,尝试重构公共功能并使用委托
(请原谅我对“Dolistaction”这样的名字选择不当):
readonly Action<Process> removeBreakpoint = p => p.RemoveBreakpoint();
readonly Action<Process> addBreakpoint = p => p.AddBreakpoint();
void DoSingleAction(Action<Process> action)
{
var p = GetProcess(viewer);
if(p != null)
{
action(p); //invokes the action
BeginRefresh(null,null);
}
}
void DoListAction(Action<Process> action)
{
lvwProcessList.ForEach(action);
BeginRefresh(false, false);
}
private void ctxgrphAddBreakpoint_Click(object sender, EventArgs e)
{
DoSingleAction(addBreakpoint);
}
private void ctxgrphRemoveBreakpoint_Click(object sender, EventArgs e)
{
DoSingleAction(removeBreakpoint);
}
private void ctxlistAddBreakpoint_Click(object sender, EventArgs e)
{
DoListAction(addBreakpoint);
}
private void ctxlistRemoveBreakpoint_Click(object sender, EventArgs e)
{
DoListAction(removeBreakpoint);
}
然后可以统一doProcessAction和dolisaction:
void DoAction(object sender, Action<Process>)
{
if(sender is ListView)
{
lvwProcessList.ForEach(action);
BeginRefresh(false, false);
}
else if (sender is GraphView)
{
var p = GetProcess(viewer);
if(p != null)
{
action(p); //invokes the action
BeginRefresh(null,null);
}
}
else {throw new Exception("sender is not ListView or GraphView");}
}
//and update all the handlers to use this, and delete DoSingleAction and DoListAction:
private void ctxgrphAddBreakpoint_Click(object sender, EventArgs e)
{
DoAction(sender, addBreakpoint);
}
//etc.
不管怎样,在每个事件处理程序中,我认为您必须指定要采取的操作。在这种情况下,我不确定继承或扩展方法是否真的是您的朋友,但下面是使用扩展方法的情况:
//these two are in a separate static class
public static InvokeAction(this ListView listView, Action<Process> action)
{ ... }
public static InvokeAction(this GraphView listView, Action<Process> action)
{ ... }
private void handler(object sender, Action<Process> action)
{
var lv = sender as ListView;
var gv = sender as GraphVeiw;
lv.InvokeAction(action); //(need to check for null first)
gv.InvokeAction(action);
if(lv == null && gv == null) {throw new Exception("sender is not ListView or GraphView");}
}
//then update all the handlers:
private void ctxgrphAddBreakpoint_Click(object sender, EventArgs e)
{
handler(sender, addBreakpoint);
}
C 2/.NET 2
要在C 2(VS2005)中实现这一点,使用委托的第一种方法仍然有效,您不能使用lambda。(2.0具有
Action<T>
代表)。只需将lambda更改为函数即可。其他一切都会正常工作。
void removeBreakpoint(Process p) { p.RemoveBreakpoint(); }
void addBreakpoint(Process p) { p.AddBreakpoint(); }
//you could also do this, but it's overkill:
readonly Action<Process> removeBreakpoint = delegate(Process p) { p.RemoveBreakpoint(); };
readonly Action<Process> addBreakpoint = delegate(Process p) { p.AddBreakpoint(); };