【问题标题】:How to get Classes to expose the same Shared/Static method如何让类公开相同的共享/静态方法
【发布时间】:2010-03-04 04:31:08
【问题描述】:

我有一个带有几个派生类的基类。我希望我的所有派生类都具有相同的 Public Shared (static) 方法和它们自己的实现。我该怎么做呢?有没有可能?

【问题讨论】:

标签: asp.net vb.net inheritance


【解决方案1】:

我知道这似乎是一个有用的功能“在设计时”,但想象一下如何使用它:

如果GetFormsShared(C# 中的static),则您没有具有类型的对象来区分使用哪种方法,即您不能以某种方式说出BaseForm.GetForms(),它可以确定实际调用了ChildFormTypeA.GetForms()ChildFormTypeB.GetForms() 中的哪一个。

如果您只想显式调用ChildFormTypeA.GetForms()ChildFormTypeB.GetForms(),或者如果您真的需要这个概念,请将其设为工厂方法,例如

MustInherit Class BaseForm

  MustOverride Sub GetForms()

End Class

Class MyForm
   Inherits BaseForm

   Public Sub New()
   End Sub

   Overrides Sub GetForms()
   End Sub   
End Class

现在你只需要

Dim f as BaseForm = New MyForm
f.GetForms

或者GetForms 可能是Protected 并从Sub New 调用。


编辑:这几乎是一个新答案。

我只是在维护现有代码时需要这个。我决定最简单的方法是让两个类都实现一个接口:

Interface ISharedNew
  Function SharedNew(ByVal Argument As String) As ISharedNew
End Interface

(在这种情况下,我已经通过泛型约束 T As New 使用了这些类,并且我需要构造函数现在具有泛型约束不支持的参数。)

新的(简化的)通用代码现在是:

Function GetNew(Of T As {New, ISharedNew})(ByVal Argument As String) As T
  Return DirectCast((New T).SharedNew(Argument), T)
End Function

在我的例子中,New T 对象本身被SharedNew 忽略,但它的类型确实指定了SharedNew 的相关实例,它使用Argument 创建了一个新的T 对象。

代码已从头开始添加到此答案中,未引用实际代码。

【讨论】:

  • 完全同意。 MyForm.GetForms() 只能对 MyForm 类型进行操作,无法指定需要使用的派生类型表单。
  • 这很容易区分,我想,如果我调用类似 Invoice.GetForms() 的东西,它会转到 Invoice 类中的共享 'GetForms()` 方法......如何有那么难吗?在基类中,将其声明为Public MustOverride Shared Sub GetForms()。不幸的是,这不会编译...对我来说很有意义,但它应该...
  • @Jason,这就是我的意思,也可以将其记录为意图:如果预期的功能实际上是由 InvoiceOther.TheFormsGet() 实现的,那么代码是如何被破坏的。
【解决方案2】:

没有。您可以使用单例,但可能会有更好的设计。

【讨论】:

    【解决方案3】:

    根据定义,静态方法不能声明为虚拟方法。要在没有静态方法的情况下实现这一点,您可以执行以下操作:

    public abstract class BaseFoo
    {
        protected virtual void Bar()
        {
        }
    }
    
    public class Foo : BaseFoo
    {
        protected override void Bar()
        {
            base.Bar();
        }
    }
    

    如果您想实现类似于将其设置为静态的东西,您可以使用单例模式,以便共享对象的单个实例。

    编辑

    我意识到你最初的问题是关于 VB 语法,所以在 VB 中也是这样:

    Public MustInherit Class BaseFoo
    
        Protected Overridable Sub Bar()
        End Sub
    
    End Class
    
    Public Class Foo
        Inherits BaseFoo
    
        Protected Overrides Sub Bar()
            MyBase.Bar()
        End Sub
    
    End Class
    

    【讨论】:

    • 这有什么原因吗?不能声明一个可以在所有类中使用的静态方法 sig 似乎很愚蠢。
    • RE:您的编辑 - 是的,谢谢...我能够在脑海中转换它,但是我正在为这个项目使用 vb :)
    • 您这样做是为了达到什么目的?虚拟方法依赖于实例化的对象,而静态方法无需创建对象即可存在。这就是为什么静态方法只能引用其他静态变量/方法的原因。如果它只是您尝试共享的方法签名,那么我之前给出的示例表明签名将被共享。在不知道您的确切情况的情况下,我会说您可能会从单例模式或依赖注入中受益。
    • 我的意思是他们做同样的事情,但他们的实现细节需要一些稍微不同的东西。如果我可以将BaseForm.GetForms() 声明为MustOverride 并在其中包含实现细节,那将是完美的,但我不能。
    猜你喜欢
    • 1970-01-01
    • 2011-04-19
    • 1970-01-01
    • 2014-11-03
    • 2012-02-11
    • 1970-01-01
    • 2021-10-14
    • 1970-01-01
    • 2016-09-18
    相关资源
    最近更新 更多