Подтвердить что ты не робот

Есть ли способ получить "защищенный" элемент другого объекта из производного типа?

class MyBase
{
    protected object PropertyOfBase { get; set; }
}

class MyType : MyBase
{
    void MyMethod(MyBase parameter)
    {
        // I am looking for:
        object p = parameter.PropertyOfBase;  // error CS1540: Cannot access protected member 'MyBase.PropertyOfBase' via a qualifier of type 'MyBase'; the qualifier must be of type 'MyType' (or derived from it)
    }
}

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

4b9b3361

Ответ 1

Нет, вы не можете этого сделать.

Вам разрешен доступ только к защищенным членам объектов типа доступа (или полученным из него). Здесь мы не знаем, имеет ли параметр тип MyType или SomeOtherCompletelyDifferentType.

EDIT: соответствующий бит спецификации С# 3.0 - это раздел 3.5.3:

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

Ответ 2

В прошлый раз, когда я столкнулся с аналогичной проблемой, я использовал решение о добавлении защищенного статического метода в базу:

class MyBase
{
    protected object PropertyOfBase { get; set; }

    protected static object GetPropertyOfBaseOf(MyBase obj) 
    {
        return obj.PropertyOfBase;
    }
}

class MyType : MyBase
{
    void MyMethod(MyBase parameter)
    {
        object p = GetPropertyOfBaseOf(parameter);
    }
}

Ответ 3

Там хорошая причина, по которой вы не можете этого сделать. Предположим, кто-то пишет:

class Other : MyBase { }

new MyType().MyMethod(new Other());

Если язык разрешил то, о чем вы просите, вы можете нарушить предполагаемые инварианты Other, изменив значение PropertyOfBase.

Ответ 4

Я думаю, вы должны спросить себя, есть ли лучший способ сделать то, что вы хотите сделать. Вы хотите, чтобы PropertyOfBase действовал как открытый в контексте MyType.MyMethod(), но для защиты во всех других ситуациях. Почему?

Ответ 5

Защищенное свойство доступно только экземпляру производного класса, а не экземплярам производных классов.

Есть разница, и имеет смысл, защищенные члены не должны отказываться от своего значения ни к какому другому экземпляру, даже к экземпляру, полученному из того же типа.

(Отредактировано, немного привязано к языку!)