Защищенные члены C#, доступ к которым осуществляется через переменную базового класса

StackOverflow https://stackoverflow.com/questions/1836175

Вопрос

На этот вопрос уже есть ответ здесь:

Это может показаться вопросом для новичков, но можете ли вы объяснить, почему метод Der.B() не может получить доступ к защищенному Foo через переменную базового класса?Мне это кажется странным:

public class Base
{
    protected int Foo;
}

public class Der : Base
{
    private void B(Base b) { Foo = b.Foo; } // Error: Cannot access protected member

    private void D(Der d) { Foo = d.Foo; } // OK
}

Спасибо!

Это было полезно?

Решение

Это часто задаваемый вопрос.Чтобы понять, почему это незаконно, подумайте, что может пойти не так.

Предположим, у вас есть другой производный класс Frob, производный от Base.Теперь вы передаете экземпляр Frob Der.B.Должен ли у вас быть доступ к Frob.Foo из Der.B?Нет, абсолютно нет.Frob.Foo защищен;он должен быть доступен только из Frob и подклассов Frob.Der не является Frob и не является подклассом Frob, поэтому он не имеет доступа к защищенным членам Frob.

Если что-то не понятно, читайте мою статью на эту тему:

http://blogs.msdn.com/ericlippert/archive/2005/11/09/491031.aspx

Другие советы

В B вы пытаетесь получить доступ к защищенному члену другого класса.Тот факт, что вы наследуете от этого класса, не имеет значения.В D вы получаете доступ к защищенному члену базового класса вашего текущего класса.В этом контексте вы можете получить доступ к чему угодно из Der и защищенных членов типа, от которого он наследуется.

Это ограничение можно обойти, объявив статический метод в базовом классе:

public class Base
{
    protected int Foo;

    protected static int GetFoo(Base b)
    {
        return b.Foo;
    }
}

public class Der : Base
{
    private void B(Base b) { Foo = GetFoo(b); } // OK
}

Проще говоря, protected разрешает доступ к подклассам.

В:

private void B(Base b) { Foo = b.Foo; }

Вы пытаетесь получить доступ к защищенному участнику, к которому у вашего экземпляра Der нет доступа.Он имел бы к нему доступ только в том случае, если бы это был базовый класс вашего текущего экземпляра Der (this).

private void D(Der d) { Foo = d.Foo; } // OK

Работает нормально, потому что вы проходите через Der для доступа к защищенному методу базовых классов.

В сценарии, который вы пытаетесь использовать, вам нужно будет использовать «внутренний» для int Foo.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top