2009-04-02 6 views
78
internal class Foo 
{ 
    public void Fee() 
    { 
    Debug.WriteLine("Fee"); 
    } 

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

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

+1

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

ответ

94

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

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

+2

+1 Мои мысли точно! – si618

2

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

6

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

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

Доступность домена вложенного элемента М, объявленного в типа Т в пределах программы P определяется следующим образом (заметим, что М сам по себе может быть, возможно, типа):

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

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

25

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

Возможно, вы найдете то же самое с частичным доверием к обычной .NET.

+3

Это такие грязные детали, которые меня всегда интересуют. Хотя, как правило, если кто-то использует рефлексию для доступа к скрытым членам в моих классах, я не буду волноваться, если им это сложно. – ScottS

+1

@ScottS - иногда вы размышляете над своими * собственными * типами - то есть, где вы обычно имеете доступ к внутреннему методу, но внезапно вы этого не делаете. –

32

Единственное, чего не хватает в ответе, почему вы это сделаете?

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

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

0

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

7

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