D'Arcy from Winnipeg
Solution Architecture, Business & Entrepreneurship, Microsoft, and Adoption

Overloads and Shadows (VB.NET)

Tuesday, January 15, 2008 3:07 PM

I'm teaching an 'OO with VB.NET' course right now, and last night was the talk about overloading, overriding, and shadowing...specifically around inheritance. Prepping for this showed some interesting behavior that I wasn't aware of, and wanted to share.

Overloading a function or sub means that you have a method with the same name as an existing method. If these are in the same files, then you need to specify different signatures for them. However, you could have a situation where a base class and a derived class both have the same method signatures and method names. In this case, you *don't* have to have different signatures: the compiler is fine with letting you have a derived class with the EXACT method signature as one in your base class.

This is an issue though, because what you're really doing is Shadowing. Where Overriding requires the base class to identify a method as overridable and the derived class to specify that its class is overriding, Shadowing has no such rules. Shadowing clobbers your base class method in favor of the derived class method...and worse yet, this is the default behavior of VB.NET.

So it would appear that Overloading in a derived class and Shadowing are the same thing. Let's say we have two classes:

Class A
Class B

Class B inherits from Class A. Both have a method called DoSomething( ) in them, and class B overloads that method.

If you created an instance of Class B...

Dim _classB as ClassB
_classB = new ClassB

...and you called DoSomething( ), the method in Class B would execute. If you *didn't* overload that method the same thing would happen. Why? Because the default behavior is to shadow the method.

However...the rules for shadowing change when you're dealing with a variable declared as the base class, but instantiated to a derived class:

Dim _classB as ClassA
_classB = new ClassB

If I were to call the DoSomething( ) method from _classB, it would actually fire off Class A's version of the method, regardless if I overloaded or shadowed the methods in Class B.

So how do you avoid this mess in your code? By being prudent in how you write your methods:
- If you overload a method in a derived class, ensure that it has a different signature than the base class method.
- If you need to overload the method in a derived class with the identical signature from the base class's method, then use the Overridable and Overrides keywords to ensure that the method is picked up properly. This way, even in the second class example, your method from _classB will fire as expected
- Favor composition over inheritance. This is a tried and true phrase: even though you *could* solve a problem by inheriting, see if there's another option that doesn't require you to inherit and compose your object of other helper objects instead.




# re: Overloads and Shadows (VB.NET)

Although, if we're being fair, you are warned:

Warning 1 sub 'DoSomething' shadows an overloadable member declared in the base class 'ClassA'. If you want to overload the base method, this method must be declared 'Overloads'.

So once you are aware of the difference, you can make an informed decision as to what you need to do.

It would be worse if it just blindly acted different without any sort of warning, obviously that could potentially cause debugging headaches. 1/16/2008 7:49 AM | Carl

# re: Overloads and Shadows (VB.NET)

For shadows yes.

It would be nice to see a similar warning come up for when you overload a function in a derived class that has an exact signature as the one in the base. Nothing displays to warn the dev that the derived class's method will be used only when a variabled of that derived class is declared and not of the base type (which like you said though: once you're aware of hte difference, you'd know to avoid)

D 1/16/2008 8:21 AM | D'Arcy from Winnipeg

# re: Overloads and Shadows (VB.NET)

Thanks for this. I've been reading up on vb.net and both books I've been reading show examples of using "Overloads" on a method of a derived class that has the same signature as the method of the base class.

I got to your blog by googling for this, as I'm trying to understand why you would want your code to exhibit this behavior.

I think your final comment about either ensuring both methods have a different signature. Or use "Overrides" instead of "Overloads" is a much better practice then using "Overloads" with the same signature.

It would make sense to me that having the same signature could lead to debugging nightmares. 3/18/2008 5:24 PM | perry

# re: Overloads and Shadows (VB.NET)

I'm a C# developer so I was curious to read your recommendations at the end.

Does VB really allow you to declare a method as an override of a base method that itself has not be marked as overridable? You'd get a compile error doing that in C#.

