Какова реальная причина предотвращения доступа защищенного члена через базовый / родной класс?

Недавно я обнаружил, что метод в производном классе может получить доступ только к базовому классу.Защищенные члены экземпляра через экземпляр производного класса (или один из его подклассов):

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. "

Ответы на вопрос(6)

Ваш ответ на вопрос