Я сейчас изучаю класс C # и пытаюсь найти лучший способ делать что-то. У меня есть опыт работы с Java, поэтому я знаком только с лучшими практиками Java; Я новичок в C #!
В Java, если у меня есть частная собственность, я делаю это;
private String name;
public void setName(String name) {
this.name = name;
}
public String getName() {
return this.name;
}
В C # я вижу, что есть много способов сделать это.
Я могу делать это как Java:
private string name;
public void setName(string name) {
this.name = name;
}
public string getName() {
return this.name;
}
Или я могу сделать это так:
private string name;
public string Name {
get { return name; }
set { name = value; }
}
Или:
public string Name { get; set; }
Какой из них мне следует использовать, и какие нюансы или тонкости связаны с каждым подходом? При создании классов я следую общим передовым методам, которые я знаю по Java (особенно читая «Эффективная Java»). Так, например, я выступаю за неизменность (предоставляю сеттеры только при необходимости). Мне просто любопытно посмотреть, как эти методы сочетаются с различными способами предоставления сеттеров и получателей в C #; по сути, как мне перевести лучшие практики из мира Java на C #?
РЕДАКТИРОВАТЬ
Я публиковал это как комментарий к ответу Джона Скита, но потом он стал длинным:
А как насчет нетривиального свойства (например, со значительной обработкой и проверкой)? Могу ли я раскрыть его через общедоступное свойство, но с логикой, заключенной в get
и set
? Зачем / должен я делать это, имея выделенные методы установки и получения (со связанной логикой обработки и проверки).
источник
public int Y { get; } = y;
).Если все, что вам нужно, это переменная для хранения некоторых данных:
public string Name { get; set; }
Хотите сделать его доступным только для чтения?
public string Name { get; private set; }
Или даже лучше ...
private readonly string _name; ... public string Name { get { return _name; } }
Хотите выполнить некоторую проверку значений перед назначением свойства?
public string Name { get { return m_name; } set { if (value == null) throw new ArgumentNullException("value"); m_name = value; } }
В общем, GetXyz () и SetXyz () используются только в определенных случаях, и вам просто нужно задействовать свою интуицию, когда вы считаете нужным. В общем, я бы сказал, что я ожидаю, что большинство свойств get / set не будут содержать много логики и будут иметь очень мало, если вообще будут, неожиданных побочных эффектов. Если для чтения значения свойства требуется вызов службы или получение ввода от пользователя для создания запрашиваемого объекта, я бы обернул его в метод и назвал бы как-то вроде
BuildXyz()
, а неGetXyz()
.источник
myList.Add()
, например (пока объект подвергается изменениям, он изменяемый).Min
/Max
значением. Вы хотите убедиться в этомMax > Min
? ИмеяSetRange(Min, Max)
может иметь смысл , но тогда , как вы будете читать эти значения обратно? Свойства Min / Max только для чтения? Выбрасывание исключений для недопустимого ввода кажется самым чистым способом справиться с этим.Используйте свойства в C #, а не методы получения / установки. Они созданы для вашего удобства, и это идиоматично.
Что касается ваших двух примеров C #, один - просто синтаксический сахар для другого. Используйте свойство auto, если все, что вам нужно, - это простая оболочка для переменной экземпляра, используйте полную версию, когда вам нужно добавить логику в геттер и / или сеттер.
источник
В C # предпочтение отдается свойствам для отображения закрытых полей для получения и / или установки. Упомянутая вами форма thie - это автосвойство, где операции get и set автоматически создают для вас скрытое поле поддержки сводной таблицы.
Я предпочитаю автоматические свойства, когда это возможно, но вы никогда не должны использовать пару методов set / get в C #.
источник
public string Name { get; set; }
Это просто автоматически реализуемое свойство , технически такое же, как обычное свойство. При компиляции будет создано резервное поле.
Все свойства в конечном итоге преобразуются в функции, поэтому фактическая скомпилированная реализация в конечном итоге такая же, как и в Java.
Используйте автоматически реализуемые свойства, когда вам не нужно выполнять определенные операции с резервным полем. В противном случае используйте обычное свойство. Используйте функции get и set, если операция имеет побочные эффекты или требует больших вычислительных ресурсов, в противном случае используйте свойства.
источник
Независимо от того, какой способ вы выберете в C #, конечный результат будет одинаковым. Вы получите переменную backinng с отдельными методами получения и установки. Используя свойства, вы следуете лучшим практикам, поэтому вопрос о том, насколько подробным вы хотите получить информацию.
Лично я бы выбрал автоматические свойства, последнюю версию :
public string Name { get; set; }
, поскольку они занимают меньше всего места. И вы всегда можете расширить их в будущем, если вам понадобится добавить что-то вроде проверки.источник
По возможности я предпочитаю общедоступные,
string Name { get; set; }
поскольку они краткие и легко читаемые. Однако бывают случаи, когда это необходимо.private string name; public string Name { get { return name; } set { name = value; } }
источник
В C # предпочтительный путь через свойства , а не
getX()
иsetX()
методы. Также обратите внимание, что C # не требует, чтобы свойства имели как получение, так и набор - вы можете иметь свойства только для получения и свойства только для набора.public boolean MyProperty { get { return something; } } public boolean MyProperty { set { this.something = value; } }
источник
Сначала позвольте мне объяснить, что вы написали:
// private member -- not a property private string name; /// public method -- not a property public void setName(string name) { this.name = name; } /// public method -- not a property public string getName() { return this.name; } // yes it is property structure before .Net 3.0 private string name; public string Name { get { return name; } set { name = value; } }
Эта структура также используется в настоящее время, но она наиболее подходит, если вы хотите выполнить некоторые дополнительные функции, например, когда значение установлено, вы можете его проанализировать, чтобы использовать его с заглавной буквы и сохранить его в закрытом члене для изменения внутреннего использования.
С .net framework 3.0
// this style is introduced, which is more common, and suppose to be best public string Name { get; set; } //You can more customize it public string Name { get; private set; // means value could be set internally, and accessed through out }
Желаю удачи в C #
источник
Как уже упоминалось, все эти подходы приводят к одинаковому результату. Самое важное - выбрать условность и придерживаться ее. Я предпочитаю использовать последние два примера свойств.
источник
как и большинство ответов здесь, используйте автоматические свойства. Интуитивно понятный, меньше строк кода и более чистый. Если вам следует сериализовать свой класс, отметьте класс
[Serializable]
/[DataConract]
атрибутом. И если вы используете,[DataContract]
отметьте член с помощью[DataMember(Name="aMoreFriendlyName")] public string Name { get; set; }
Частный или публичный сеттер зависит от ваших предпочтений.
Также обратите внимание, что для автоматических свойств требуются как геттеры, так и сеттеры (публичные или частные).
/*this is invalid*/ public string Name { get; /* setter omitted to prove the point*/ }
В качестве альтернативы, если вы хотите только получить / установить, создайте резервное поле самостоятельно
источник
При переходе со свойствами есть одно предостережение, которое еще не упоминалось: со свойствами вы не можете параметризовать свои геттеры или сеттеры.
Например, представьте, что вы хотите получить элементы списка и одновременно хотите применить фильтр. С помощью метода get вы можете написать что-то вроде:
obj.getItems(filter);
Напротив, со свойством вы вынуждены сначала вернуть все предметы
obj.items
а затем примените фильтр на следующем шаге, или вам нужно добавить специальные свойства, которые выставляют элементы, отфильтрованные по различным критериям, что вскоре раздувает ваш API:
obj.itemsFilteredByX obj.itemsFilteredByY
Что иногда может быть неприятно, так это когда вы начали со свойства, например,
obj.items
а затем позже обнаружили, что параметризация геттера или сеттера необходима или может упростить задачу для пользователя класса API. Теперь вам нужно будет либо переписать свой API и изменить все те места в коде, которые имеют доступ к этому свойству, либо найти альтернативное решение. Напротив, с помощью метода get, напримерobj.getItems()
, вы можете просто расширить подпись вашего метода, чтобы принять необязательный объект «конфигурации», например,obj.getItems(options)
без необходимости переписывать все те места, которые вызывают ваш метод.При этом (автоматически реализованные) свойства в C # по-прежнему являются очень полезными сокращениями (по различным причинам, упомянутым здесь), поскольку в большинстве случаев параметризация может не потребоваться, но это предостережение остается в силе.
источник