Sombras vs sobrecargas en VB.NET
oop method-overloading (3)
De hecho, he confirmado compilando el mismo código con Shadows
vs Overloads
para un método con un nombre y firma idénticos en la clase base y mirando el resultado de ildasm
para ambos. La única diferencia es que el caso de Overloads
especifica hidebysig
.
El significado de esto es mejor explicado por Jon Skeet en esta respuesta .
Pero simplemente significa que solo hay una diferencia real si la clase base tiene sobrecargas del método que se redefine:
-
Shadows
causarán que todas esas sobrecargas no se puedan descargar a través de la clase derivada, donde -
Overloads
solo reemplazan el único método.
Tenga en cuenta que esto es solo un constructo de lenguaje y no se aplica por la CLI (es decir, C # y VB.NET hacen cumplir esto, pero otros lenguajes pueden no hacerlo).
Un simple ejemplo de código:
Module Module1
Sub Main()
Dim a1 As C1 = New C2
Dim a2 As New C2
a1.M1()
a2.M1()
a1.M2()
a2.M2()
a1.M3()
a2.M3()
a1.M1(1)
'' Overloads on M1() allows the M1(int) to be inherited/called.
a2.M1(1)
a1.M2(1)
'' Shadows on M2() does not allow M2(int) to be called.
''a2.M2(1)
a1.M3(1)
'' Shadows on M3() does not allow M3(int) to be called, even though it is Overridable.
''a2.M3(1)
If Debugger.IsAttached Then _
Console.ReadLine()
End Sub
End Module
Class C1
Public Sub M1()
Console.WriteLine("C1.M1")
End Sub
Public Sub M1(ByVal i As Integer)
Console.WriteLine("C1.M1(int)")
End Sub
Public Sub M2()
Console.WriteLine("C1.M2")
End Sub
Public Sub M2(ByVal i As Integer)
Console.WriteLine("C1.M2(int)")
End Sub
Public Overridable Sub M3()
Console.WriteLine("C1.M3")
End Sub
Public Overridable Sub M3(ByVal i As Integer)
Console.WriteLine("C1.M3(int)")
End Sub
End Class
Class C2
Inherits C1
Public Overloads Sub M1()
Console.WriteLine("C2.M1")
End Sub
Public Shadows Sub M2()
Console.WriteLine("C2.M2")
End Sub
Public Shadows Sub M3()
Console.WriteLine("C2.M3")
End Sub
'' At compile time the different errors below show the variation.
'' (Note these errors are the same irrespective of the ordering of the C2 methods.)
'' Error: ''Public Overrides Sub M1(i As Integer)'' cannot override ''Public Sub M1(i As Integer)'' because it is not declared ''Overridable''.
''Public Overrides Sub M1(ByVal i As Integer)
'' Console.WriteLine("C2.M1(int)")
''End Sub
'' Errors: sub ''M3'' cannot be declared ''Overrides'' because it does not override a sub in a base class.
'' sub ''M3'' must be declared ''Shadows'' because another member with this name is declared ''Shadows''.
''Public Overrides Sub M3(ByVal i As Integer)
'' Console.WriteLine("C2.M3(int)")
''End Sub
End Class
El resultado de lo anterior:
C1.M1
C2.M1
C1.M2
C2.M2
C1.M3
C2.M3
C1.M1(int)
C1.M1(int)
C1.M2(int)
C1.M3(int)
El resultado muestra que las llamadas de Shadows
se usan cuando se llama directamente a C2
y no cuando se llama indirectamente a través de C1
.
Cuando tenemos algo new
en C #, personalmente lo veo como una solución para anular una propiedad que no tiene una declaración virtual / anulable, en VB.NET tenemos dos Shadows
y Overloads
"conceptos".
¿En ese caso prefieren uno a otro?
Hay tres conceptos estrechamente relacionados; anulación, sombreado y sobrecarga.
La anulación es cuando realiza una nueva implementación para un método virtual.
El remedo es cuando realiza una nueva implementación no virtual para un método.
La sobrecarga es cuando agrega un método con el mismo nombre pero diferentes parámetros.
Los tres conceptos están disponibles tanto en C # como en VB.
Shadows
es para casos en los que su clase base es Function SomeMethod() As String
y desea tener Function SomeMethod() As Integer
. Básicamente, para cambiar el tipo de devolución.
Overloads
son para el caso en el que su clase base es Function SomeMethod() As String
y desea agregar un parámetro como Function SomeMethod(ByVal value As Integer) As String
.