Какова реальная причина предотвращения доступа защищенного члена через базовый / родной класс?
Недавно я обнаружил, что метод в производном классе может получить доступ только к базовому классу.Защищенные члены экземпляра через экземпляр производного класса (или один из его подклассов):
class Base
{
protected virtual void Member() { }
}
class MyDerived : Base
{
// error CS1540
void Test(Base b) { b.Member(); }
// error CS1540
void Test(YourDerived yd) { yd.Member(); }
// OK
void Test(MyDerived md) { md.Member(); }
// OK
void Test(MySuperDerived msd) { msd.Member(); }
}
class MySuperDerived : MyDerived { }
class YourDerived : Base { }
Мне удалось обойти это ограничение, добавив статический метод в базовый класс, так как Base 'Методы s имеют доступ к Base.Member, и MyDerived может вызывать этот статический метод.
Я до сих пор неХотя я не понимаю причину этого ограничения. Я'Мы видели несколько разных объяснений, но они не могут объяснить, почему MyDerived.Test () по-прежнему разрешен доступ к MySuperDerived.Member.
Принципиальное объяснение:Защищенные» значит этоДоступно только для этого класса и его подклассов. YourDerivedмог переопределите Member (), создав новый метод, который должен быть доступен только для YourDerived и его подклассов. MyDerived можетне вызывать переопределенный yd.Member (), потому что этоэто не подкласс YourDerived, и он можетt вызвать b.Member (), потому что b может фактически быть экземпляром YourDerived.
Хорошо, но тогда почему MyDerived может вызвать msd.Member ()? MySuperDerived может переопределить Member (), и это переопределение должно быть доступно только для MySuperDerived и его подклассов, верно?
Ты недо времени выполнения не знаю,Вызываете переопределенный член или нет. И когда участник является полем, он можетв любом случае не может быть отменено, но доступ по-прежнему запрещен.
Прагматическое объяснение:Другие классы могут добавлять инварианты, которые не делает ваш классне знаю, и вы должны использовать их общедоступный интерфейс, чтобы они могли поддерживать эти инварианты. Если бы MyDerived мог иметь прямой доступ к защищенным членам YourDerived, он мог бы сломать эти инварианты.
Мое же возражение применимо и здесь. MyDerived не делаетНе знаю, какие инварианты мог бы добавить MySuperDerived, - он может быть определен в другой сборке другим автором - так почему MyDerived имеет прямой доступ к своим защищенным элементам?
У меня складывается впечатление, что это ограничение времени компиляции существует как ошибочная попытка решить проблему, которая действительно может быть решена только во время выполнения. Но, может быть, яЯ что-то упустил. У кого-нибудь есть пример проблемы, которая может быть вызвана предоставлением MyDerived доступа к базе?Защищенные члены через переменную типа YourDerived или Base, ноне уже существует при доступе к ним через переменную типа MyDerived или MySuperDerived?
-
ОБНОВЛЕНИЕ: я знаю, что компилятор просто следует спецификации языка; то, что я хочу знать, является целью этой части спецификации. Идеальный ответ был бы, как, "Если бы MyDerived мог вызвать YourDerived.Member (), произойдет $ NIGHTMARE, но это можетэто происходит при вызове MySuperDerived.Member (), потому что $ ITSALLGOOD. "