Зачем использовать частные члены, затем использовать общедоступные свойства для их установки?
Посмотрите несколько примеров кода, где это происходит:
public class Foo
{
string[] m_workID;
public string[] WorkID
{
get
{
return m_workID;
}
private set
{
m_workID = value;
}
}
}
В чем смысл этого?
Поскольку использование m_workID не требуется.
Ответы
Ответ 1
В общем, дело в том, чтобы отделить реализацию (поле) от API (свойство).
Позже вы можете, если хотите, поместить логику, протоколирование и т.д. в свойство, не нарушая исходную или двоичную совместимость, - но что более важно, вы говорите, что ваш тип готов сделать, а не как это сделать он.
У меня статья, дающая больше преимуществ использования свойств вместо публичных полей.
В С# 3 вы можете сделать все это намного проще с автоматически реализованными свойствами:
public class Foo
{
public string[] WorkID { get; private set; }
}
В этот момент у вас все еще есть публичный геттер и частный сеттер, но поле поддержки (и реализация свойства) создается для вас за кулисами. В любой момент вы можете изменить это на "нормальное" полностью реализованное свойство с помощью поля поддержки, и вы по-прежнему будете иметь двоичную и исходную совместимость. (Совместимость сериализованных объектов - это другое дело, заметьте.)
Кроме того, в этом случае вы не можете отразить поведение, которое вы хотите (возможность читать значение публично, но пишите его конфиденциально) с помощью поля - вы могли бы иметь поле readonly, но тогда вы могли бы писать только ему конструктор. Лично мне жаль, что для этого не было подобного сокращения:
public class Foo
{
private readonly int id;
public int Id { get { return id; } }
...
}
поскольку мне нравятся неизменные типы, но это другое дело.
В другом другом случае вообще не рекомендуется выделять такие массивы, даже если вызывающие не могут изменить, к какому массиву WorkID
относится, они могут изменять содержимое массива, что, вероятно, не так вы хотите.
В приведенном вами примере вы можете уйти без средства настройки свойств, просто установив поле непосредственно в пределах одного класса, но это будет означать, что если вы когда-либо захотите добавить журнал и т.д., вам придется найти все эти пишет.
Ответ 2
Свойство само по себе не предоставляет места для размещения данных - для хранения требуется поле (m_workID
), но полностью верно, чтобы скрыть это свойство по многим причинам. В С# 3.0 вы можете уменьшить это:
public string[] WorkID {get; private set;}
Что будет делать почти то же самое. Обратите внимание, что разоблачение самого массива может быть проблематичным, так как нет механизма защиты данных в массиве - по крайней мере, с помощью IList<string>
вы могли (при необходимости) добавить дополнительный код для проверки здравого смысла или сделать его неизменным. Я не говорю, что это требует исправления, но это то, что нужно посмотреть.
Ответ 3
В дополнение к объектно-ориентированной философии инкапсуляции данных, это помогает, когда вам нужно что-то делать каждый раз, когда ваша собственность читается/записывается,
Вам может потребоваться выполнить журнал, проверку или любой другой вызов метода позже в вашей разработке.
Если ваше свойство является общедоступным, вам придется осмотреть весь свой код, чтобы найти и изменить свой код. А что, если ваш код используется как библиотека кем-то другим?
Если ваше свойство является приватным с соответствующими методами get/set, тогда вы меняете get/set и все.
Ответ 4
Вы можете использовать функцию автомасштабирования С# 3.0, чтобы сэкономить время:
public class Foo
{
public string[] WorkID
{
get; private set;
}
}
Кроме того, свойства дают вам много преимуществ по сравнению с полями:
-
свойства могут быть виртуальными
-
свойства скрывают детали реализации (не все свойства - просто тривиальные переменные аксессоры)
-
свойства могут содержать код проверки и регистрации и поднять события изменения
-
интерфейсы не могут содержать поля, но свойства
Ответ 5
Много раз вы только хотите предоставить доступ для чтения к полю. Используя свойство, вы можете предоставить этот доступ. Как вы упомянули, вы можете выполнять операции перед доступом к полю (ленивая загрузка, например). У вас много кода, который больше не нужен, если вы еще не работаете в .Net 2.0 -.