对VB/C#与事件处理程序的转换感到困惑

本文关键字:转换 程序 VB 事件处理 | 更新日期: 2023-09-27 18:26:45

我几乎使用了所有的转换工具来将VB.NET片段转换为C#。除了转换中的一些差异之外,我很难理解的一件事是事件处理程序转换。看看一些纯C#代码,我看到了这样的东西:

protected override void OnPreRender(EventArgs e)
{
    base.OnPreRender(e);
    ...
}

它查看MSDN,引发PreRender事件。好的。现在,取一些VB.NET代码:

Private Sub Page_PreRender(ByVal sender As Object, 
    ByVal e As System.EventArgs) Handles Me.PreRender
....
EndSub

它处理相同的PreRender事件,并使用转换工具对其进行转换(DeveloperFusion似乎提供了事件处理程序中最干净的转换),得到了以下结果:

public class MyClass : UserControl
{
    private void Page_PreRender(object sender, System.EventArgs e)
    {
        ...
    }
    public MyClass()
    {
        PreRender += Page_PreRender;
    }
}

作为新手,我的主要问题是,上面第一个列出的原始(或纯)C#代码是否与转换后的C#代码基本相同(除了object sender部分)?如果没有简短的解释,我们将不胜感激。

从本质上讲,我只是想知道PreRender += Page_PreRender;部分是否多余。

对VB/C#与事件处理程序的转换感到困惑

第一个C#代码块显示基类的OnPreRender函数的覆盖,而第二个是PreRender事件的事件处理程序。

是的,它们是不同的,但在功能上它们或多或少是等价的,因为正如您所提到的,基类OnPreRender函数将触发PreRender事件。

从本质上讲,它代表了完成同一件事的两种方法,而您选择的机制主要是语义问题。我这么说主要是因为选择一种方法而不是另一种方法可能有明确的理由,但如果你不知道,就选择一种。

我自己更喜欢覆盖,因为您通常使用事件向外部侦听器广播通知,而不是向对象的派生实例广播通知。

PreRender += Page_PreRender在您的示例中并不是多余的,因为在使用该机制时需要连接事件处理程序。您发布的VB版本是使用事件而不是重写实现的,因此转换是正确的。这些事件的"连线"在VB.net中是隐含的,所以在VB版本中找不到等效的语句。

PreRender += Page_PreRender;部分是多余的吗?

否-该代码是C#分配事件处理程序的方法,这是在VB中用Handles Me.PreRender子句完成的。

转换是正确的,但它等同于原始C#:

在MSDN中,引发PreRender事件。

原始代码不是一个处理程序,而是一个调用程序。调用CCD_ 10以提升CCD_。如果VB代码在Page_PreRender中引发PreRender,则会导致无限递归。

可重写的"On[事件名称]"模式用于允许子类"处理"事件,但它与处理程序不同。对base/MyBase的调用实际上引发了事件,因此,通过重写其中一个方法,实际上是在强制操作完全发生在调用所有事件处理程序之前或之后(取决于调用基础的位置)。

作为一名n00b,我的主要问题是原件(或pure)C#代码基本上与转换后的C#代码。

是的,转换工具是对的!


解释

VB.NET的HandlesPreRender += Page_PreRender;是等价的。

CCD_ 18在后台基本上做了完全相同的事情;添加事件处理程序。

因此,Codesnippet#1Codesnippet#2是相同的,只是您需要在#2中自己管理处理程序(就像在Windows窗体被处理时删除处理程序一样)。

代码片段#1(VB.NET)

Private Sub Page_PreRender(ByVal sender As Object, 
    ByVal e As System.EventArgs) Handles Me.PreRender
....
End Sub

代码片段#2(VB.NET)

AddHandler Me.PreRender, AddressOf Page_PreRender

很明显,转换后的代码都不是多余的。