23

C# では、個人的には仮想/オーバーライド可能な宣言を持たnewないプロパティをオーバーライドするための回避策としてのみ見られますが、VB.NET では 2 つの「概念」ShadowsOverloads.

どちらの場合、どちらを優先しますか?

4

4 に答える 4

22

基本クラスで同じ名前とシグネチャを持つメソッドに対してShadowsvsを使用して同じコードをコンパイルし、両方の出力を見て、実際に確認しました。唯一の違いは、大文字と小文字が指定されていることです。OverloadsildasmOverloadshidebysig

この重要性は、Jon Skeet がこの回答で最もよく説明しています。

しかし、基本クラスに再定義されるメソッドのオーバーロードがある場合にのみ、実際の違いがあることを意味します。

  • Shadowsこれらのオーバーロードはすべて、派生クラスを介して呼び出すことができなくなります 。
  • Overloads1 つのメソッドのみを置き換えます。

これは単なる言語構造であり、CLI によって強制されるものではないことに注意してください (つまり、C# と VB.NET ではこれが強制されますが、他の言語では強制されない場合があります)。

簡単なコード例:

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

上記の出力:

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

出力は、を介して間接的に呼び出されたときではなく、 が直接呼び出さShadowsれたときに呼び出しが使用されることを示しています。C2C1

于 2011-01-21T15:37:28.820 に答える
16

密接に関連する 3 つの概念があります。オーバーライド、シャドーイング、オーバーロード。

オーバーライドとは、仮想メソッドの新しい実装を作成することです。

シャドーイングとは、メソッドの新しい非仮想実装を作成することです。

オーバーロードとは、同じ名前でパラメーターが異なるメソッドを追加することです。

3 つの概念はすべて、C# と VB の両方で利用できます。

于 2010-03-25T11:43:03.550 に答える
0

Shadowsは、基本クラスが でFunction SomeMethod() As Stringあり、 が必要な場合ですFunction SomeMethod() As Integer。基本的に、戻り値の型を変更します。

Overloadsは、基本クラスがFunction SomeMethod() As Stringあり、などのパラメーターを追加する場合ですFunction SomeMethod(ByVal value As Integer) As String

于 2010-03-25T11:40:38.673 に答える