De hecho, he confirmado por compilar el mismo código con Shadows
vs Overloads
de un método con un nombre idéntico y firma en la clase base y mirando a la salida de ildasm
para ambos. La única diferencia es que el caso Overloads
especifica hidebysig
.
La importancia de esto se explica mejor por Jon Skeet en this answer.
Pero simplemente significa que hay sólo una diferencia real si la clase base tiene sobrecargas del método está redefiniendo:
Shadows
causará todo de esos sobrecargas para ser uncallable través la clase derivada , donde como
Overloads
sólo reemplaza el método uno.
Tenga en cuenta que esto es sólo una construcción del lenguaje y no impuesta por la CLI (es decir, C# y VB.NET hacer cumplir esto, pero otros idiomas no).
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
La salida de los anteriores:
C1.M1
C2.M1
C1.M2
C2.M2
C1.M3
C2.M3
C1.M1(int)
C1.M1(int)
C1.M2(int)
C1.M3(int)
la salida muestra se utilizan los Shadows
llamadas cuando C2
se llama directamente y no cuando se le llama indirectamente a través de C1
.
La pregunta no es sobre anular, esto está bien. Ahora ** Overloads ** también se puede usar para ** sombrear ** un miembro existente, o un conjunto de miembros sobrecargados, en una clase base. Cuando utiliza Sobrecargas de esta manera, declara la propiedad o el método con el mismo nombre y la misma lista de argumentos que el miembro de la clase base, y no proporciona la palabra clave Sombras. Veo * new * (C#) = * Shadows * (VB.NET), ¿cuál es el C# equivalente a las sobrecargas? – serhio
@serhio: Acabo de mencionar que se debe completar porque es un concepto estrechamente relacionado. Como la palabra clave Overloads en VB también se puede usar para el sombreado, no hay un equivalente exacto en C#. En C# no hay palabra clave para sobrecargar, solo declara un método con el mismo nombre y una firma diferente para sobrecargarlo. – Guffa
por lo tanto, sus definiciones no están completas, por lo que estos 2 conceptos no están claros para mí. 'Shadows' crea una función" nueva "y' Overloads' se usa (puede usarse) para el mismo alcance. Entonces, ¿cuál es la diferencia? – serhio