публичные и внутренние методы во внутреннем классе

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

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

Я думаю, что Fee () и Fi () одинаково доступны, поскольку весь класс уже внутренний. Я что-то не замечаю? Есть ли причина выбирать публичные или внутренние методы в таком случае?

ScottS
источник
2
@EricLippert опубликовал сегодня свое мнение в блоге. ericlippert.com/2014/09/15/internal-or-public/#more-2353
ScottS

Ответы:

97

internal class FooДекларация переопределяет доступность public void Fee()метода, фактически делает его внутреннее.

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

Рид Копси
источник
36

Единственное, чего здесь не хватает, - это зачем вам это делать?

В некоторых библиотеках есть много классов, которые не предназначены для того, чтобы потребитель библиотеки мог их касаться, но они должны наследовать интерфейсы, отмеченные как общедоступные. Например, у меня есть библиотека с классом, который наследует интерфейс IComparer, но он используется только внутри, и я не хочу загромождать публичный аспект моей библиотеки. Если я помечу реализованную функцию сравнения как внутреннюю, компилятор пожалуется, что я не внедряю интерфейс IComparer.

Итак, как мне успешно реализовать интерфейс и в то же время предотвратить его доступность в публичном аспекте моей библиотеки? Отметьте класс как внутренний, а реализованную функцию как общедоступную.


источник
30

На самом деле - большая разница, если вы используете отражение; в частности, Silverlight может сильно расстроиться, если вы попытаетесь получить доступ к внутренним методам через отражение, даже если бы у вас был доступ. Я видел случаи, когда мне приходилось делать метод общедоступным, чтобы код работал в Silverlight, даже если он работает в обычном .NET.

Вы можете обнаружить то же самое при частичном доверии к обычному .NET.

Марк Гравелл
источник
3
Это своего рода грязные детали, которые меня всегда интересуют. Хотя, как правило, если кто-то использует отражение для доступа к скрытым членам в моих классах, я не буду беспокоиться, если для них это будет сложно.
ScottS
1
@ScottS - иногда вы размышляете над своими собственными типами - то есть там, где у вас обычно есть доступ к внутреннему методу, но внезапно нет.
Марк Гравелл
9

Это будет иметь значение, когда вы хотите, чтобы ваш внутренний класс реализовал интерфейс. Метод, который является реализацией некоторого интерфейса, должен быть Public.

пользователь1343819
источник
7

Вы правы, и Fee, и Fi будут одинаково доступны.

Из спецификации языка CSharp 3.0 в разделе 3.5.2:

Область доступности вложенного члена M, объявленного в типе T в программе P, определяется следующим образом (с учетом того, что сам M может быть типом):

• Если заявленная доступность M является общедоступной, область доступности M является областью доступности T.

Таким образом, даже если Fee объявлен как общедоступный, он будет таким же доступным, как и Foo (т.е. внутренний).

eglasius
источник
3

Согласно документации msdn, ваш класс Foo не будет доступен за пределами вашей сборки, поэтому нет никакой разницы в том, чтобы пометить методы как внутренние или общедоступные; это даже не имеет значения, используя Attribute InternalsVisibleTo

Джонни Д. Кано -Посуда-
источник
1

Я бы использовал только внутренние методы, если класс внутренний. если вы передумаете и сделаете класс общедоступным, вы можете просто заменить текст, и все готово.

гниколаропулос
источник