尽管使用 Overridable/Overrides,实现 ToString 不会覆盖原始的 ToString 方法。我想念什么?

Implementing ToString does not override the original ToString method despite using Overridable/Overrides. What do I miss?

我想,VB 的 OverridableOverrides 说明符并不像我想象的那样起作用。

其他 类 继承了 3 代:GrandfatherFatherTestOverrides

Public Interface IElements
    Function ToString() As String
End Interface

Public Class Grandfather
    Implements IElements
    Private _MyArg As String
    Public Sub New(Arg As String)
        _MyArg = Arg
    End Sub
    Public Overridable Function IElements_ToString() As String _
        Implements IElements.ToString
        Return _MyArg
    End Function
End Class

Public Class Father
    Inherits Grandfather
    Implements IElements
    Public Sub New(Arg As String)
        MyBase.New(Arg)
    End Sub
    Public Overrides Function IElements_ToString() As String _
        Implements IElements.ToString
        Return MyBase.ToString
    End Function
End Class

Public Class TestingOverrides
    Inherits Father
    Implements IElements
    Public Sub New(Arg As String)
        MyBase.New(Arg)
    End Sub
    Public Overrides Function IElements_ToString() As String _
        Implements IElements.ToString
        Return MyBase.ToString
    End Function
End Class

它们的构造函数用于将值存储在私有 属性 中,并且它们的(覆盖的)ToString 方法(作为接口的方法实现)尝试检索该值。

Module Module1
    Sub Main()
        Dim oTest = New TestingOverrides("x")
        Console.Write(oTest.ToString)
        'produces: SSML.TestingOverrides. Why not "x"?
    End Sub
End Module

然而,调试器甚至没有进入 oTest.ToString。我想念什么?

如果通过接口调用就可以了:

Sub Main()
    Dim oTest As IElements = New TestingOverrides("x")
    Console.Write(oTest.ToString())
End Sub

但是,如果您通过 class 的类型调用它,那么您必须使用 class 的方法名称。因为,在 class 上,您将其声明为名为 IElements_ToString 的 public 方法,所以您必须这样调用它:

Sub Main()
    Dim oTest As New TestingOverrides("x")
    Console.Write(oTest.IElements_ToString())
End Sub

在 class 上调用 ToString 的唯一原因是因为所有 class 都从基础 public ToString 中继承了一个方法 Object类型。如果您使用任何其他方法名称,它会告诉您指定的方法不存在。

正如其他人所提到的...由于所有类型都自动继承 ToString 方法,因此通过接口定义另一个具有相同名称的方法是不寻常的、意外的和令人困惑的。最好将其命名为 GetValueGetDescription 之类的名称,或者简单地信任所有派生的 classes 来覆盖 Object.ToString 方法。如果你真的想强制所有派生的 classes 提供 ToString 实现,你可以通过 Grandfather class:

的实现来强制它
Public Class Grandfather
    Implements IElements
    Private _MyArg As String
    Public Sub New(Arg As String)
        _MyArg = Arg
    End Sub
    Public NotOverridable Overrides Function ToString() As String _
        Implements IElements.GetArg
        Return _MyArg
    End Function
End Class

或:

Public Class Grandfather
    Implements IElements
    Public NotOverridable Overrides Function ToString() As String 
        Return GetArg()
    End Function

    Public MustOverride Function GetArg() Implements IElements.GetArg
End Class