Tuesday, October 24, 2006

Overloads Overloads

Finally got around to digging into something that's been bugging me since February, re the warning message that can be issued by VB.NET in VS2005: "Inappropriate use of 'Overloads' keyword in a module".

As related in that post, the Microsoft explanation (from the lovely Amanda Silver) is: "the Overloads keyword only makes a difference to the semantics of the application when the method is overloaded across an inheritance chain". But we all know that an overload is when two methods (properties etc.) share the same name but have different signatures, right? It even says so in the VB language spec (section 4.1.1): "The only way to declare identically named entities of the same kind in a declaration space is through overloading."

Ah, but that's the concept called overloading, which is obviously different from the overloading keyword. A few pages further on in the spec (section 4.3.3), all is made clear: "Shadowing by name is specified using the Shadows keyword. ... Shadowing by name and signature is specified using the Overloads keyword.". I.e. "overloads" is actually overloaded in Visual Basic! And those C# snobs call us stupid ;-)

Joking aside, the point is that Overloads and Shadows are telling the compiler about the relationship between a name in the current class and the same name in base classes, not about the relationship between same-named members within one class. They are saying "this member is not related to members of the same name that I happen to inherit; specifically, it does not override any of them". So actually, these keywords are only necessary when the base member is overridable (i.e. virtual).

As mentioned, the difference between the two keywords is that Overloads prevents overriding of a specific signature while Shadows prevents overriding of anything with the same name; the following code is illegal:


    2 Public Class Class1


    4     Public Overridable Sub F(ByVal x As Integer)

    5     End Sub


    7     Public Overridable Sub F(ByVal s As String)

    8     End Sub


   10 End Class


   12 Public Class Class2

   13     Inherits Class1


   15     Public Shadows Sub F(ByVal y As Integer)

   16     End Sub


   18     Public Overrides Sub F(ByVal s As String)

   19         MyBase.F(s)

   20     End Sub


   22 End Class


It generates the error "sub 'F' cannot be declared 'Overrides' because it does not override a sub in a base class." on line 18. Replace Shadows with Overloads on line 15 and it works just fine.

Here's the equivalent in C#, which only has a single keyword for this duty, i.e. new:


    2 public class Class1

    3 {

    4     public virtual void F(int x) { }

    5     public virtual void F(string s) { }

    6 }


    8 public class Class2 : Class1

    9 {

   10     public new void F(int y) { }

   11     public override void F(string s) { }

   12 }


This compiles fine, leading us to deduce that new is equivalent to Overloads. However in the book on which I cut my .NET teeth (Table 7-4), Jeffrey Richter cites Shadows as the VB equivalent of new.

Hmm, I wonder... Did Overloads start off meaning "I meant to give these methods the same name" but morph into its current meaning when Microsoft realized Shadows was a bit too blunt-edged?

Update 31/10/2006

I was obviously still confused when I wrote the above post, so I've attempted to straighten it out here.

No comments: