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

Это то, с чем я всегда боролся в своем коде. Предположим, что мы имеем следующий код:

public class MyClass {
    private string _myVariable;

    public string MyVariable {
        get { return _myVariable; }
        set { _myVariable = value; }
    }

    public void MyMethod() {
        string usingPrivateMember = _myVariable; // method A
        string usingPublicProperty = MyVariable; // method B
    }
}

Какой путь является более правильным - метод A или B? Я всегда разорван об этом. Метод A кажется, что это было бы намного быстрее, из-за того, что ему не нужно было перейти к собственности до получения реальной переменной. Тем не менее, метод B более безопасен, потому что если getter для MyVariable добавляет к нему бизнес-логику, вы можете быть уверены, всегда звоните, даже если нет текущей бизнес-логики.

Каков общий консенсус?

Ответ 1

Используйте это свойство.

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

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

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

Ответ 2

Это будет действительно зависеть от того, к чему вы обращаетесь к свойству. Рассмотрим следующие два сценария:

Сценарий 1: вы пишете метод для обеспечения общего действия с данными в классе:

// assume a hypothetical class Position

public class Circle
{
    private int _radius;
    private int _xpos;
    private int _ypos;

    public int Radius { get { return _radius; } }
    public Position Center { get { return new Position(_xpos, _ypos); } }

    public bool PointInCircle(Position other)
    {
         return distance(this.Center, other) < this.Radius;
    }
}

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

Сценарий 2: вы пишете метод манипулирования базовыми данными. Хорошим примером этого является сериализация. Вы хотели бы сериализовать базовые элементы данных в отличие от значений, возвращаемых объектами доступа свойств.

Ответ 3

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

private int timeSinceLastPropertyAccess;

public int TimeSinceLastPropertyAccess
{
   get 
   { 
      // Reset timeSinceLastPropertyAccess to 0
      int a = timeSinceLastPropertyAccess; 
      timeSinceLastPropertyAccess = 0; 
      return a; 
   }
}

Вы хотите, чтобы timeSinceLastPropertyAccess был reset, когда он используется внутри вашего класса или нет?

Ответ 4

Чтобы добавить еще одну вещь, ваш пример спросил только о геттерах. Другая половина этого - сеттеры.

Иногда вам нужно, чтобы объект использовал сеттеры, а иногда вы хотите, чтобы он обошел их и просто назначил основное поле.

Например, скажем, у вас есть свойство, называемое IsModified. Что скажет вам всякий раз, когда объект был изменен. Вы могли бы, чтобы все ваши сеттеры перевернули это значение true в случае, если другое значение присвоено одному из следующих полей.

Теперь, если вы увлажняете этот объект (либо загружаете из базы данных, либо в другое место), вам не нужно будет устанавливать IsModified. Потому что, честно говоря, он еще не изменен. Таким образом, в этом методе вы используете имена базового поля, но во всех других методах вы используете свойство setter.

Ответ 5

это зависит, хотите ли вы сделать то, что делает свойство? частный/общественный не имеет никакого значения, это как вызов функции.

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

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

Дело в том, что, если ВСЕ, что доступ к этой переменной - даже функции частного класса - делает это через свойство, которое просто проходит через переменную, зачем вообще иметь свойство? почему бы просто не создать переменную, называемую "MyVariable", тогда, если вы обнаружите, что хотите что-то сделать, когда ее изменили/получили доступ, просто создайте другую переменную с именем _MyVariable или что-то еще, а затем измените MyVariable, чтобы потом было свойство для _MyVariable.

вы должны думать о свойствах как о том, как функции accessor() и mutator(), которые вы использовали для записи, трюк с ними был, если вы обнаружили, что вы хотите сделать некоторый код всякий раз, когда переменная была "доступна", вам пришлось изменить ВСЕ вызовы на эту переменную, чтобы вместо этого использовать аксессуар (вызов функции, а не просто доступ к переменной-члену), поэтому на всякий случай вы бы создали аксессоры и матадоры по умолчанию. Как я уже говорил выше, у вас нет этой проблемы с С# и свойствами (за исключением одного хромого случая, когда вы не можете писать суб-членам члена, если его свойство... ПОЧЕМУ?)