我可以在继承类中拥有一个具有类本身返回类型的函数吗?网络

发布于 2024-12-20 20:12:13 字数 1172 浏览 2 评论 0原文

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

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())

我该怎么做?

I have a parent class that is also a factory. For example:

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

And then an inherited one

Public Class BookFactory
    inherits Factory
End Class

I can use inflection in the Factory class to generate the proper extended objects when called by the inherited one. myBookFactory.clone() will then return a BookFactory instance and not only a Factory instance.

The problem: this BookFactory instance will be cast as Factory, since the type of the function is Factory and not BookFactory.

I'd like to do something like

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

So the returned value would be correctly cast and avoid having to do this each time:

Dim myBookFactory2 = DirectCast(myBookFactory1.clone(), myBookFactory1.getType())

How can I do this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

苄①跕圉湢 2024-12-27 20:12:13

这似乎是要求协变返回类型的一种变体。正如您所注意到的,VB.NET(或 C#)不支持这一点。通常,这是在重写虚拟方法的上下文中提出的,但仍然不允许这样做。有多种选择,每种都有各自的优点和缺点。

使用通用模板参数来指定派生类

这与最常见的 IComparable 实现方式类似。

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

此外,如果您可以向 Factory 基类添加 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。它还允许您在正常继承意义上多态地处理所有工厂类型。但是,如果您有一个类型为 Factory 的对象,您仍然会返回一个类型为 Factory 的对象。

重新考虑继承关系

根据这些类的使用方式,在这里使用继承关系可能没有意义。如果您只关心不重新输入代码,您可能需要研究代码生成。

This seems to be a variation on asking for covariant return types. As you have noticed, this is not supported by VB.NET (or C# for that matter). Typically this is asked in the context of overriding virtual methods, where it is still not allowed. There are several alternatives, each with their own pros and cons.

Use a generic template argument to specify the derived class

This is similar to the way IComparable<T> is most commonly implemented.

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

Additionally, if you can add a New constraint to the Factory (eg: Factory(Of T {New, Factory(Of T)})) base class, you may be able to avoid using reflection.

However, this does not prevent the accidental (or potentially malicious) mistake of declaring a class like this:

Public Class EvilFactory
    Inherits Factory(Of BookFactory)
    'hmmm, now clone will be making the wrong type
End Class

Also, this approach makes it impossible to create a list of factories of different types without resorting to another base class below Factory(Of T) or declaring the list as being of object.

Make new methods on the derived classes that return the specific type you want.

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

This allows you to hide the cast for those times when you know you have a BookFactory and want to get another BookFactory. It also lets you treat all factory types polymorphically in the normal inheritance sense. However, if you have an object typed as Factory, you will still get back an object type as Factory.

Reconsider the inheritance relationship

Depending on how these classes are used, it may not make sense to use the inheritance relationship here. If you are only concerned with not retyping code, you may want to look into code generation instead.

愿与i 2024-12-27 20:12:13

您可以使用泛型来使问题变得更容易,但它不会消除在某些时候进行强制转换的要求。例如:

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

You could potentially use generics to make the problem easier, but it won't remove the requirement to cast at some point. For example:

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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文