“Overloads” keyword in VB.NET

2019-01-15 12:26发布

问题:

Do you really need this keyword to overload methods? What is the difference between using the overloads keyword vs. just having different method signatures?

回答1:

Within the same class, the Overloads keyword is optional, but if one method is declared Overloads or Overrides, you must use it for all overloads of that method.

' this is okay
Sub F1(s as String)
Sub F1(n as Integer)

' This is also okay
Overloads Sub F2(s as String)
Overloads Sub F2(n as Integer)

' Error
Overloads Sub F3(s as String)
Sub F3(n as Integer)

It gets more complicated when you are overloading base class methods in a derived class however.

If a base class has several overloaded methods and you want to add an overloaded method in a derived class, then you must mark the method in the derived class with the Overloads keyword, otherwise all the overloaded methods in the base class are unavailable in the derived class.

See MSDN for more details.



回答2:

This shows up high in the Google results, and I think it could be explained more clearly here.

There is no reason to use the Overloads keyword when you're overloading various methods within the same class. The main reason that you would use Overloads is to allow a derived class to call a method from its base class that has the same name as the overloaded method, but a different signature.

Suppose you have two classes, Foo and SonOfFoo, where SonOfFoo inherits from Foo. If Foo implements a method called DoSomething and SonOfFoo implements method with the same name, the SonOfFoo method will hide the parent class's implementation...even if the two methods take different parameters. Specifying the Overloads keyword will allow the derived class to call the parent class's overloads of the method.

Here's some code to demonstrate the above, with the classes Foo and SonOfFoo implemented as described, and another pair of classes, Bar and SonOfBar that use the Overloads keyword:

Class Foo
    Public Sub DoSomething(ByVal text As String)
        Console.WriteLine("Foo did: " + text)
    End Sub
End Class

Class SonOfFoo
    Inherits Foo

    Public Sub DoSomething(ByVal number As Integer)
        Console.WriteLine("SonOfFoo did: " + number.ToString())
    End Sub
End Class

Class Bar
    Public Sub DoSomething(ByVal text As String)
        Console.WriteLine("Bar did: " + text)
    End Sub
End Class

Class SonOfBar
    Inherits Bar

    Public Overloads Sub DoSomething(ByVal number As Integer)
        Console.WriteLine("SonOfBar did: " + number.ToString())
    End Sub
End Class

Sub Main()
    Dim fooInstance As Foo = New SonOfFoo()
    'works
    fooInstance.DoSomething("I'm really a SonOfFoo")
    'compiler error, Foo.DoSomething has no overload for an integer
    fooInstance.DoSomething(123)

    Dim barInstance As Bar = New SonOfBar()
    'works
    barInstance.DoSomething("I'm really a SonOfBar")
    'compiler error, Bar.DoSomething has no overload for an integer
    barInstance.DoSomething(123)

    Dim sonOfFooInstance As New SonOfFoo()
    'compiler error, the base implementation of DoSomething is hidden and cannot be called
    sonOfFooInstance.DoSomething("I'm really a SonOfFoo")
    'works
    sonOfFooInstance.DoSomething(123)

    Dim sonOfBarInstance As New SonOfBar()
    'works -- because we used the Overloads keyword
    sonOfBarInstance.DoSomething("I'm really a SonOfBar")
    'works
    sonOfBarInstance.DoSomething(123)
End Sub

Here's some information on how this compiles differently in the CLI.



回答3:

It was a design consideration. Of course it (VB) could have been designed to infer overloading by the function signature (like in C#) - so the Overloads keyword itself could have been omitted but in the end it's just in line with Visual Basic's expressiveness (which some consider overhead) and it was only a language design decision.



回答4:

Miky D is right. There is no difference between an overloaded method declared Overloads and another one which doesn't.

I just wanted to point out that the Overloads keyword is mandatory when another method with the same name is declared Overrides or Overloads. For example, if you override the Equals method like this:

Public Overrides Function Equals(ByVal obj As Object) As Boolean ...

Then you want to create an overload like this:

Public Function Equals(ByVal otherProduct As Product) As Boolean ...

You will get the following error:

"function 'Equals' must be declared 'Overloads' because another 'Equals' 
is declared 'Overloads' or 'Overrides'."

You will get the same error if someone declared a method as Overloads, and you want to overload that method. You will have to either add the Overloads keyword to your method or remove it from the other method.

I personally never declare an overloaded method Overloads unless I don't have the choice, like in the situation above.



回答5:

I ran into a situation where I was required to use the Overloads keyword.

I had a parent class, and an inherited class.

Public Class DataManager

   Public MustOverride Function LoadDataSet(ByVal TableName as String, ByVal SQL as SQLObject) as DataSet

   Public Function LoadDataSet(ByVal TableName as String, ByVal SQL as String) as DataSet
     Return LoadDataSet(TableName, new SQLObject(SQL))
   End Function
End Class

Public Class OracleDataManager
  Inherits DataManager

  Public Overloads Overrides Function LoadDataSet(ByVal TableName as String, ByVal SQLObj as SQLObject) as DataSet
    // code here
  End Function

End Class

In this example, I had to use the overloads keyword.



回答6:

The Overloads-Keyword is completely optional - I don't see advantages in using it.