Ombre vs Sovraccarichi in VB.NET

Quando abbiamo una new in C #, che personalmente vedo solo come soluzione alternativa per sostituire una proprietà che non ha una dichiarazione virtuale / sovrascrivibile, in VB.NET abbiamo due “concetti” Shadows e Overloads .

In tal caso preferisci l’uno all’altro?

Ci sono tre concetti strettamente correlati; sovrascrittura, ombreggiamento e sovraccarico.

L’override avviene quando si effettua una nuova implementazione per un metodo virtuale.

Lo shadowing è quando si realizza una nuova implementazione non virtuale per un metodo.

Il sovraccarico si ha quando si aggiunge un metodo con lo stesso nome ma diversi parametri.

Tutti e tre i concetti sono disponibili sia in C # che in VB.

In realtà ho confermato compilando lo stesso codice con Shadows vs Overloads per un metodo con un nome e una firma identici nella class base e guardando l’output di ildasm per entrambi. L’unica differenza è che il caso Overloads specifica hidebysig .

Il significato di questo è spiegato meglio da Jon Skeet in questa risposta .

Ma semplicemente significa che c’è solo una vera differenza se la class base ha sovraccarichi del metodo ridefinito:

  • Shadows causano l’impossibilità di tutti questi sovraccarichi attraverso la class derivata, dove come
  • Overloads sostituisce solo l’ unico metodo.

Si noti che questo è solo un costrutto linguistico e non applicato dalla CLI (cioè C # e VB.NET impongono questo, ma altre lingue potrebbero non esserlo).

Un semplice esempio di codice:

 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 

L’output di quanto sopra:

 C1.M1 C2.M1 C1.M2 C2.M2 C1.M3 C2.M3 C1.M1(int) C1.M1(int) C1.M2(int) C1.M3(int) 

L’output mostra che le chiamate Shadows vengono utilizzate quando C2 viene chiamato direttamente e non quando viene chiamato indirettamente tramite C1 .

Shadows è per i casi in cui la class base è Function SomeMethod() As String e si desidera avere Function SomeMethod() As Integer . Fondamentalmente, per cambiare il tipo di ritorno.

Overloads è per il caso in cui la class base è Function SomeMethod() As String e si desidera aggiungere un parametro come Function SomeMethod(ByVal value As Integer) As String .