【问题标题】:Overloading a method with Object as parameter type重载以 Object 为参数类型的方法
【发布时间】:2013-01-30 23:28:24
【问题描述】:

我正试图找出这种奇怪的行为。我有一个基类 (A),它有一个名为“M”的重载方法:一个用于整数,一个用于浮点数(在 VB.NET 上为单个)。

另一方面,我有第二个类 (B),它继承自 A,它以两种方式重载方法 M:一种用于数据类型 double,另一种用于对象数据类型。

问题是:我希望方法将每个函数用于其数据类型,但出于某种奇怪的原因,具有 Object 数据类型的方法会占用所有调用。为什么会这样?

我希望这个程序的输出是15,但实际上是4

这是代码(VB.NET):

Module Module1

Public Class A

    Public Function M(ByVal a As Integer) As Integer
        Return 8
    End Function

    Public Function M(ByVal a As Single) As Integer
        Return 4
    End Function

End Class

Public Class B
    Inherits A

    Public Overloads Function M(ByVal a As Double) As Integer
        Return 2
    End Function

    Public Overloads Function M(ByVal a As Object) As Integer
        Return 1
    End Function

End Class


Sub Main()

    Dim a0 As Double = 1
    Dim a1 As Single = 2
    Dim a2 As Integer = 4
    Dim a3 As Object = 8

    Dim arre(4)

    arre(0) = a0
    arre(1) = a1
    arre(2) = a2
    arre(3) = a3

    Dim b As New B

    Dim suma% = 0

    For i = 0 To 3
        suma += b.M(arre(i))
    Next i

    Console.WriteLine(suma)

    System.Threading.Thread.CurrentThread.Sleep(2000)
End Sub

End Module

【问题讨论】:

  • 如果你这样做会发生什么:Dim var as Double =7 : b.M(var) ?
  • 在这种情况下,它使用“Double”方法。谢谢!

标签: vb.net object inheritance overloading


【解决方案1】:

之所以调用采用Object 的重载,是因为您的数组是Object 类型。

' original code
Dim arre(4)

arre(0) = a0
arre(1) = a1
arre(2) = a2
arre(3) = a3

' verbose version
Dim arre(4) As Object

arre(0) = DirectCast(a0, Object)
arre(1) = DirectCast(a1, Object)
arre(2) = DirectCast(a2, Object)
arre(3) = DirectCast(a3, Object)

在 .NET 中查找“装箱”和“拆箱”,有大量好文章对此进行了更详细的解释。

【讨论】:

  • 这很奇怪,因为调试器说 arre(0) 是 double 类型,而是调用“object”类型。我尝试用“Double”变量调用函数 M,它转到“Double”函数,所以你的解释是有道理的。非常感谢!
  • arre(0) 中的实际值仍然是Double 类型,但它被“装箱”为(转换为)Object。这之所以成为可能,是因为 Double 继承自 Object(顺便说一句,其他所有内容也是如此)。
【解决方案2】:

每次都在您的示例中调用 Object 重载,因为您将数组声明为 Object 数组。 (Option Strict 会强制你在它后面加上 As Object,但这不会改变事情。)你在数组中放入什么类型并不重要,因为这些值被“装箱”到对象中

考虑以下,简化以演示正在发生的事情 (不需要您的自定义类或继承来展示您所看到的)

Module Module1

Public Function M(ByVal a As Integer) As Integer
    Return 8
End Function

Public Function M(ByVal a As Object) As Integer
    Return 1
End Function

Sub Main()
    Dim a0 As Integer = 0
    Dim a1 As Object = 0
    Dim arre(1)
    arre(0) = a0
    arre(1) = a1

    Console.WriteLine(M(arre(0)))
    ' 1, arre() is implicitly typed as an array of Objects
    ' so the Object overload will be called

    Console.WriteLine(M(arre(1)))
    ' 1, see above

    Console.WriteLine(M(DirectCast(arre(0), Integer)))
    ' 8, explicit cast to an Integer

    Console.WriteLine(M(DirectCast(arre(1), Integer)))
    ' 8, see above

    Console.WriteLine(M(a0))
    ' 8, a0 declared explicitly as an Integer

    Console.WriteLine(M(a1))
    ' 1, a1 declared explicitly as an Object

    Threading.Thread.Sleep(2000)
End Sub

End Module

【讨论】:

  • 太棒了,这完全有道理。不幸的是,我只能将一个答案检查为“我接受的答案”,而另一个人先给了我类似的答案。不过非常感谢!!!很棒的解释。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-31
  • 2014-08-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多