【问题标题】:Overloads Versus Overrides in VB.netVB.net 中的重载与覆盖
【发布时间】:2011-10-24 14:41:41
【问题描述】:

Other1Other2 类的 Previous 属性有哪些行为差异。

注意Other2 的重载Previous 属性的返回类型已更改为Other2,而Other1 仍为Base

Public Class Base
    Private _Previous as Base

    Protected Overridable ReadOnly Property Previous As Base
         Get
             Return _Previous 
         End Get
    End Property

    Public Sub New(Previous as Base)
         _Previous = Previous 
    End Sub
End Class

Public Class Other1
    Inherits Base
    Private _Parent as SomeType

    Protected Overrides ReadOnly Property Previous As Base
         Get
             Return _Parent.Previous.Something
         End Get
    End Property

    Public Sub New(Parent as SomeType)
        MyBase.New(Nothing)
        _Parent = Parent 
    End Sub
End Class

Public Class Other2
    Inherits Base
    Private _Parent as SomeType

    Protected Overloads ReadOnly Property Previous As Other2
         Get
             Return _Parent.Previous.Something
         End Get
    End Property

    Public Sub New(Parent as SomeType)
        MyBase.New(Nothing)
        _Parent = Parent 
    End Sub
End Class

【问题讨论】:

    标签: vb.net


    【解决方案1】:

    在我对Jim Wooley's answer 发表评论后,“它看起来像遮蔽了重载的属性。”我在this article看到了光。

    因此,Other2 类中的重载更像是阴影而不是覆盖。文章中有一个comments,特别有指导意义:

    之所以产生混淆,是因为关键字“重载”不是 C# 程序员认为的传统 OO 意义上的重载。这是 VB.Net 特有的一种隐藏方式。在大多数情况下,您实际上可以将关键字 SHADOWS 与 OVERLOADS 交换,并且行为是相同的。不同之处在于当您有一个具有多个重载方法签名的基类时。如果您在具有匹配名称和 SHADOWS 关键字的子类中声明方法,它将隐藏基类中该方法的每个重载。如果你改用 OVERLOADS 关键字,它只会隐藏具有相同签名的基类方法。

    【讨论】:

    • 听起来像Shadows 关键字很容易变成严重违反LSP。
    【解决方案2】:

    当您提供不同的输入参数时,通常会使用重载。覆盖替换功能。在您的情况下,您希望在 Other2 中覆盖而不是重载。虽然属性可以接受值以外的参数,但最好不要提供它们并在传递其他值时使用方法而不是属性:

    Public Class OldMath
       Public Overridable Function DoSomething(val1 As Integer) As Integer
           Return val1 + val1
       End Function
    End Class
    
    Public Class NewMath
       Public Overrides Function DoSomething(val1 As Integer) As Integer
          Return val1 * val1
       End Function
       Public Overloads Function DoSomething(val1 As Integer, val2 As Integer) As Integer
          Return val1 * val2
       End Function
    End Class
    

    【讨论】:

    • 我明白,但是 Overloads 允许将返回类型修改为 Other2,当引用声明为 Base 类型时,它的行为会像 Overridden Proprety 吗?
    • 覆盖也可用于添加除了覆盖方法之外的功能。很多时候,你会看到一个方法覆盖了一个基方法,但仍然调用它,因为它只需要为继承类添加一些东西。
    • @DavRob60 您不能重载返回类型,只能重载输入参数。如果您的输入参数不同并且您的返回类型不同,则将调用的参数将基于调用参数的最佳匹配,使用缩小约定来确定最佳匹配。
    • @JimWooley 你可以重载返回类型,如果你按照我在Other2 中的方式来做。我已经知道为什么/如何以及何时有人通常想要重载或覆盖属性/子/函数。我想解释的是它在这种特殊情况下的工作原理。
    • 尝试添加 Option Strict On 并查看您的代码是否继续工作。它可能适用于您的情况,因为您延迟绑定结果。
    【解决方案3】:

    我在social.msdn.microsoft.com 论坛上找到了很好的解释。

    【讨论】:

      猜你喜欢
      • 2016-03-24
      • 1970-01-01
      • 2010-10-24
      • 2022-01-02
      • 2012-02-16
      • 2011-04-14
      • 2011-12-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多