VB.NET - 调用多个构造函数

16

我是一名C#开发人员,对VB.NET的经验不足。

场景:

Namespace Presenters
    Public Class BaseFooPresenter

        ' assuming the public default parameterless constructor

        Public Sub New(ByVal strvar As String)
            ' TODO with strvar variabile
        End Sub

    End Class

    Public Class FooPresenter
           Inherits BaseFooPresenter

        Public Sub New(ByVal boolvar As Boolean)
            ' TODO with boolvar variabile
        End Sub

        Public Sub New(ByVal boolvar As Boolean, _
                       ByVal objvar As Object)
            MyBase.New(String.Empty)
            Me.New(true)
            ' TODO with objvar variabile
        End Sub

    End Class
End Namespace

在第二个FooPresenter构造函数中使用此代码会导致错误:

"Constructor call is valid only at the first statement in an instance constructor."

位置:

            Me.New(true)

如果我反转顺序,我会在以下位置收到错误:

            MyBase.New(String.Empty)

我可以创建一个方法SetValues(...参数...),并从两个构造函数中调用它,但是是否有人知道避免此错误的解决方法?为什么编译器不验证在重载构造函数之前调用基础构造函数的可能性呢?

有人知道如何在逻辑上证明不可能同时从一个类级构造函数调用基类构造函数和另一个类级构造函数吗?


抱歉@Moonlight,因为我在stackoverflow上很新,且没有足够的声望分数(目前只有14分),无法对答案进行投票:( - manuellt
3
你可以在自己的问题上标记答案(不是投票选项,而是标记为答案)。 - Moonlight
2
感谢 @Moonlight 提供的建设性意见,我现在正在标记答案 ;) - manuellt
3个回答

24
问题在于,一旦您指定了参数构造函数,如果您没有明确指定,无参构造函数就会变为私有

因此,修改ken2K的代码:

Namespace Presenters
    Public Class BaseFooPresenter

        ' SPECIFYING the protected default parameterless constructor
        ' can also be public
        Protected Sub New()

        End Sub

        Public Sub New(ByVal strvar As String)
            ' TODO with strvar variabile
        End Sub

    End Class

    Public Class FooPresenter
        Inherits BaseFooPresenter

        Public Sub New(ByVal boolvar As Boolean)
            MyBase.New()
            ' TODO with boolvar variabile
        End Sub

        Public Sub New(ByVal boolvar As Boolean, _
                       ByVal objvar As Object)
            Me.New(boolvar)
            ' TODO with objvar variabile
        End Sub

    End Class
End Namespace

你好 @M.A. Hanin,我需要第一个FooPresenter构造函数调用无参数的基础构造函数,而第二个FooPresenter构造函数在调用重载的基础构造函数之前/之后先调用第一个FooPresenter构造函数,但我发现这是不可能的。 - manuellt

7
就像在C#中一样,你不能同时调用this()和base()。下面是正确的做法:
Namespace Presenters
    Public Class BaseFooPresenter

        ' assuming the public default parameterless constructor

        Public Sub New(ByVal strvar As String)
            ' TODO with strvar variabile
        End Sub

    End Class

    Public Class FooPresenter
           Inherits BaseFooPresenter

        Public Sub New(ByVal boolvar As Boolean)
            MyBase.New(String.Empty)
            ' TODO with boolvar variabile
        End Sub

        Public Sub New(ByVal boolvar As Boolean, _
                       ByVal objvar As Object)
            Me.New(boolvar)
            ' TODO with objvar variabile
        End Sub

    End Class
End Namespace

嗨@ken2k,第一个构造函数不调用重载的基类构造函数非常重要,第一个构造函数必须调用隐式无参数的基类构造函数。提前致谢。 - manuellt
1
@manuellt:“必须调用隐式无参基类构造函数的第一个构造函数。”为什么?这个要求看起来只会给自己带来麻烦。 - user1039415
@Robin Brown,感谢您的观察。如果使用无参数构造函数,则FooPresenter会消耗在基类中创建的对象;如果使用重载构造函数并传递基类的键,则会消耗来自堆栈的静态对象。有几个现有的类继承自这个基类,我只想找到实现新行为对现有类和新类影响最小的方法。 - manuellt
1
@manuellt:我认为问题在于你试图让一个项目做两件事情,因此在你上面的评论中出现了“OR”。是否有可能重新审视你的整体设计,并进行更改,以便你不依赖继承?也许使用接口来强制执行行为,或者可能是一个创建对象的单例/工厂类?如果你还没有这样做,我建议(重新)阅读《Head First Design Patterns》,因为它有助于澄清很多这些问题。 - user1039415
@Robin Brown,我同意,实际上有一个对象适用于所有演示者,但我需要一些演示者拥有单例对象(尚未实现),也许我需要重新审查设计,感谢您的建议 :) - manuellt

2

你不能这样调用多个构造函数。就像在C#中一样,你只能调用一个初始化器。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接