2

在 WinForms 解决方案中,您有多个相同类型的控件。您需要为每个控件添加一个事件处理程序,并且当前事件处理程序将执行相同的操作。您不希望它们之间有任何差异。

例如:

ScheduledPatientsGrid.ProcessGridKey += ScheduledPatientsGrid_ProcessGridKey;
RecentPatientsGrid.ProcessGridKey += RecentPatientsGrid_ProcessGridKey;
RecentPatientsGrid.ProcessGridKey += RecentPatientsGrid_ProcessGridKey;

... 

private void ScheduledPatientsGrid_ProcessGridKey(object sender, KeyEventArgs e)
{
   ...
}

private void RecentPatientsGrid_ProcessGridKey(object sender, KeyEventArgs e)
{
   ...
}

private void PatientsGrid_ProcessGridKey(object sender, KeyEventArgs e)
{
   ...
}

现在是在如下所示的不同事件之间共享单个事件处理程序更好,还是像上面显示的代码示例中使用不同的事件处理程序更好?

ScheduledPatientsGrid.ProcessGridKey += ProcessGridKey;
RecentPatientsGrid.ProcessGridKey += ProcessGridKey;
RecentPatientsGrid.ProcessGridKey += ProcessGridKey;                


private void ProcessGridKey(object sender, KeyEventArgs e)
{
  ...
}

在接下来的页面中,微软似乎建议共享更好,但是我注意到自 .NET 2.0 以来他们没有更新它(即:Visual Studio 2008)

http://msdn.microsoft.com/en-us/library/4ac48519%28v=vs.90%29.aspx

在这种情况下,是否有提供最佳实践建议的指南?

4

3 回答 3

10

绝对会使用相同的方法。拥有多个完全相同的方法有什么可能的好处,但没有一个被命名来说明它的作用?

我个人厌恶source_EventNameVisual Studio 产生的约定。我更愿意给我的事件处理程序方法赋予有意义的名称,以说明它们的作用。然后当你在设计器中向下查看事件处理程序列表时,你可以看到当一个按钮被单击时,X 会发生,而不是“按钮的单击事件处理程序将被调用”,这是没有用的。

或者,使用 lambda 表达式订阅事件并使用有意义的参数调用有意义的方法。(senderandargs通常对事件处理程序无用。)

于 2012-06-21T20:22:53.687 回答
1

在这种情况下,我通常让它们包装一个通用方法,但我会根据使用情况来命名它们的事件处理程序。这使我可以轻松地对该方法进行单元测试并(通常)减少所需的参数,并且堆栈跟踪中的任何错误对于进程失败的网格都是非常易读的:

ScheduledPatientsGrid.ProcessGridKey += ScheduledPatientsGrid_ProcessGridKey;
RecentPatientsGrid.ProcessGridKey += RecentPatientsGrid_ProcessGridKey;
RecentPatientsGrid.ProcessGridKey += RecentPatientsGrid_ProcessGridKey;

... 

private void ScheduledPatientsGrid_ProcessGridKey(object sender, KeyEventArgs e)
{
   ProcessGridKey(e.Key);
}

private void RecentPatientsGrid_ProcessGridKey(object sender, KeyEventArgs e)
{
   ProcessGridKey(e.Key);
}

private void PatientsGrid_ProcessGridKey(object sender, KeyEventArgs e)
{
   ProcessGridKey(e.Key);
}

private void ProcessGridKey(Key e)
{
    ...
}

您的里程可能会因共享方法的作用或传入的参数而异。(例如,在我上面的示例中,我复制了KeyKeyEventArgs.

于 2012-06-21T20:24:31.947 回答
0

我更喜欢分享,如果逻辑失控,您始终可以将单个事件用作正确方法的路由器,例如...

private void ProcessGridKey(object sender, KeyEventArgs e)
{
     if (sender is x)
          xmethod();
     if (sender is y)
          ymethod();    //etc 
}

我知道这种语法不太有意义,因为在 OP 示例中发送者将始终是同一个对象,但你明白了。

于 2012-06-21T20:23:30.507 回答