为什么子类不能同时实现接口和处理事件?

4
为什么一个子类不能同时实现接口和处理事件?
以下代码会出现语法错误:
Sub MySub() Handles MyButton.Click Implements MyInterface.MyMethod
End Sub

我知道我可以用另一种方法处理这种逻辑,但这不是重点。我只想了解背后的原因。

1
大多数.NET编码规范指定接口应以大写字母I作为前缀,以表示它们是接口(并有助于将其与类区分开来)。因此,您的接口实际上将被称为IMyInterface - Cody Gray
当然,但那不是重点 :) - codymanix
2个回答

4
语法错误与语言语法一致,在VB语言规范的§9.2.1中(注1):
SubDeclaration ::= [Attributes] [ProcedureModifier+] SubSignature [HandlesOrImplements] LineTerminator Block End Sub StatementTerminator 并且
HandlesOrImplements ::= HandlesClause | ImplementsClause 所以,在任何一个方法上只支持一个。 规范(快速查看)没有包括此限制的原因。 如果需要这方面的信息,您需要与微软的VB语言设计团队联系。
注1:这是在VS安装的‹VSRoot›\VB\Specifications\1033下包含的。

3
我从未见过任何关于VB.NET团队做出这个决定的详细讨论,但说实话,我很难从面向对象设计的角度看出这有什么意义。事件处理程序方法通常不应该执行任何工作。相反,它们应该调用其他方法来完成重要的工作。它们调用的另一个方法将是实现您接口的方法。
但如果你这样做,它肯定是可行的:
Public MustInherit Class MyParentClass
    Protected WithEvents MyButton As Button

    Protected MustOverride Sub MySub() Handles MyButton.Click
End Class

Public Class MyDerivedClass : Inherits MyParentClass : Implements IMyInterface
    Protected Overrides Sub MySub() Implements IMyInterface.MyMethod
        ' Do something here...
    End Sub
End Class

还要记住,事件处理程序方法通常具有独特的签名; 类似于以下内容:
Public Sub MySub(ByVal sender As System.Object, ByVal e As System.EventArgs)

这也是为什么事件处理程序方法很难同时实现接口定义方法的另一个原因。

不清楚你从哪里得到了“事件处理程序方法通常不应该执行任何工作”的说法。然而,一个微不足道的转发方法将被内联(除非设置了调试)。 - Richard
我不想失礼,但我明确表示我不想听任何关于代码示例的意见,而是想要理解微软在这里的推理。 - codymanix
1
@Richard:嗯,那是一个相当普遍的设计原则。我听过很多人以各种理由拥护它。然而,基本的理由是,在事件处理方法中放置大量实现代码会使代码与UI紧密地耦合在一起。由于*这通常被认为是不良实践,因此可以说,事件处理程序应调用包含逻辑或算法的其他方法。 - Cody Gray
1
@Richard:啊,我懂你的想法了。答案不一定是肯定的。我只是假设这是 UI 代码,因为我有90%的时间都在那里工作。确实,在其他地方这样做可能也有道理。我不是那种坚决遵守设计范畴“规则”的人。从婴儿时期起,我就认为规则应该相当灵活。 - Cody Gray
@CodyGray:明白了-这就是我提出疑问的原因。赞成“我不是那种严格遵守设计规则的人”:每个规则都有例外。 - Richard
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接