1

シャドウイングとオーバーライドの違いを説明する質問や他の Web ページがかなりあることは知っています。残念ながら、私はまだどちらを使用すべきかを理解していません。

私の状況は次のとおりです。System.ComponentModel.BindingList特定の型の を継承するクラスを作成して、追加や削除などの操作をスレッドセーフにしたいと考えています。

私の基本クラスが次の場合:

Imports System.ComponentModel

Public Class DeviceUnderTestBindingList

Inherits System.ComponentModel.BindingList(Of DeviceUnderTest)

Private Sub New()
    MyBase.New()
End Sub

Public Sub Add(ByVal device As DeviceUnderTest)
    MyBase.Add(device)
End Sub

Public Sub Remove(ByVal deviceKey As UInteger)
    MyBase.Remove(deviceKey)
End Sub
End Class

このクラスを使用している人が、BindingList のメソッドではなく、私が提供した .Add および .Remove メソッドのみを使用できるようにしたいと考えています。しかし、クラスが BindingList メソッドに内部的にアクセスできるようにしたいと考えています。たとえば、現在、.Add メソッドがある時点で BindingList.Add メソッドを呼び出していることがわかります。

私は両方shadowsで試してみましたが、どちらoverridesも同じ効果があるようです。この状況では、一方が他方よりも正しいのはなぜですか?

4

2 に答える 2

4

過負荷はまったく異なる概念です。本質的に、オーバーロードにより、メソッドをオーバーライドして元の動作を「置換」しながら、複数のAdd()andRemove()メソッドを使用できます。シャドーイングはその中間です。シャドウイングは元の動作を「隠します」が、基本型にキャストすることで基本メソッドにアクセスできます。

一般的に言えば、代わりにオーバーライドできる場合は、メンバーをシャドウしません。よほどの特別な理由がない限り。

同じメンバーをオーバーライドしてシャドウすることはできないことに注意してください。ただし、たとえば、元のAdd()メソッドのオーバーライドとオーバーロードの両方を行うことができます。

編集

Add()メソッドをオーバーライドすることはできませんが、オーバーライドすることはできますOnAddingNew()。同様に、 をオーバーライドすることはできませんがRemove()、オーバーライドすることはできますRemoveItem()。このクラスの詳細はわかりませんが、裏でRemove()使用RemoveItem()されていると思われます。

実装は次のようになります。

Imports System.ComponentModel
Imports System.Collections.ObjectModel

Public Class DeviceUnderTestBindingList
    Inherits BindingList(Of DeviceUnderTest)

    Private Sub New()
        MyBase.New()
    End Sub

#Region "Add()"

    Protected Overrides Sub OnAddingNew(e As AddingNewEventArgs)
        Dim newDevice As DeviceUnderTest = DirectCast(e.NewObject, DeviceUnderTest)

        Try
            If (Not IsValidEntry(newDevice)) Then ' don't add the device to the list
                Exit Sub
            End If

            ' (optionally) run additional code
            DoSomethingWith(newDevice)
        Finally
            MyBase.OnAddingNew(e)
        End Try
    End Sub

    Private Function IsValidEntry(device As DeviceUnderTest) As Boolean
        ' determine whether the specified device should be added to the list
        Return True Or False
    End Function

    Private Sub DoSomethingWith(newDevice As DeviceUnderTest)
        ' This is where you run additional code that you would otherwise put in the 'Add()' method.
        Throw New NotImplementedException
    End Sub

#End Region ' Add()

#Region "Remove()"

    Public Shadows Function Remove(device As DeviceUnderTest) As Boolean
        Try
            RemoveItem(IndexOf(device))
        Catch
            Return False
        End Try
        Return True
    End Function

    Protected Overrides Sub RemoveItem(index As Integer)
        MyBase.RemoveItem(index)
    End Sub

#End Region ' Remove()

End Class
于 2013-08-26T12:42:58.453 に答える
1

この質問と受け入れられた回答を見てください。これは、私の知る限り、VB.NET &と意味が同じである C# new&キーワードの違いを説明しています。overrideshadowsoverrides

あなたの場合、使用することをお勧めしoverrideます。より一般的には、これを行う理由が確実にわかっている場合にのみshadows(またはC# で) 使用することをお勧めします。new

このshadowsキーワードを使用すると、ユーザーは、クラスで定義したものではなく、メソッドの基本型バージョンを呼び出すことができるようになります。メソッドのoverridesあなたのバージョンでは、両方のケースで呼び出されます。

于 2013-08-26T11:19:51.403 に答える