I don't know why you'd recommend composition over inheritance. Redefining how a base class implements a method is one of the prime benefits of inheritance. A simple example is changing the output of the ToString method in a derived class. I'll admit I don't know VB.NET that well and so maybe it's implementation of classes leads to your recommendations. 1/30/2009 9:57 AM | Tim

# re: Overloads and Shadows (VB.NET)

isnt ur article confusing. 11/13/2009 8:54 AM | TheProdigy

# re: Overloads and Shadows (VB.NET)

good article 1/27/2010 9:26 PM | Munendra

# re: Overloads and Shadows (VB.NET)

Shadow is *not* the default behavior in vb.NET. If you don't include the shadow keyword, the behavior is different, i.e. the base class same-name method will be executed as well. 5/20/2010 7:47 AM | Kakos

# re: Overloads and Shadows (VB.NET)

Tim, C# developer. This functionality is in C#, you use the NEW keyword. A classes method or property can be overriden without marking the base class as virtual. It's not new or unique to .Net, most languages with inheritance allow this type of overriding.

To get the overriden method to work with the NEW keyword you have to actually have to reference it's class type rather than an abstract or base type. With normal C# overrides this is not the case; you can use abstract or base type for the override method or property to work.
6/14/2010 5:16 AM | Chris Sullivan

# re: Overloads and Shadows (VB.NET)

Beating a dead horse? Just wanted to add some clarification to this article/discussion. The confusion arises because the keyword "Overloads" isn't what a C# programmer considers an overload in the traditional OO sense. It's a type of hiding that is specific to VB.Net. You can actually swap the keyword SHADOWS with OVERLOADS in most cases, and the behavior is the same. The difference is when you have a base class with multiple overloaded method signatures. If you declare a method in a subclass with a matching name, and the SHADOWS keyword, it will hide EVERY overload of that method in the base class. If you use the OVERLOADS keyword instead, it will only hide the base class method with an identical signature.

As a simple example, consider the following snippet:

Public Class Base
Public Sub DoSomething()
End Sub

Public Sub DoSomething(ByVal withThis As String)
Console.WriteLine("Base." & withThis)
End Sub
End Class

Public Class SubClass
Inherits Base

Public Shadows Sub DoSomething(ByVal withThis As String)
Console.WriteLine("SubClass." & withThis)
End Sub
End Class

The subclass in this example DOES NOT have a parameterless DoSomething method. Because the method was declared as SHADWOS, it hides ALL of the base class methods with the same name, regardless of parameter differences.

Because of this, the following code will not compile:

Dim x as New SubClass()

However, it WILL compile if you change the subclass definition to the following:

Public Class SubClass
Inherits Base

Public Overloads Sub DoSomething(ByVal withThis As String)
Console.WriteLine("SubClass." & withThis)
End Sub
End Class

Hope that helps! 3/18/2011 12:48 PM | Wade

# re: Overloads and Shadows (VB.NET)

Wade: The fact people are still reading this blog post three years after I posted it means the horse must still be somewhat alive. :) Thanks for your response, great clarification!

D 3/18/2011 1:05 PM | D'Arcy from Winnipeg

# re: Overloads and Shadows (VB.NET)

I have to doff my hat to Wade; his explanation on 'Shadows' vs 'Overrides' is spot-on: succinct yet very clear.

@D'Arcy: Yes, the horse's still alive and kickin' ;-) 4/30/2011 11:57 AM | Pandu E Poluan

# re: Overloads and Shadows (VB.NET)

Here's how you do it:

<script runat="server">
Public Overloads Sub Page_Load(ByVal Sender As System.Object, ByVal e As System.EventArgs) Handles Me.Load
Dim cstring1 As String
cstring1 = "hello"
End Sub
5/1/2011 11:36 PM | Biff Martin

# re: Overloads and Shadows (VB.NET)

Thanks, you helped me to solve my own question on stackoverflow!

http://stackoverflow.com/q/7877378/275404 10/24/2011 2:20 PM | davrob60

Post a comment