Похоже, это вариант запроса ковариантных типов возврата. Как вы заметили, это не поддерживается VB.NET (или C # в этом отношении). Обычно это задается в контексте переопределения виртуальных методов, где это все еще не разрешено. Есть несколько вариантов, каждый со своими плюсами и минусами.
Используйте универсальный аргумент шаблона для указания производного класса
Это похоже на то, как обычно применяется IComparable<T>
.
Public Class Factory(Of T As Factory)
Public Function Clone() As T
'use GetType(T) to determine derived type
End Function
End Class
Public Class BookFactory
Inherits Factory(Of BookFactory)
End Class
Кроме того, если вы можете добавить ограничение New
к базовому классу Factory (например: Factory(Of T {New, Factory(Of T)})
), вы можете избежать использования отражения.
Однако это не предотвращает случайную (или потенциально злонамеренную) ошибку объявления такого класса:
Public Class EvilFactory
Inherits Factory(Of BookFactory)
'hmmm, now clone will be making the wrong type
End Class
Кроме того, этот подход делает невозможным создание списка фабрик разных типов без обращения к другому базовому классу ниже Factory(Of T)
или объявления списка как объекта.
Создайте новые методы для производных классов, которые возвращают определенный тип, который вы хотите.
Public Class Factory
Public Function Clone() As Factory
'create derived class, but return as base
End Function
End Class
Public Class BookFactory
Inherits Factory
Public Function CloneBooks() As BookFactory
Return CType(Me.Clone(), BookFactory)
End Function
End Class
Это позволяет вам скрыть актерский состав для тех случаев, когда вы знаете, что у вас есть BookFactory
и хотите получить еще один BookFactory
. Это также позволяет полиморфно обрабатывать все типы фабрики в обычном смысле наследования. Однако, если у вас есть объект, напечатанный как Factory
, вы все равно получите тип объекта как Factory
.
Пересмотреть наследственные отношения
В зависимости от того, как используются эти классы, может не иметь смысла использовать здесь отношения наследования. Если вас беспокоит не перепечатывание кода, вы можете вместо этого заняться генерацией кода.