我有一个父类也是一个工厂。例如:
Public Class Factory
Public Function clone() as Factory
' Some logic here
' return something
End Function
Public Function all() as List (Of Factory)
' Some logic here
' return something
End Function
End Class
然后是继承的
Public Class BookFactory
inherits Factory
End Class
我可以在Factory类中使用拐点,以便在被继承类调用时生成适当的扩展对象。然后,myBookFactory.clone()
将返回BookFactory
实例,而不仅仅是Factory
实例。
问题:这个BookFactory
实例将被转换为Factory
,因为函数的类型是Factory
而不是BookFactory
。
我想做一些像
Public Class Factory
Public Function clone() as Me.GetType()
' Some logic here
' return something
End Function
Public Function all() as List (Of Me.GetType())
' Some logic here
' return something
End Function
End Class
因此返回值将被正确转换,避免每次都这样做:
Dim myBookFactory2 = DirectCast(myBookFactory1.clone(), myBookFactory1.getType())
我该怎么做?
这似乎是请求协变返回类型的一种变体。正如您所注意到的,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(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
的时候,这允许你隐藏cast。它还允许您以正常继承的方式多态地处理所有工厂类型。然而,如果你有一个类型为Factory
的对象,你仍然会得到一个类型为Factory
的对象。
重新考虑继承关系
根据这些类的使用方式,在这里使用继承关系可能没有意义。如果您只关心不重复输入代码,那么您可能需要查看代码生成。
您可能会使用泛型来简化问题,但它不会在某些时候消除强制类型转换的需求。例如:
Public Class Factory(Of T)
Public Function clone() As Factory(Of T)
' Some logic here
' return something
End Function
Public Function all() As Collections.Generic.List(Of T)
' Some logic here
' return something
End Function
End Class
Public Class BookFactory
Inherits Factory(Of Book)
End Class