使用Object作为参数类型重载方法

时间:2013-01-30 23:28:25

标签: vb.net object inheritance overloading

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

另一方面,我有一个继承自A的第二个类(B),它以两种方式重载方法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

2 个答案:

答案 0 :(得分: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中查找“装箱”和“拆箱”,有大量优秀的文章可以更详细地解释这一点。

答案 1 :(得分:0)

每次都会在示例中调用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