0

私はこの奇妙な行動を理解しようとしています。「M」と呼ばれるオーバーロードされたメソッドを持つ基本クラス (A) があります。1 つは整数用、もう 1 つは浮動小数点数 (VB.NET では単一) です。

一方、A から継承する 2 番目のクラス (B) があり、メソッド M を 2 つの方法でオーバーロードします。1 つは double データ型用、もう 1 つはオブジェクト データ型用です。

問題は、メソッドがそれぞれの関数をそのデータ型に使用することを期待しているのですが、何らかの奇妙な理由で、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
4

2 に答える 2

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 で "boxing" と "unboxing" を調べてください。これについて詳しく説明している優れた記事がたくさんあります。

于 2013-01-31T00:25:04.910 に答える
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
于 2013-01-31T00:37:24.510 に答える