2013-08-26 4 views
1

Я знаю, что существует немало вопросов и других веб-страниц, объясняющих разницу между затенением и переопределением. К сожалению, я до сих пор не понял, какой из них я должен использовать.Должен ли я тень или переопределение?

Моей ситуацией является следующее: Я хочу создать класс, который наследует 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 

Я хотел бы кто-то использует этот класс, чтобы только быть в состоянии использовать методы .Add и .Отвернуть, которые я предоставил, а не те, из BindingList , Но я хотел бы, чтобы мой класс имел возможность получить доступ к методам BindingList внутренне, например. вы можете увидеть, что мой метод .Add в настоящее время вызывает метод BindingList.Add в какой-то момент.

Я пробовал его как с shadows, так и с overrides, и оба они кажутся одинаковыми, так что это правильнее, чем в этой ситуации и почему?

+0

В этом вопросе я на самом деле означало перегрузках, где я написал переопределение - обвинить в понедельник! – Toby

ответ

2

Перегрузка - это совершенно другая концепция. В сущности, перегрузка позволяет вам использовать несколько методови Remove(), а переопределение метода «заменяет» исходное поведение. Тень находится где-то посередине. Shadowing «скрывает» исходное поведение, но вы все равно можете получить доступ к базовому методу путем литья в базовый тип.

Вообще говоря, вы не затеняете член, если можете вместо этого переопределить его. Если у вас нет особых причин для этого.

Обратите внимание, что вы не можете переопределить и скрыть один и тот же элемент. Но вы можете, например, переопределить и перегрузить исходный метод Add().

EDIT

Вы не можете переопределить метод 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 
+0

Спасибо. Когда я пытаюсь переопределить соответствующие методы, VS говорит мне, что метод не переопределяем, и я не хочу использовать мои методы как-хорошо, но вместо этого, поэтому я предполагаю, что это достаточно точно, чтобы использовать тени? – Toby

+2

Поскольку базовый метод не является переопределяемым, тень является единственным вариантом. Тем не менее, это не значит, что это лучшее решение. Обычно стоит искать альтернативную стратегию (например, шаблон адаптера). См. Мой обновленный ответ для обходного пути. –

1

Обратите внимание на вопрос this и принятый ответ. Он объясняет разницу между ключевыми словами, которые AFAIK, то же, что в значении, для VB.NEt shadows &.

В вашем случае я бы рекомендовал использовать override. В более общем плане, лучше использовать shadows (или new в C#) только в том случае, если вы точно знаете, почему вы хотите это сделать.

Если вы используете ключевое слово shadows, пользователи смогут вызывать базовую версию метода, а не тот, который вы определяете в своем классе, - если они назовут его ссылкой на базовый тип. С overrides ваша версия метода будет вызываться в обоих случаях.

+0

Gah! Я хотел написать перегрузки! Поскольку .Remove и .Add не являются переопределяемыми. То же самое и для теней и перегрузок? – Toby

+1

Ну, если мы рассматриваем перегрузку, то это действительно другая концепция, и это вряд ли имеет отношение к вашей проблеме. Поскольку вы не можете переопределить базовые методы, единственный вариант, с которым вы остались, - это скрытие/затенение. С другой стороны, я бы предложил избегать этого. Причина в том, что он не допускает полиморфизма, и это не удобно на самом деле. На мой взгляд, вам лучше ввести несколько новых методов с разными именами, в которых будет четко указано, что на самом деле делают методы и как они отличаются от исходного Add/Remove. –

Смежные вопросы