Это 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()
{ }
}
какое-либо тело может объяснить это?Спасибо
Мы не можем изменять модификаторы доступа при переопределении виртуального метода в производном классе.
Это утверждение неверно. Вы можете и должны изменять модификаторы доступа именно в той ситуации, которую вы описали. В других ситуациях вы не должны изменять модификаторы доступа.
Я отсылаю вас к разделу 10.6.4 спецификации, который гласит:
объявление переопределения не может изменить доступность виртуального метода. Однако, если переопределенный базовый метод является защищенным внутренним и он объявлен в другой сборке чем сборка, содержащая переопределенный метод, то переопределенный объявленная доступность переопределенного метода должна быть защищенной.
Рассуждения просты.
У вас, Асад, есть банковский счет, BankAccount.
У вас есть дом. Вы сдаете комнату в доме своему лучшему другу Чарли.
У Чарли есть сын Дэвид, который живет в квартире.
У вас есть сын Элрой, который живет в кондоминиуме.
У Элроя есть сын, ваш внук, Фрэнк, который живет в юрте.
У Элроя есть лучший друг Грег, который живет с ним в Кондо.
Вы предоставляете доступ к вашему BankAccount себе, всем, кто живет в House, и любому из ваших потомков. Таким образом, доступ к банковскому счету могут получить Асад, Чарли, Элрой и Фрэнк.
Дэвид не получает доступа, потому что он не является ни вами, ни вашим потомком, ни живущим в доме. То, что он является ребенком вашего соседа по дому, не имеет значения; он не получает доступа к вашему банковскому счету.
Грег также не имеет доступа к вашему банковскому счету. Он не является вашим потомком. Он не живет в Доме. Тот факт, что он живет с вашим потомком, не дает ему тех же прав, что и вашему потомку.
Теперь мы подходим к сути вопроса. Элрой не имеет права предоставлять Грегу доступ к вашему банковскому счету. Вы владеете этим банковским счетом, и вы сказали "я, мои потомки и мои соседи по дому". Ваши дети не имеют права расширять доступ к BankAccount за пределы того, что вы изначально установили.
Когда Элрой описывает, какой доступ он имеет к BankAccount, он имеет право сказать только "Я предоставляю доступ к этому себе и своим потомкам", потому что это то, что вы уже разрешили. Он не может сказать: "Я предоставляю доступ к BankAccount себе, своим потомкам и другим жителям Кондо".
Для ясности:
Потому что, хотя терминология иная, переопределение ее как protected
сохраняет видимость элемента той же самой. Если бы вам было разрешено переопределить его как protected internal
, то вы внезапно открыли бы член для любого другого типа в вашей сборке.
Защищенный внутренний означает защищенный ИЛИ внутренний. Таким образом, если при переопределении за пределами исходной сборки вам разрешили пометить ее как защищенную внутреннюю, вы позволили бы другим классам в той же сборке, что и переопределитель, вызывать этот метод. Это фактически означало бы, что внутренняя инкапсуляция исходного родителя будет нарушена.