避免在参数类上使用长整数语句

时间:2016-07-29 12:33:11

标签: vb.net polymorphism case-statement

可以由A类执行任务的类层次结构。

在A类中,有一个长case语句检查任务类并调用相应的处理程序方法。

Class Task
End Class

Class TaskX
Inherits Task
End Class

Class TaskY
Inherits Task
End Class

...


Class A
    Public Sub PerformTask(Task As Task)
        Select Case Task.GetType
            Case GetType(TaskX)
                PerformTaskX(CType(Task, TaskX))
            Case GetType(TaskY)
                PerformTaskY(CType(Task, TaskY))
        End Select
    End Sub


    Private Sub PerformTaskX(Task As TaskX)
    End Sub

    Private Sub PerformTaskY(Task As TaskY)
    End Sub

    ...
End Class

任务有各自的参数,验证逻辑等。这个例子很简单。

我想避免案例陈述,我正在寻找替代解决方案。

一般的想法是将类类型映射到Handler(Of class),它可以以某种方式工作:

Delegate Sub Handler(Task As Task)

Private TypeToHandlerDict As New Dictionary(Of System.Type, Handler) From { _
            {GetType(TaskX), AddressOf PerformTaskX}, _
            {GetType(TaskY), AddressOf PerformTaskY} _
        }

这样我就可以用更优雅的方式替换PerformTask方法内容:

Public Sub PerformTask(Task As Task)
    Dim handler As Handler = Nothing
    If Not TypeToHandlerDict.TryGetValue(Task.GetType, handler) Then Exit Sub
    handler(Task)
End Sub

但它不起作用。

委托绑定到类型Task,但处理程序方法接受任务子类参数。我正在使用Option Strict。 我可以重写所有处理程序方法来接受Task对象并执行显式转换,但这同样不够优雅。

有什么建议吗? 谢谢!

更新:感谢@Sehnsucht的回答,这是解决方案。

Class Task
    Public MustOverride Sub Perform(a As A)
End Class

Class TaskX
Inherits Task
    Public Overrides Sub Perform(a As A)
        a.DoThis()
    End Sub
End Class

Class TaskY
Inherits Task
    Public Overrides Sub Perform(a As A)
        a.DoThat()
    End Sub
End Class

...


Class A
    Public Sub PerformTask(Task As Task)
        Task.Perform(Me)
    End Sub


    Public Sub DoThis()
    End Sub

    Public Sub DoThat()
    End Sub

    ...
End Class

1 个答案:

答案 0 :(得分:0)

所有PerformTask...都有相同的签名,并且由您在帖子中显示的代理Handler强制执行。
因此,您应该在Task类中使用默认实现创建一个Overridable方法(如果Task类是MustInherit,则将该方法标记为MustOverride),该方法将被其继承者覆盖,以根据其具体情况执行该任务情况下。

Class Task
    Public Overridable Sub Perform()
        ' implementation specific to Task ("default" case)
    End Sub
End Class

Class TaskX
    Inherits Task

    Public Overrides Sub Perform()
        ' implementation specific to TaskX
        ' you can call the parent implementation if needed with
        MyBase.Perform()
    End Sub
End Class

'Usage
Class A
    Public Sub PerformTask(task As Task)
        task.Perform() ' will call the "right one" according to it's runtime type
    End Sub
End Class