metody publiczne a metody wewnętrzne w klasie wewnętrznej

82
internal class Foo
{
  public void Fee()
  {
    Debug.WriteLine("Fee");
  }

  internal void Fi()
  {
    Debug.WriteLine("Fi");
  }
}

Myślę, że Fee () i Fi () są jednakowo dostępne, ponieważ cała klasa jest już wewnętrzna. Czy coś przeoczę? Czy jest jakiś powód, aby wybrać publiczne lub wewnętrzne metody w takim przypadku?

ScottS
źródło
2
@EricLippert opublikował dzisiaj swoją opinię na blogu. ericlippert.com/2014/09/15/internal-or-public/#more-2353
ScottS

Odpowiedzi:

97

internal class FooOświadczenie zastąpi dostępności tej public void Fee()metody, dzięki czemu skutecznie wewnętrzny.

W takim przypadku użycie metod wewnętrznych i publicznych przyniesie ten sam efekt. Jedynym powodem, dla którego wybrałbym metody publiczne zamiast metod wewnętrznych w takim przypadku, byłoby ułatwienie przejścia do klasy publicznej w przyszłej wersji, jeśli zdecydujesz się to zrobić.

Reed Copsey
źródło
36

Jedyne, czego brakuje w odpowiedzi, to dlaczego miałbyś to zrobić?

Niektóre biblioteki mają wiele klas, które nie są przeznaczone do dotykania przez konsumenta biblioteki, ale muszą dziedziczyć interfejsy oznaczone jako publiczne. Na przykład mam bibliotekę z klasą, która dziedziczy interfejs IComparer, ale jest używana tylko wewnętrznie i nie chcę zaśmiecać publicznego aspektu mojej biblioteki. Jeśli oznaczę zaimplementowaną funkcję Compare jako wewnętrzną, kompilator narzeka, że ​​nie implementuję interfejsu IComparer.

Jak więc z powodzeniem wdrożyć interfejs i jednocześnie uniemożliwić dostęp do niego w publicznym aspekcie mojej biblioteki? Oznacz klasę jako wewnętrzną, ale zaimplementowaną funkcję jako publiczną.


źródło
30

Właściwie - jest duża różnica, jeśli używasz odbicia; w szczególności Silverlight może się bardzo zdenerwować, jeśli spróbujesz uzyskać dostęp do metod wewnętrznych poprzez odbicie, nawet jeśli miałbyś do nich dostęp. Widziałem sytuacje, kiedy musiałem upublicznić metodę, aby kod działał w Silverlight, mimo że działa na zwykłym .NET.

Możesz znaleźć to samo w przypadku częściowego zaufania w zwykłym .NET.

Marc Gravell
źródło
3
To są te brudne szczegóły, które zawsze mnie interesują. Chociaż generalnie, jeśli ktoś używa refleksji, aby uzyskać dostęp do ukrytych członków na moich zajęciach, nie będę się martwić, jeśli będzie to dla nich trudne.
ScottS
1
@ScottS - czasami zastanawiasz się nad własnymi typami - tj. Gdzie normalnie miałbyś dostęp do metody wewnętrznej, ale nagle nie.
Marc Gravell
9

Miałoby to znaczenie, gdy chcesz, aby Twoja klasa wewnętrzna implementowała interfejs. Metoda będąca implementacją jakiegoś interfejsu musiałaby być Public.

user1343819
źródło
7

Masz rację, zarówno Opłata, jak i Fi będą równie dostępne.

Ze specyfikacji języka CSharp 3.0, pod 3.5.2:

Domena dostępności zagnieżdżonego elementu członkowskiego M zadeklarowana w typie T w programie P jest zdefiniowana w następujący sposób (zauważając, że sam M może być typem):

• Jeśli zadeklarowana dostępność M jest publiczna, domena dostępności M jest domeną dostępności T.

Tak więc, nawet jeśli Opłata zostanie zadeklarowana jako publiczna, będzie tak samo dostępna jak Foo (tj. Wewnętrzna).

eglasius
źródło
3

Zgodnie z dokumentacją msdn, twoja klasa Foo nie będzie dostępna poza twoim assemblerem, więc oznaczanie metod jako wewnętrznych lub publicznych nie ma znaczenia; nawet nie robi różnicy przy użyciu atrybutu InternalsVisibleTo

Jhonny D. Cano -Leftware-
źródło
1

Użyłbym tylko metod wewnętrznych, jeśli klasa jest wewnętrzna. w przypadku, gdy zmienisz zdanie i upublicznisz klasę, możesz po prostu zastąpić tekst i gotowe.

gnikolaropoulos
źródło