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

Это extension поскольку этот вопрос спросил час назад.

Мы не можем изменить access modifiers, при переопределении a 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()
        { }  
    }

какое-либо тело может объяснить это?Спасибо

27
задан Community 23 May 2017 в 10:29
поделиться

3 ответа

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

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

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

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

Рассуждения просты.

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

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

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

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

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

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

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

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

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

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

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

Для ясности:

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

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

7
ответ дан 28 November 2019 в 04:52
поделиться

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

3
ответ дан 28 November 2019 в 04:52
поделиться
Другие вопросы по тегам:

Похожие вопросы: