Ответ от Алекс Красс[гуру]
Одним из соглашений объектно-ориентированного программирования и разработки является инкапсуляция данных. Инкапсуляция данных означает, что поля типа НИ В КОЕМ СЛУЧАЕ не следует открывать для общего доступа, так как в этом случае слишком просто написать код, способный испортить сведения о состоянии объекта путем ненадлежащего применения полей. Банальный пример, поле возраста: people.age = -5 рушит всю логику. Особенно если вы работаете в команде или забыли за что это поле отвечает и задали неправильное значение. То есть соглашения устраняют потенциальные ошибки, которые вы можете совершить по неосторожности.
Есть и другие причины для инкапсуляции доступа к полям данных типа. Допустим, вам нужен доступ к полю, чтобы что-то сделать, разместить в кэше некоторое значение или создать какой-то внутренний объект, создание которого было отложено, причем обращение к полю не должно нарушать безопасность потоков. Или, скажем, поле является логическим и его значение представлено не байтами в памяти, а вычисляется по некоторому алгоритму.
Каждая из этих причин заставляет при разработке типов, во-первых, помечать абсолютно все поля как закрытые (private), во-вторых, давать пользователю вашего типа возможность получения и задания сведений о состоянии через специальные методы, предназначенные исключительно для этого. Методы, выполняющие функции оболочки для доступа к полю, обычно называют аксессорами (accessor). Аксессоры могут выполнять дополнительную зачистку, гарантируя, что сведения о состоянии объекта никогда не будут искажены.
private string _myString;
public string getMyString()
{
return _myString;
}
public void setMyString(string value)
{
_myString = value
}
Как видите, у инкапсуляции данных есть два недостатка: во-первых, из-за реализации дополнительных методов приходится писать более длинный код, во-вторых, вместо простой ссылки на имя поля пользователям типа приходится вызывать соответствующие методы. Но благодаря свойствам, этого можно избежать.
Поэтому код:
public string myString { get; set; }
Является заменой вот такого кода:
private string _myString;
public string myString
{
{ return _myString; }
{ _myString = value; }
}
Который на самом деле должен выглядеть как-то так без свойств:
private string _myString;
public string getMyString()
{
return _myString;
}
public void setMyString(string value)
{
_myString = value
}
И все потому, что бы не делать потенциальных ошибок и следовать ООП парадигме и ее правилам. Даже если вы считаете, что данные никак нельзя испортить, лучше иметь привычку делать все правильно. И согласитесь, писать одну строчку кода свойств взамен аксессоров в пять строк и их вывод, это очень разные вещи.
Ну и да, закрытое свойство при использовании свойств генерируется автоматически и его не обязательно объявлять.Алекс Красс
Просветленный
(39782)
Это подразумевается во втором абзаце ответа, но не акцентировано явно. Я предполагаю автора интересовало больше почему не используется прямое обращение к открытому полю вместо свойства, поэтому ответ по сути вопроса и дан. Текст взят из CLR via C# и немного подредактирован под требования.
Синтаксический сахар. Просто для сокращения количества кода.
Кста, хз как до них, но в интерфейсах так же можно указывать проперти.
public interface ITestInterface
{
string MyString { get; }
}
При имплементации в классе будет
public string MyString { get; private set; }
Теоретически, в таком "пустом" свойстве никакого смысла.
Практически - кое-какие библиотеки (например, использующие рефлексию - типа сериализаторов, или какие-нибудь привязки данных к GUI) могут работать только со свойствами или, наоборот, только с полями. Приходится извращаться.
например можно сделать так
public string myString
{
get { return _myString + "some text"; }
set { _myString = value; }
}