2010-04-01 2 views
50

Итак, это может быть немного глупый вопрос, и, безусловно, есть очевидный ответ, но мне было любопытно, если я пропустил какие-то тонкости здесь.Публичные и внутренние члены во внутреннем классе?

Есть ли разница с точки зрения видимости/практичности между public член объявлен в классе internal и internal члена, объявленного в internal классе?

т.е. между

internal class Foo 
{ 
    public void Bar() 
    { 
    } 
} 

и

internal class Foo 
{ 
    internal void Bar() 
    { 
    } 
} 

Если вы объявили метод как public, а также virtual, а затем отменяют его в производном классе, который public, причина для использования этого модификатора чисто. Однако, это единственная ситуация ... я пропустил что-то еще?

+2

_If вы объявили метод общедоступным, а также виртуальным, а затем переопределите его в производном классе, который является public_ ** meeeep! **: вам не разрешено увеличивать видимость, только наоборот: вы можете создать производный класс открытого класса, который является внутренним (или даже вложенным и приватным) – springy76

+2

Гуглеры принимают к сведению: этот почти дубликат [вопрос] (http://stackoverflow.com/questions/9302236/why-use-a-public-method -in-an-internal-class/9302642 # 9302642) содержит еще один особенно отличный ответ. –

ответ

47

Рассмотрим этот случай:

public interface IBar { void Bar(); } 
internal class C : IBar 
{ 
    public void Bar() { } 
} 

Здесь C.Bar не могут быть помечены как внутренние; делать это ошибка, потому что C.Bar можно получить с помощью вызывающей D.GetBar():

public class D 
{ 
    public static IBar GetBar() { return new C(); } 
} 
+1

Спасибо Эрик, это еще один хороший случай. Таким образом, эффективная реализация интерфейса и наследование классов - это причины, позволяющие либо «публичный», либо «внутренний» модификатор в «внутреннем» классе. В других случаях они эквивалентны. – Noldorin

+8

Эрик также отвечает на почти идентичный вопрос по адресу: http://stackoverflow.com/a/9302642/398015. В его сообщении есть дополнительные сведения, которые добавляют существенное содержание в ответ выше. – Chris

0

public членов в internal класса могут переопределить publicpublic членов базовых классов и, следовательно, быть немного более подвержены ... если косвенно.

29

A public член все еще только internal когда в internal класс.

From MSDN:

The accessibility of a member can never be greater than the accessibility of its containing type. For example, a public method declared in an internal type has only internal accessibility

Подумайте об этом так, я бы доступ к public собственности на ....? Класс, который я не вижу? :)

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

+0

Да, это была именно моя мысль, за исключением случая, в котором указал Эрик (а также тот, который был в моем первоначальном вопросе). – Noldorin

+0

Это также имеет значение, когда вы используете отражение. Методы без параметров по умолчанию, такие как Type.GetMethods(), возвращают только публичные элементы. И общедоступный метод внутри внутреннего класса все еще знает, что он является общедоступным. – springy76

+1

«Доступность элемента никогда не может быть больше, чем доступность его содержащего типа». Хотя это справедливо для некоторых случаев, «публичный» член класса «private» явно имеет более широкий охват, чем «частный» член класса «private» (первый из них является проектом, последний из которых является только классом). – Deanna

1

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

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

1

Просто столкнулся с другим примером, где является Разница между этими двумя, при использовании из XAML в WPF.

XAML:

<Button Tag="{x:Static vm:Foo+Bar.e1}" /> 

код с internal перечислимого успешно компилируется:

internal class Foo 
{ 
    internal enum Bar 
    { 
     e1, 
     e2, 
    } 
} 

Но удивительно изменяя его public приводит к ошибке:

internal class Foo 
{ 
    public enum Bar 
    { 
     e1, 
     e2, 
    } 
} 

Последний пример производит ошибку компиляции :

error MC3064: Only public or internal classes can be used within markup. 'Bar' type is not public or internal.

К сожалению, я не могу объяснить, что не так с public в этом случае. Я предполагаю, что «просто потому, что WPF работает именно так». Просто измените модификатор вложенного класса на internal, чтобы избавиться от ошибки.

+0

Спасибо за это! Я бы никогда не догадался, что случилось с моим XAML – torvin

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