Должен ли я использовать общедоступные свойства и частные поля или публичные поля для данных?
В большей части кода, который я видел (на SO, thecodeproject.com и я, как правило, делаю это в своем собственном коде), я видел, что публичные свойства создаются для каждого отдельного частного поля, содержащегося в классе, даже если они являются наиболее основным типом get; set;
, например:
private int myInt;
public int MyInt
{
get { return myInt; }
set { myInt = value }
}
Мой вопрос: как это отличается от:
public int MyInt;
и если мы должны использовать свойства вместо публичных полей, почему мы должны использовать их в этом конкретном случае? (Я не говорю о более сложных примерах, где геттеры и сеттеры действительно делают что-то особенное или есть только один get или set (только чтение/запись), а не просто возврат/установка значения частного поля). Похоже, что он не добавляет дополнительной инкапсуляции, а только дает хороший значок в IntelliSense и помещается в специальный раздел в диаграммах классов!
Ответы
Ответ 1
См. статью http://blog.codinghorror.com/properties-vs-public-variables/
В частности
- Отражение работает по-разному по переменным и свойствам, поэтому, если вы полагаетесь на отражение, проще использовать все свойства.
- Вы не можете привязывать данные к переменной.
- Изменение переменной в свойство является нарушением изменения.
Ответ 2
Три причины:
- Вы не можете переопределять поля в подклассах, например свойства.
- В конечном итоге вам может понадобиться более сложный getter или setter, но если это поле, его изменение приведет к поломке API.
- Конвенция. Это так, как это было сделано.
Я уверен, что есть еще несколько причин, о которых я просто не думаю.
В .Net 3.x вы можете использовать автоматические свойства следующим образом:
public int Age { get; set; }
вместо старого школьного пути с объявлением ваших личных полей самостоятельно:
private int age;
public int Age
{
get { return age; }
set { age = value; }
}
Это делает его так же просто, как создание поля, но без проблем с изменением (среди прочего).
Ответ 3
При создании частного поля name и простого открытого свойства Имя, которое фактически получает и устанавливает значение поля имя
public string Name
{
get { return name; }
}
и вы используете это свойство везде вне вашего класса, и однажды вы решите, что свойство Имя этого класса будет действительно ссылаться на поле lastName (или что вы хотите для возврата строки "Мое имя:" + имя), вы просто меняете код внутри свойства:
public string Name
{
get { return lastName; //return "My name: "+name; }
}
Если вы использовали общедоступное поле имя везде во внешнем коде, вам придется изменить имя на lastName везде, где вы его использовали.
Ответ 4
Ну, это действительно имеет значение. Публичные данные могут быть изменены без знания экземпляра объекта. Используя геттеры и сеттеры, объект всегда осознает, что было сделано изменение.
Помните, что инкапсуляция данных - это только первый шаг к лучшему структурированному дизайну, это не конечная цель сама по себе.
Ответ 5
Вы должны использовать свойства в следующих случаях:
- Когда вам нужно сериализовать данные в свойстве в каком-то формате.
- Если вам нужно переопределить свойства в производном классе.
- Когда вы реализуете методы get и set с некоторой логикой. Например, когда вы реализуете шаблон Singleton.
- Когда вы выведены из интерфейса, где объявлено свойство.
- Если у вас есть конкретные проблемы, связанные с Reflection.
Ответ 6
Это... зависит?
Я всегда использую геттеры и сеттеры, так как они создали этот ярлык:
public int Foo {get; задавать; }
Во время компиляции оно переводится. Теперь вы не можете понять, что это такое, но оно есть, и если вам нужно получить фантазию, вы просто произнесите его позже.
Однако публичный, закрытый, защищенный... все зависит от того, кого вы хотите настроить данные. Мы используем наследование много, и это очень распространенный метод для нас, так что только chidren могут редактировать определенные свойства.
protected _foo;
public Foo
{
get { return _foo; }
} //lack of set intentional.
Ответ 7
Существует много причин.
В основном:
- Вы можете выполнять некоторые другие функции, когда переменная установлена
- Вы можете предотвратить настройку и предоставить только
- Некоторые "вещи" работают только на свойствах (например, DataBinding)
- Вы можете скрыть реализацию свойства [возможно, это переменная ViewState, в ASP.NET).
Ответ 8
Дело в том, что если дальше по строке вы хотите удостовериться, что каждый раз, когда myInt
ссылается, происходит что-то особенное (записывается файл журнала, он изменен на 42 и т.д.)? Вы не можете сделать это без геттеров и сеттеров. Иногда разумно программировать то, что вам может понадобиться, а не то, что вам нужно прямо сейчас.
Ответ 9
На самом деле, если вы используете Silverlight, вы поймете, что поля не могут быть установлены на статические ресурсы, и вам придется использовать свойство (даже для доступа к const
).
Я понял, что когда я пытался объединить имена регионов, которые я использую в Composite Guidance (PRISM).
Однако, что только языковые ограничения и кроме полей static
/const
, я всегда использую свойства.
Ответ 10
Идея заключается в том, что вы не должны случайно/непреднамеренно изменять значение закрытого поля класса снаружи.
Когда вы используете get и set, это означает, что вы изменяете секретное поле класса намеренно и сознательно.
Ответ 11
Установка значения в частное поле только изменяет это поле, но, делая их в свойстве, вы можете обрабатывать другие аргументы, например, вы можете вызвать метод после установки значения
private string _email;
public string Email
{
get
{
return this._email;
}
set
{
this._email = value;
ReplaceList(); //**
}
}
Ответ 12
Говоря проще, ответ на ваш вопрос - это модификаторы доступа, то есть публичные и частные.
Если вы используете:
public int myInt;
public int MyInt
{
get { return myInt; }
set { myInt = value }
}
то в проекте могут быть изменены как свойство MyInt, так и переменная myInt. Значит, если ваш класс предполагает, что A наследуется классом B, тогда myInt и MyInt доступны для модификации, и никакая проверка не может быть применена. Предположим, вы хотите, чтобы значение myInt можно было установить в классе вывода, если какое-то конкретное условие прошло.
Это может быть достигнуто только путем предоставления частным лицам и собственности публичным. Так что доступно только свойство, и на нем могут быть установлены условия.
Ответ 13
Я не могу поверить, что с 11 ответами никто не сказал этого:
Не все частные поля должны быть открыты как общедоступные. Вы должны обязательно использовать свойства для чего-то, что должно быть не-частным, но вы должны сохранить как можно больше своего класса.