Мне интересно, есть ли у кого-нибудь хорошее предложение / шаблон для решения следующей проблемы дизайна.У меня есть иерархия командных классов.На самом абстрактном уровне у меня есть интерфейс ICommand.Результатом выполнения функции RunCommand () ICommand является объект.Разные команды будут иметь разные типы результатов, так что это подходящая абстракция.
Построение иерархии немного больше, становится желательным использование обобщений.Я создаю интерфейс Generic.ICommand (Of TResult).
Существует некоторый распространенный код рабочей панели, такой как Run, TryRun, BeginRun, BeginTryRun и т. Д., Который я хочу для всех команд - поэтому я создаю класс BaseCommand, который предоставляет все это и реализует неуниверсальный интерфейс ICommand.Однако BaseCommand не знает, как на самом деле выполнить что-либо, поэтому все эти команды в конечном итоге вызывают защищенную абстрактную функцию с именем InternalRunCommand.Все это прекрасно работает.
Теперь я хочу создать универсальную версию этого класса: BaseCommand (Of T).Он наследуется от BaseCommand, а также реализует общий интерфейс ICommand (Of T).Это работает, но теперь существует несоответствие: InternalRunCommand.
В неуниверсальной версии InternalRunCommand возвращает объект.В моем универсальном классе BaseCommand (Of T) я хотел бы перегрузить его универсальной версией, которая возвращает результат как тип T. К сожалению, компиляторы VB.NET/C# не позволяют вам перегрузить метод, гдеЕдинственное отличие - это тип возвращаемого значения.
Поскольку это защищенная функция, в конечном итоге она не имеет большого значения для общего API, но, тем не менее, меня раздражает, что у меня нет эстетически приятного решения этой проблемы.немного архитектуры.
В настоящее время я переопределил неуниверсальный InternalRunCommand в классе BaseCommand (Of T), чтобы он вызывал новую защищенную абстрактную функцию OnRunCommand, которая принимает те же параметры, но возвращает результаттипа T. InternalRunCommand также был объявлен как NonOverridable.Это, возможно, самое близкое, что я могу получить - но хотел посмотреть, есть ли какие-нибудь лучшие идеи там?:)
РЕДАКТИРОВАТЬ: я включил упрощенную копию кода в соответствии с просьбой, чтобы вы могли лучше представить проблему:
Public Interface ICommand
Property Name as String
Property Description As String
Property ResultType as Type
Function RunCommand(target as Device) As Object
Function TryRunCommand(target as Device, Byref result as Object) AS Boolean
Function BeginRunCommand(target as Device) as Task(Of Object)
Function BeginTryRunCommand(target as Device) As Task(of Boolean)
End Interface
Namespace Generic
Public Interface ICommand(Of TResult)
Function RunCommand(target as Device) as T
Function BeginRunCommand(target as Device) As Task(Of T)
End Interface
End Namespace
Public MustInherit Class BaseCommand
Implements ICommand
Public Function RunCommand(target as Device) As Object Implements ICommand.RunCommand
Return InternalRunCommand(device)
End Function
Public Function BeginRunCommand(target as Device) As Task(of Object) Implements ICommand.BeginRunCommand
Return Task(Of Object).Factory.StartNew( Function() InternalRunCommand(target))
End Function
' Other boiler plate code goes here'
Protected MustOverride Function InternalRunCommand(target as Device) As Object
End Class
Namespace Generic
Public Class BaseCommand(Of TResult)
Inherits BaseCommand
Implements ICommand(Of TResult)
Public Function BeginRunCommand(target as Device) As Task(of TResult) Implements ICommand(Of TResult).BeginRunCommand
Return Task(Of TResult).Factory.StartNew( Function() OnRunCommand(target))
End Function
Protected NotOverridable Overrides Function InternalRunCommand(target as Device) As Object
' Re-route to the generic version'
Return OnRunCommand(device)
End Function
Protected MustOverride Function OnRunCommand(target as Device) As T
End Class