Я читал, что к защищенному члену можно получить доступ из производных классов. Почему мое использование слова «защищенный» не работает?
Это незаконно, потому что вы не предоставили гарантии, что получаете доступ к данным экземпляра «B». Рассмотрим аналогичный случай:
abstract class BankAccount
{
protected int accountNumber;
}
class SwissBankAccount : BankAccount
{
}
--- in another assembly, evil-doers write ---
class EvilBankAccount : BankAccount
{
void DoEvil()
{
BankAccount b = GetASwissBankAccount();
int number = b.accountNumber;
}
}
EvilBankAccount не наследуется от SwissBankAccount, поэтому защищенный член SwissBankAccount не может использоваться внутри EvilBankAccount. Вам разрешен доступ к защищенным членам ваших «родителей», но не вашим «братьям и сестрам»! EvilBankAccount может получить доступ только к защищенным членам EvilBankAccount (или типу, производному от EvilBankAccount). Доступ к защищенным членам SwissBankAccount запрещен.
Правило состоит в том, что тип выражения «получателя», к которому осуществляется доступ через, должен быть, по крайней мере, таким же производным, как и объявление типа, содержащее доступ к члену. Точную формулировку правила и некоторые наглядные примеры см. В разделе 3.5.3 спецификации C # 4.0.
Кстати, в C ++ тоже есть это правило.
Это правило часто понимают неправильно. Более подробный анализ этого правила и некоторых других последствий защищенного доступа можно найти в моих статьях на эту тему. Самые актуальные статьи, которые я написал на эту тему, - это этот и этот. Я написал еще несколько статей на похожие темы здесь (хотя некоторые из них уходят от темы самого защищенного доступа к теме того, как использовать защищенный доступ для построения модели данных с родительскими ссылками.)
person
Eric Lippert
schedule
12.04.2011