2016-07-29 2 views
0

Там есть иерархия классов задач, которые могут быть выполнены по классу А.Избежания долго заявление дела о классе аргумента

Внутри класс А есть длинный сазе проверка на класс задач и вызов обработчика корреспондентского метод.

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 

Задачи имеют свои индивидуальные параметры, логику проверки и т. Д. Пример упрощен.

Я хочу избежать заявления о ситуации, и я ищу альтернативные решения.

Общая идея отображение типа класса к обработчику (класс), которые могли бы работать как-то так:

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 
+0

Вы можете добавить '' Perform' или метод Execute' для классов Task и пусть они делают свою работу? Возможно, при необходимости используйте интерфейс 'ITask'. – Plutonix

+0

Можете ли вы поставить PerformTask как функцию переопределения функции внутри задачи, и каждая из них TaskX реализует свою собственную версию? Таким образом вы просто вызываете task.PerformTask() –

+1

Не зря, но вы задали 8 вопросов и получили 10 ответов, но не отметили ни одного из них, как принято. Принятие лучшего ответа, если таковое имеется, и повышение, помогает другим пользователям находить хорошие ответы. [Тур] объясняет это и другие вещи в очень краткой форме. – Plutonix

ответ

0

Все PerformTask... имеют ту же сигнатуру, и это исполнение делегатом Handler вы показали в своем сообщении.
Итак, вы должны сделать метод Overridable в своем классе Task с реализацией по умолчанию (или пометить метод как MustOverride, если класс Task - MustInherit), метод, который будет переопределен его наследниками для выполнения задания в соответствии с их конкретным случаем.

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 
+0

Выполнение задачи включает бизнес-логику внутри класса A («_how_ должно быть сделано»), в то время как задача только знает о «_what_ должно быть сделано». Создание метода Execute с параметром класса A в задаче и возможность вызова открытой бизнес-логики класса A, хотя мне это не нравится. – Manolis

+0

@Manolis никогда не указывалось, что классы Tasks содержат только данные о * what *, а не о * how *. Почти наоборот, для меня, когда вы заявили, что каждая задача имеет индивидуальный параметр, логика проверки ...это подразумевало для меня, что каждый знал, как это будет выполняться. С этой дополнительной информацией ваш комментарий в дополнение к начальному сообщению я, возможно, ответил бы по-другому :-) – Sehnsucht

+0

По-видимому, единственное решение, которое работает, действительно должно использовать полиморфизм и заставить каждого потомка задачи выполнять свою работу. Чтобы реализовать это в нашей системе, мне нужно выставить некоторую логику класса A и изменить полиморфный метод выполнения задачи, чтобы принять параметр A как параметр, чтобы он мог вызывать логику, которую он хочет. Спасибо! – Manolis

Смежные вопросы