Pytanie zaimplementuj interfejs z prywatną metodą w vb.net


Byłem trochę zszokowany tym. Czy ktoś mógłby wyjaśnić, dlaczego to działa? Dobrym przykładem tego, kiedy go używać, również byłoby miłe.

Public Interface IFoo
  Sub DoIt()
End Interface

Public Class Bar
  Implements IFoo

  Private DoIt() implements IFoo.DoIt
End Class

...

Dim b as new Bar()
b.DoIt() 'error
CType(b, IFoo).DoIt() 'no error

11
2018-01-12 17:46


pochodzenie


Więc ten kod działa? Jestem zaskoczony. Wydaje się bardzo sprzeczne z ideą interfejsu. - jcollum


Odpowiedzi:


Posiadanie implementacji prywatnego interfejsu w zasadzie pozwala tylko zaimplementować interfejs bez konieczności mącenia interfejsu API twojej klasy. Możesz wdrożyć IFoo, ale tylko API, które traktują cię jak IFoo muszę o tym wiedzieć.

MSDN mówi

Możesz użyć prywatnego członka, aby zaimplementować członka interfejsu. Gdy członek prywatny implementuje członka interfejsu, ten członek staje się dostępny za pośrednictwem interfejsu, nawet jeśli nie jest dostępny bezpośrednio dla zmiennych obiektu dla klasy.


11
2018-01-12 17:58





Byłem trochę zszokowany tym. Czy ktoś mógłby wyjaśnić, dlaczego to działa? Dobrym przykładem tego, kiedy go używać, również byłoby miłe.

Ta koncepcja jest prawie analogiczna do implementacji jawnego interfejsu C #. Tam też możesz uzyskać dostęp do elementu interfejsu tylko wtedy, gdy rzucasz ten typ bezpośrednio na ten interfejs.

Nie mogę komentować czemu zespół programistów platformy .NET uznał, że ta funkcja jest rzeczywiście niezbędna. Może czasem wzmocnić hermetyzację, ale nie jestem tego pewien. W każdym razie, coś bardzo podobnego byłoby zawsze możliwe przy użyciu składu zamiast dziedziczenia (interfejsu).


6
2018-01-12 17:51



Kiedy członek jest "prywatny", służy temu samemu celowi, co implementacja jawnego interfejsu C # i ma w zasadzie tę samą semantykę (jawne C # byłoby równoważne prywatnej implementacji w stylu vb z unikalną losową prywatną nazwą). Dużą korzyścią dla podejścia VB jest implementacja interfejsów Protected Overridable Funkcje. Klasy pochodne mogą następnie implementować interfejs pod kątem implementacji rodzica, co nie jest możliwe w języku C # bez dodawania obcej warstwy. - supercat


Pierwsza część pytania została omówiona w innych postach, ale nie widziałem przykładu. Zwykle używam tego podczas implementowania ogólnych interfejsów i ich nietypowych odpowiedników. Na przykład, jeśli chcę utworzyć ogólną ObservableList, chciałbym wdrożyć oba interfejsy IList.

Public Class ObservableList(Of T)
    Implements INotifyCollectionChanged, 
               IList, 
               IList(Of T)
End Class

Kiedy obydwaj ILists są zaimplementowani, otrzymujemy wiele zduplikowanych funkcji. Niektóre mają ten sam podpis i mogą implementować obie funkcje IList, takie jak Clear. Ale niektóre z nie ogólnych funkcji zajmują się obiektami zamiast ogólnymi. Tak więc dla funkcji dodawania działałbym na obie implementacje, ale ustawię wersję nietypową jako prywatną, aby korzystanie z klasy było łatwiejsze.

Public Sub Add(item As T) Implements System.Collections.Generic.ICollection(Of T).Add
    'Add item to collection
End Sub

Private Function Add1(item As Object) As Integer Implements System.Collections.IList.Add
    'Add item to collection
End Function

W ten sposób klasa może zostać przekazana i wykorzystana jako IList, ale koder używa jej jako IList (Of T) bez potencjalnego przeciążenia.


2
2017-07-12 14:04