0

それぞれ 2 つの引数で何度もオーバーロードされたサブルーチンから正しいサブルーチンを選択するのに苦労しています。おそらく何らかの形式の二重ディスパッチが適切でしょうが、チェックする必要がある 2 つの (潜在的に) 異なる型を持つ 2 つの引数がある場合、それを行う適切な方法がわかりません。

基本的に、私が作成したサンプル コードは期待どおりに動作しますが、それを実行する方法は非常に貧弱に思えます。タイプはコンパイル時に決定されるため、テストしようとしている 2 つのオブジェクトを渡して、必要なサブルーチンを単純に呼び出すことはできません。

test(store(0),store(1)) 

署名付きのテストサブルーチンのみを呼び出します

Sub test(cA As Class1, cB As Class1)

store(x) の静的タイプは常に Class1 になるためです。

二重ディスパッチのいくつかの複雑な形式は実行可能ですか、それともより良い解決策がありますか?

Option Strict On
Module Module1

    Sub Main()
        Dim store As List(Of Class1) = New List(Of Class1)
        store.Add(New Class2)
        store.Add(New Class3)
        If TypeOf (store(0)) Is Class2 Then
            If TypeOf store(1) Is Class2 Then
                test(CType(store(0), Class2), CType(store(1), Class2))
            ElseIf TypeOf store(1) Is Class3 Then
                test(CType(store(0), Class2), CType(store(1), Class3))
                'and so on...
            End If

        ElseIf TypeOf (store(0)) Is Class3 Then
            'relevant tests of store(1)
        ElseIf TypeOf (store(0)) Is Class4 Then
            'relevant tests of store(1)
        End If

        Console.ReadLine()
    End Sub

    Sub test(cA As Class2, cB As Class2)
        Console.WriteLine(cA.class2SecondUniqueProperty)
        Console.WriteLine("2 and a 2")
    End Sub
    Sub test(cA As Class2, cB As Class3)
        Console.WriteLine("2 and a 3")
    End Sub
    Sub test(cA As Class2, cB As Class4)
        Console.WriteLine(cB.class4UniqueProperty)
        Console.WriteLine("2 and a 4")
    End Sub
    Sub test(cA As Class3, cB As Class2)
        Console.WriteLine("3 and a 2")
    End Sub
    Sub test(cA As Class3, cB As Class3)
        Console.WriteLine("3 and a 3")
    End Sub
    Sub test(cA As Class3, cB As Class4)
        Console.WriteLine("3 and a 4")
    End Sub
    'and so on, for many (but not all) pairs of classes inherited from Class 1.
    Public Class Class1
    End Class
    Public Class Class2
        Inherits Class1
        Property class2UniqueProperty As String = "only present in Class 2"
        Property class2SecondUniqueProperty As String = "only present in Class 2"
        Sub class2UniqueSub()
            'do something that the other classes derrived from Class1 don't
        End Sub
    End Class
    Public Class Class3
        Inherits Class1
        Property class3UniqueProperty As String = "only present in Class 3"
    End Class
    Public Class Class4
        Inherits Class1
        Property class4UniqueProperty As String = "only present in Class 4"
    End Class
    'will be more than 4 classes
End Module
4

1 に答える 1

1

オーバーロード メソッドは、コンパイラによって選択されます(オーバーロードの解決)。おそらく、実行時にメソッドを選択する方法を探しているでしょう。タイプマッチングの方法は解決策になる可能性がありますが、タイプ解決コードをtestメソッド内に配置することをお勧めします。

あなたのコードは、オブジェクト指向プログラミングの観点からは良くありません。より良い方法は、クラスでメソッドを定義して呼び出すことです。

Public MustInherit Class Class1
  Public Property TypeNumber as  integer
  Public MustOverride Sub Test(Ca As Class1)
  Public MustOverride Sub SomeMethod()
End Class
Public Class Class2
  Inherits Class1
  Public Sub New()
       TypeNumber = 2
  End Sub

  Property class2UniqueProperty As String = "only present in Class 2"
  Public Overrides Sub Test(Ca As Class1)
      Ca.SomeMethod()
      Console.Writeln(Me.TypeNumber & " and a " & Ca.TypeNumber)
  End Sub
  Public MustOverride Sub SomeMethod()
      Console.Writeln(class2UniqueProperty)
  End Sub
End Class

'... 他のクラスを続行

そしてコールは今すぐ使用します

store(0).Test(Store(1))

タイプマッチングロジックなしでは問題を解決できない可能性がありますが、通常は避ける方がよいでしょう。オブジェクト指向パターンは通常、モジュール メソッドを使用するよりも管理しやすいです。

于 2013-10-13T15:36:15.990 に答える