2010-03-25 19 views
20

Cuando tenemos new en C#, personalmente veo solo como una solución para anular una propiedad que no tiene una declaración virtual/anulable, en VB.NET tenemos dos "conceptos" Shadows y Overloads.Sombras vs sobrecargas en VB.NET

¿En ese caso prefieren uno a otro?

Respuesta

13

Hay tres conceptos estrechamente relacionados; anulación, sombreado y sobrecarga.

Reemplazando es cuando realiza una nueva implementación para un método virtual.

sombreado es cuando realiza una nueva implementación no virtual para un método.

Sobrecarga es cuando se agrega un método con el mismo nombre pero con parámetros diferentes.

Los tres conceptos están disponibles tanto en C# como en VB.

+1

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

+0

@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

+1

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

0

Shadows es para los 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 es para el caso donde su clase base es Function SomeMethod() As String y desea agregar un parámetro como Function SomeMethod(ByVal value As Integer) As String.

+2

** Las sobrecargas ** también se pueden 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. – serhio

16

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.