title: Avoiding long case statement on argument class
body: <p>There is a class hierarchy of tasks that can be performed by the class A.</p>
  
  <p>Inside the class A there is a long case statement checking for the task class  and calling the correspondent handler method.</p>
  
  <pre><code>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
  </code></pre>
  
  <p>The tasks have their individual parameters, validation logic, etc. The example is simplified.</p>
  
  <p>I want to avoid the case statement and I am looking for alternative solutions.</p>
  
  <p>The general idea is mapping a class type to a Handler(Of class) that could work somehow like this:</p>
  
  <pre><code>Delegate Sub Handler(Task As Task)
  
  Private TypeToHandlerDict As New Dictionary(Of System.Type, Handler) From { _
              {GetType(TaskX), AddressOf PerformTaskX}, _
              {GetType(TaskY), AddressOf PerformTaskY} _
          }
  </code></pre>
  
  <p>so that I can replace the PerformTask method contents with the much more elegant:</p>
  
  <pre><code>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
  </code></pre>
  
  <p>But it doesn't work.</p>
  
  <p>The delegate binds to type Task, but the handler methods accept a task subclass parameter. I am using Option Strict.
  I could rewrite all handler methods to accept a Task object and perform an explicit cast, but this is equally inelegant.</p>
  
  <p>Any suggestions?
  Thank you!</p>
  
  <p><strong>Update</strong>: Here is the solution thanks to the answer from @Sehnsucht. </p>
  
  <pre><code>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
  </code></pre>