C # защищенное поле для частного, добавить свойство - почему? - PullRequest
5 голосов
/ 09 ноября 2009

В Visual Studio 2008 Team System я только что запустил Анализ кода (из меню Анализ) в одном из моих проектов на C #. Одним из предупреждений было следующее:

Microsoft.Design: поскольку поле «Connection._domain» видно за пределами его объявленного типа, измените его доступность на private и добавьте свойство с той же доступностью, что и у поля в настоящее время, чтобы обеспечить доступ к нему.

Это относится к следующему полю:

public abstract class Connection
{
    protected string _domain;
}

Я не понимаю причину этого предложения. Это то, что, я думаю, оно хочет от меня:

public abstract class Connection
{
    private string _domain;
    protected string Domain { get { return _domain; } set { _domain = value; } }
}

Два вопроса:

  1. Правильно ли я понял, что это предложение хочет от меня, по коду?
  2. Почему он хочет, чтобы я это сделал?

Ответы [ 8 ]

13 голосов
/ 09 ноября 2009

Да, я думаю, вы поняли правильно - хотя в более поздних версиях C # есть более краткий способ написать это:

public string Domain { get; set; }

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

2 голосов
/ 09 ноября 2009

Ваш перевод правильный. Можно использовать тот же аргумент для использования «защищенных» свойств, что и для использования «открытых» свойств вместо непосредственного предоставления переменных-членов.

Если это просто приводит к распространению простых методов получения и установки, то я думаю, что ущерб читабельности кода перевешивает выгоду от возможности изменить код в будущем. С развитием сгенерированных компилятором свойств в C # это не так уж и плохо, просто используйте:

protected string Domain { get; set; }
2 голосов
/ 09 ноября 2009

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

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

2 голосов
/ 09 ноября 2009
  1. Да, вы исправили код проблемы.
  2. Речь идет об инкапсуляции. _domain - это данные о вашем объекте. Вместо того, чтобы выставлять его напрямую, чтобы у любого клиента был нефильтрованный доступ, вы должны предоставить интерфейс для доступа к нему. Практически это может быть добавление проверки к установщику, чтобы она не могла быть установлена ​​ни на какое значение. Это может показаться глупым, если вы пишете код только потому, что знаете, как работает ваш API. Но попробуйте подумать о вещах на уровне крупного предприятия, лучше иметь API, чтобы ваш объект можно было увидеть как блок, который выполняет задачу. Вы можете сказать, что у вас никогда не будет необходимости добавлять что-то вроде валидации к этому объекту, но все сделано таким образом, чтобы обеспечить возможность этого, а также быть последовательным.
2 голосов
/ 09 ноября 2009

Да. Это предложение. Вы не должны иметь доступность выше, чем частная доступность как поля прямого экземпляра.

Это один из основных принципов OOD - инкапсуляция, также называемая «сокрытием данных».

0 голосов
/ 10 ноября 2009

В дополнение к другим ответам, упомянутым здесь, открытые / защищенные члены, начинающиеся с подчеркивания, не CLS-совместимые , поскольку для языков .NET не требуется поддержка членов с ведущими подчеркиваниями поэтому кто-то, унаследованный от вашего класса на другом языке .NET, может не иметь доступа к этому конкретному защищенному члену.

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

0 голосов
/ 09 ноября 2009

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

В выбранном ответе по ссылке лучше всего сказано: «Свойства обеспечивают инкапсуляцию. Вы можете инкапсулировать любую необходимую проверку / форматирование / преобразование в коде для свойства. Это будет трудно сделать для полей».

http://social.msdn.microsoft.com/Forums/en-IE/netfxbcl/thread/985f4887-92ae-4ec2-b7ae-ec8cc6eb3a42

0 голосов
/ 09 ноября 2009

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

Однако я бы просто использовал синтаксис автоматического свойства:

public abstract class Connection
{
    protected string Domain { get; set; }
}
...