переопределение защищенного внутреннего с защищенным!

Это extension для этого вопроса, заданного час назад.

Мы не можем модифицировать access modifiers при переопределении virtual method в derived classе. Рассмотрим class Control в System.Web.UI имен System.Web.UI

 public class Control : IComponent, IDisposable,... { protected internal virtual void CreateChildControls() { } . . } 

Теперь рассмотрим это

 public class someClass : System.Web.UI.Control { // This should not compile but it does protected override void CreateChildControls() { } // This should compile but it does not protected internal override void CreateChildControls() { } } 

может ли любой орган объяснить это? Спасибо

    Мы не можем модифицировать модификаторы доступа при переопределении виртуального метода в производном classе.

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

    Я отсылаю вас к разделу 10.6.4 спецификации, в котором говорится:

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

    Выводы просты.

    У вас, Асад, есть банковский счет BankAccount.

    У тебя есть дом. Вы арендуете комнату в Доме своему лучшему другу Чарли.

    У Чарли есть сын Давид, который живет в квартире.

    У вас есть сын, Элрой, который живет в Кондо.

    У Элроя есть сын, твой внук, Фрэнк, который живет в Юрте.

    У Элроя есть лучший друг Грег, который живет в Кондо вместе с ним.

    Вы предоставляете доступ к своей Банковской платете себе, любому, кто живет в Доме, и любому из ваших потомков. Таким образом, люди, которые могут получить доступ к банковскому счету, это Асад, Чарли, Элрой и Фрэнк.

    Дэвид не получает доступа, потому что он не является ни вами, ни вашим потомком, ни он живет в Доме. То, что он ребенок вашего соседа по дому, не имеет значения; он не получает доступ к вашему BankAccount.

    Грег также не получает доступ к вашему банковскому счету. Он не твой потомок. Он не живет в Доме. Тот факт, что он живет с вашим потомком, не дает ему тех же прав, что и ваш потомок.

    Теперь мы переходим к сути дела. Элроу не разрешено предоставлять доступ к вашему Банку-счету Грегу. У вас есть этот BankAccount, и вы сказали «я, мои потомки и мои соседи по дому». Ваши дети не имеют права расширять доступность BankAccount сверх того, что вы изначально создали.

    Когда Элрой описывает, какой доступ он имеет к BankAccount, ему разрешено говорить «Я предоставляю доступ к этому себе и моим потомкам», потому что это то, что вы уже допустили. Он не может сказать: «Я предоставляю доступ к BankAccount себе, моим потомкам и другим жителям Кондо».

    Просто быть чистым:

    • Я и мои потомки получают доступ = защищенный доступ
    • Я и мои соседи получают доступ = внутренний доступ
    • Я и мои потомки и мои соседи получают доступ = защищенный внутренний доступ
    • Управление = Асад
    • CreateChildControls = BankAccount
    • Дом = System.Web.DLL
    • Charlie = любой тип в System.Web.DLL
    • Дэвид = производный тип Чарли в сборке Apartment.DLL
    • Elroy = someClass
    • Condo = ваша assembly, содержащая SomeClass
    • Greg = какой-то другой class в Condo.DLL
    • Frank = производный тип someClass в Yurt.DLL
    • Юрт = какая-то другая assembly

    Потому что, хотя терминология отличается, переопределение ее как protected сохраняет видимость элемента одинаковым. Если вам разрешено переопределить его как protected internal , то вы внезапно будете подвергать участника другому типу сборки.

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