13

Simple question from a simple-minded: What are the differences between the Shadows keyword in VB.NET and the New keyword in C#? (regarding method signatures of course).

M.A. Hanin
  • 8,044
  • 33
  • 51

2 Answers2

14

They are not identical.

The Shadowing concept does not exist in C #

Consider a vb.net base class with some overloads:

Public Class BaseClass
    Public Function SomeMethod() As String
        Return String.Empty
    End Function
    Public Function SomeMethod(SomeParam As String) As String
        Return "Base from String"
    End Function

    Public Function SomeMethod(SomeParam As Integer) As String
        Return "Base from Integer"
    End Function
    Public Function SomeMethod(SomeParamB As Boolean) As String
        Return "Base from Boolean"
    End Function
End Class

And this derived class:

Public Class DerivedClass
    Inherits BaseClass

    Public Shadows Function SomeMethod(SomeParam As String) As String
        Return "Derived from String"
    End Function
End Class

Now consider the implementation:

Dim DerivedInstance = New DerivedClass()

DerivedInstance have just one version of SomeMethod, and all other base versions have been shadowed.

if you compile and reference the assembly in a C# project you can see what happens:

DerivedInstance shadows method

To perform hiding in VB.Net, you still have to use the overloads (or overrides if base method is marked as overridable) keyword:

Public Class DerivedClass
    Inherits BaseClass

    Public Overloads Function SomeMethod(SomeParam As String) As String
        Return "Derived from String"
    End Function
End Class

And this is what happens after compiling:

DerivedInstance hide method

So, in VB.Net, if you use overloads keyword, on a signature that matches one on base class, you're hiding that base version of method, just like you would in c #:

public class DerivedClass : BaseClass
{
    public new string SomeMethod(string someParam)
    {
        return "Derived from String";
    }
}

Edit: This is the IL code:

From C#:

.method public hidebysig specialname rtspecialname instance void .ctor () cil managed 
{
    IL_0000: ldarg.0
    IL_0001: call instance void Shadowing_CS.BaseClass::.ctor()
    IL_0006: ret
}

.method public hidebysig instance string SomeMethod (
        string s
    ) cil managed 
{
    IL_0000: ldstr "Derived from string"
    IL_0005: ret
}

From VB:

.method public specialname rtspecialname instance void .ctor () cil managed 
{
    IL_0000: ldarg.0
    IL_0001: call instance void Shadowing_VB.BaseClass::.ctor()
    IL_0006: ret
}

.method public instance string SomeMethod (
        string s
    ) cil managed 
{
    IL_0000: ldstr "Derived from string"
    IL_0005: ret
}

So.... they are not identical.

E_net4
  • 27,810
  • 13
  • 101
  • 139
Giancarlo Melis
  • 697
  • 4
  • 17
  • 2
    Here is [a related answer from another thread](https://stackoverflow.com/a/4760614/1336654). – Jeppe Stig Nielsen Oct 18 '17 at 08:36
  • 2
    This answer is correct. When the base class has two signatures for a method name, and the inheriting class mentions only one of these signatures, then the C# keyword `new` corresponds to the VB.NET construct `Public Overloads Function SomeMethod(SomeParam As String) As String`, not to `Public Shadows Function SomeMethod(SomeParam As String) As String`. In C#, there is no way to ___hide___ the other signature as well (except if you repeat both signatures in the inheriting class, of course). C# always puts `hidebysig` in the output CIL. In VB.NET, you can hide by name alone. – Jeppe Stig Nielsen Oct 18 '17 at 09:01
  • There should be a special badge for coming up with the right answer six years after the question was posted – M.A. Hanin Oct 20 '17 at 11:09
0

They are same, its just the language specific keyword to implement the same OOP concept.

Maheep
  • 5,539
  • 3
  • 28
  • 47