简体   繁体   中英

Calling constructor from shared method (C# to VB.Net)

I have not enough experience in VB.NET, I have a Windows Forms VB.NET application and I'm trying to do what in C# I'd do in this way:

public class MyForm{    
    MyForm(string caption) {
        _caption = caption;
        if(...){
            BaseForm.Show(caption);
      }
    }

    public static void Show(string caption) {
        new MyForm(caption);
    }
}

(BaseForm is another class I have in the application with a static method Show). All works fine in C#, but in Visual Basic .NET I'm not able to call the constructor. The constructor has become:

Public Sub New(ByVal caption As String)
        _caption = caption
        If ...
            BaseForm.Show(caption)
        End If
End Sub

But what is the VB.NET equivalent for new classname(parameters) ? What i've tried:

Public Shared Sub Show(ByVal caption As String)
    MyForm.New(caption)
End Sub 

Public Shared Sub Show(ByVal caption As String)
    Me.New(caption)
End Sub

Public Shared Sub Show(ByVal caption As String)
    New MyForm(caption)
End Sub

None of these works. It also appears that online C#-VB.NET converters give me the third option as answer (I wouldn't have tried that) but it's wrong. VS 2017 gives me the following errors respectively:

  1. "Constructor call is valid only as the first statement in an
    instance constructor"
  2. This obviously doesn't work because a shared/static method can't call an instance
  3. "Syntax error"

EDIT: Sorry for the mistake, I originally posted a code where I was passing three arguments in the VB.NET functions. However, in my real code the functions have more arguments and I'm sure this is not the problem. I thought it would have been clearer if I had only shown you the essential code since the complete code is too long but forgot to delete the additional arguments in some functions

在 VB.NET 中,你应该使用一个临时变量:

Dim tempVar As New MyForm(caption)

The essential issue here is that VB does not allow "naked" expressions to be statements. C# (and Java) restricts expressions as statements to the following:

  • Assignment expressions
  • Any use of ++ or --
  • Method invocations
  • Object creation expressions

Regarding the first two points, VB has sort-of equivalents. VB doesn't have a built-in assignment expression; instead it has an assignment statement. VB doesn't have ++ or -- operators; it only has += and -= assignment statements. In any case, via helper Functions one can make fully emulated equivalents of them in VB.

Of the above points, only the "Method invocations" one is allowed in VB. The "Object creation expressions" is not.

So something like New MyForm() is an expression, despite the pretense of Sub New() . The most straight-forward work-around is to make use of local variables (as others have already suggested):

Dim tmp As New MyForm(Text, caption, timeout)

Another idea is using With :

With New MyForm(Text, caption, timeout) : End With

If you figure this is the sort of thing you'll be doing a lot, maybe you could add a private or protected method to your class that does nothing:

    Private Sub NoOp()
    End Sub

and use it like so:

Call New MyForm(Text, caption, timeout).NoOp()

That works because the Call statement allows for expressions on the way towards getting at a method invocation.

Alternatively, you could make a helper function in a Module like so:

#Disable Warning IDE0060 ' Remove unused parameter
    Friend Sub [Call](Of T)(x As T)
#Enable Warning IDE0060 ' Remove unused parameter
    End Sub

And then do this with it:

[Call](New MyForm(Text, caption, timeout)) ' Note square brackets on [Call]

Your MyForm constructor takes only one parameter and your Show method is wrong and should be like this to return the newly created instance.

Public Shared Function Show(ByVal caption As String) As MyForm
    Return New MyForm(caption)
End Function

The real issue here is your design, you should not have any logic implemented inside of your constructor.

Something like this instead

Public Sub Show()
    BaseForm.Show(_caption)
End Sub

Public Shared Sub Show(ByVal caption As String)
    Dim form = New MyForm(caption)
    form.Show()
End Sub

For these kinds of question there are many C# to VB converters, including at least 2 Free Open Source once that will do the conversion for you. One is mine at https://github.com/paul1956/CSharpToVB

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM