Overloads and shadow by signature

In VB.NET the Overloads keyword is overloaded itself, having two different meanings.  One is adding a new method with the same name but different signature, and the other is shadowing a base class method with a method of the same name and signature (Hide-by-sig)

The problem is the developer can’t tell the difference unless they look closely at the base class, and its base class, all the way down to System.Object

I would like to see the VB team include a new keyword for hide by signature, such as ShadowBySig, and introduce a compiler warning if Overloads is used as hide by sig. This would allow us to remove this ambiguity over time without breaking any code, and in the long term makes code more readable, easier to understand, and less prone to accidental hiding by signature.

Thoughts ?

9 Comments so far

  1.   Isaiah D. Williams on July 26th, 2004          

    The VS.Net IDE will produce a warning if a developer writes a shadowed method without using the Shadows keyword. I believe that Robert Green and his team have done a good job with this but I do agree with you about the new keyword. I believe that we should avoid shadow methods and stick with overriding the methods when possible.

    You raise a good point here Bill! <g>

  2.   Larry Serflaten on July 26th, 2004          

    Overloads is not required when used in the same module, I don’t normally add it in. I can easily see there are more than one method available when the tips show 1 of 3 or whatever, (where it is being called). So, its one of those, out of sight, out of mind things, if its not there, no one worries about it!

    Also, isn’t the role of hide-by-signature supposed to be covered by Overrides, and not Overloads? The way I see it, Overloads pertains to the current module, and Overrides pertains to method in the base of a derived class.

    If you are using Overloads to perform the Overrides function, maybe the compiler should throw a warning?

  3.   Bill on July 26th, 2004          

    Hi Larry,

    Overloads is needed when adding a method of the same name but a different signature. You can omit it if they are in the same class, but cannot omit it if they are in a derived class. e.g.

    Class foo

    Sub test()


    End Sub

    End Class

    Class bar

    Inherits foo

    Overloads Sub test(ByVal name As String)


    End Sub

    End Class

    As for Overrides, that is a completely different thing, and you should NOT confuse overrides with Overloads. Overrides is the "same" signature, implemented in a different place. Overloads creates a "new" signature. When Overloads hides a base member by signature, the method is still a new method, but matches the base method by name, call type, parameters and return type. It is still a new method, even though to us it looks the same ๐Ÿ˜‰

    This is the reason they chose Overloads to do both adding new methods and hide by signature, as in both cases they append "new" to the emitted method. However, this does little to make the situation less ambiguous for developers. And most likely, this overloading of overloads is probably partly to blame for the confusion it causes you and many developers learning VB.

    I was thinking back to when I first encountered Overloads and was digging into it’s intricacies. I remember I didn’t like it then, and still don’t. I still have vivid memories of another VB MVP using most un-lady like language in regards to it when she discovered it’s nuances back then too ๐Ÿ˜‰

    The simplest thing to do is to extend the language to allow deprecation of the shadowy part of Overloads, phase it in over time, integrate it with compiler warnings and smart tag helpers to correct code. Leaving it as is, just makes the language un-necessarily ambiguous, and hence harder to learn, IMO.

  4.   Bill on July 26th, 2004          

    Thanks Isaiah.

  5.   Larry Serflaten on July 26th, 2004          

    Nevermind! After a little more investigation, I found this in the docs:

    "Derived classes can overload inherited members with members that have identical

    parameters and parameter types, a process known as shadowing by name and signature.

    If the Overloads keyword is used when shadowing by name and signature, the derived

    classes implementation of the member will be used instead of the implementation

    in the base class, and all other overloads for that member will be available to

    instances of the derived class."

    So again, you were right, Overloads, is overloaded!

    (Now how do I cancel my earlier submission? ๐Ÿ˜‰


  6.   Larry Serflaten on July 26th, 2004          

    OK, but as defined, the Bar class has a member called Test(), because it is inherited from the Foo class. Now, like any other time you want methods of the same name, in the same module, you will be overloading that method name. So it would appear, that Overloads is the right choice, but then there is this in the Docs:

    "The Overloads keyword is optional when overloading, but if any overloaded member

    uses the Overloads keyword, then all other overloaded members with the same name

    must also specify this keyword."

    That’s why I can overload without using the keyword, but your situation breaks that rule!

    One version uses overloads, while the other does not….

    What if they just made it optional, so that you would not need the Overloads keyword in your situation. It is after all a new method is it not?

  7.   Bill on July 26th, 2004          

    Hey Larry,

    You can’t. I could, but I think leaving it there highlights part of the issue. Overloads is overly complex. It shouldn’t be. There should be no confussion ๐Ÿ˜‰

  8.   Bill on July 26th, 2004          

    They could make Overloads optional everywhere, but then you loose the explicit nature of the language, and once again are reliant on object browser and class view to indicate if the method is an overload.

    So I think removing it, or making it optional would actually be a loss in explicit readability

  9.   Jonathan Allen on August 2nd, 2004          

    I agree. When VB.Net first came out, it wasn’t a big deal. But now that I’ve got to look at 2-year-old code, it is quite annoying.