我可以有一个函数的返回类型的类本身在继承类?VB.NET



我有一个父类也是一个工厂。例如:

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

相关内容

  • 没有找到相关文章

最新更新