Подтвердить что ты не робот

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

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

Мы не можем изменить access modifiers при переопределении класса virtual method в классе derived. Рассмотрим класс Control в пространстве имен 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()
        { }  
    }

Может ли кто-нибудь объяснить это? Благодаря

4b9b3361

Ответ 1

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

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

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

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

Проводка проста.

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

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

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

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

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

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

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

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

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

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

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

Просто, чтобы быть ясным:

  • Я и мои потомки получают доступ = защищенный доступ
  • Я и мои соседи получают доступ = внутренний доступ
  • Я и мои потомки и мои соседи получают доступ = защищенный внутренний доступ
  • Control = Asad
  • CreateChildControls = BankAccount
  • House = System.Web.DLL
  • Charlie = любой тип в System.Web.DLL
  • David = производный тип Charlie в сборке Apartment.DLL
  • Elroy = someClass
  • Кондо = ваша сборка, содержащая SomeClass
  • Greg = некоторый другой класс в Condo.DLL
  • Фрэнк = производный тип someClass в Yurt.DLL
  • Yurt = какая-то другая сборка

Ответ 2

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

Ответ 3

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