Vb.net 重载对象为参数类型的方法

Vb.net 重载对象为参数类型的方法,vb.net,object,inheritance,overloading,Vb.net,Object,Inheritance,Overloading,我想弄清楚这种奇怪的行为。我有一个基类(a),它有一个名为“M”的重载方法:一个用于整数,另一个用于浮点(在VB.NET上为single) 另一方面,我有一个从a继承的第二个类(B),它以两种方式重载方法M:一种用于数据类型double,另一种用于对象数据类型 问题是:我希望这些方法将每个函数用于其数据类型,但出于某种奇怪的原因,具有对象数据类型的方法将承担所有调用。为什么会这样 我希望这个程序的输出是15,但实际上是4 下面是代码(VB.NET): 它调用接受对象的重载的原因是因为数组的类型为

我想弄清楚这种奇怪的行为。我有一个基类(a),它有一个名为“M”的重载方法:一个用于整数,另一个用于浮点(在VB.NET上为single)

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

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

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

下面是代码(VB.NET):


它调用接受
对象的重载的原因是因为数组的类型为
对象

' 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中查找“装箱”和“取消装箱”,有很多好文章对此进行了更详细的解释。

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

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


如果这样做会发生什么:
Dim var as Double=7
b.M(var)
?在这种情况下,它使用“Double”方法。谢谢这很奇怪,因为调试器说arre(0)是double类型,但却调用“object”类型。我试着用一个“Double”变量调用函数M,它转到了“Double”函数,所以你的解释是有意义的。谢谢!
arre(0)
中的实际值仍然是类型
Double
,但它被“装箱”为(转换为)
对象。这之所以可能是因为
Double
继承自
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)
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