Авто-свойства C # 3.0 - полезно или нет? [закрыто]

Примечание: это было опубликовано, когда я начинал C #. Обладая знаниями 2014 года, я могу с уверенностью сказать, что авто-свойства являются одними из лучших вещей, которые когда-либо случались с языком C #.

Я привык создавать свои свойства в C #, используя закрытое и открытое поле:

private string title;
public string Title
{
    get { return title;  }
    set { title = value;  }
}

Теперь, с .NET 3.0, мы получили авто-свойства:

public string Title { get; set; }

Я знаю, что это скорее философский / субъективный вопрос, но есть ли какая-либо причина использовать эти авто-свойства, кроме сохранения пяти строк кода для каждого поля? Моя личная неприятность в том, что эти свойства скрывают от меня вещи, и я не большой поклонник черной магии.

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

Я вижу преимущество в том, что я сохраняю много кода (одна против шести строк), не теряя возможности изменить логику получения / установки позже, но с другой стороны, я уже могу это сделать, просто объявив открытое поле «Public string Title» без необходимость {получить; установлен; } блок, таким образом, даже сохраняя больше кода.

Итак, что мне здесь не хватает? Почему кто-то на самом деле хочет использовать авто-свойства?

12.08.2008 23:06:58
«Моя личная неприятность в том, что эти свойства скрывают вещи от меня, и я не большой поклонник черной магии». А? Вы знаете, что компилятор все время скрывает от вас тонну, верно? Если вы не пишете ассемблер (или, точнее, фактические 1 и 0 для вашего кода), ВСЕ, что вы пишете, скрывает от вас вещи.
Charles Boyung 10.06.2010 15:37:53
18 ОТВЕТОВ
РЕШЕНИЕ

Мы используем их все время в переполнении стека.

Вы также можете быть заинтересованы в обсуждении свойств и общедоступных переменных . ИМХО, это действительно то, на что это реакция, и для этой цели это здорово.

117
7.04.2014 18:32:29

Я лично люблю авто-свойства. Что не так с сохранением строк кода? Если вы хотите что-то делать в методах получения или установки, в дальнейшем нет проблем преобразовать их в обычные свойства.

Как вы сказали, вы можете использовать поля, и если вы захотите добавить логику к ним позже, вы конвертируете их в свойства. Но это может создать проблемы с любым использованием отражения (и, возможно, в другом месте?).

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

Я думаю, это то же самое, что и ключевое слово var. Вопрос личных предпочтений.

29
12.12.2018 08:34:10

Три больших недостатка использования полей вместо свойств:

  1. Вы не можете привязать данные к полю, тогда как вы можете к свойству
  2. Если вы начинаете использовать поле, вы не можете позже (легко) изменить его на свойство
  3. Есть некоторые атрибуты, которые вы можете добавить в свойство, которое нельзя добавить в поле
45
20.01.2010 09:16:21
«Если вы начинаете использовать поле, вы не можете позже (легко) изменить его на свойство», извините, но почему?
Homam 11.10.2010 13:26:53
@Homam В основном, любой потребительский код, который использует отражение в ваших полях, сломается, поскольку им придется переключиться с использования FieldInfo на PropertyInfo.
WCWedin 21.10.2010 16:10:52
@Homam Кроме того, изменение поля на свойство нарушает двоичную совместимость, требуя перекомпиляции всех потребителей поля.
Odrade 20.01.2011 18:20:27
Помимо проблем с перекомпиляцией и отражением, очень легко инкапсулировать поля с помощью Visual Studio: Ctrl-R + E позволит вам превратить поле в свойство с соответствующими методами получения / установки. (или щелкните правой кнопкой мыши поле, измените коэффициент, инкапсулируйте поле).
JoeBrockhaus 7.11.2012 18:30:37
Поля @Hommam являются lvalues ​​(они переменные), а свойства - нет. Материал, который мог скомпилироваться, когда это было поле, может не скомпилироваться, когда это свойство.
Mark 26.05.2015 21:07:51

Я использую авто-свойства все время. До C # 3 я не мог возиться со всей типизацией и просто использовал открытые переменные.

Единственное, чего мне не хватает, так это возможности сделать это:

public string Name = "DefaultName";

Вы должны перенести значения по умолчанию в ваши конструкторы со свойствами. нудный :-(

5
12.08.2008 23:22:07
С помощью инициализаторов Auto-property из C # 6 вы скоро сможете это сделать: public string Name { get; set; } = "DefaultName"; blogs.msdn.com/b/csharpfaq/archive/2014/11/20/…
Carlos Muñoz 26.03.2015 17:01:38

Я думаю, что любая конструкция, которая интуитивно понятна и сокращает количество строк кода, является большим плюсом.

Именно такие особенности делают такие языки, как Ruby, такими мощными (это и динамические функции, которые также помогают уменьшить избыточный код).

У Руби все это время было:

attr_accessor :my_property
attr_reader :my_getter
attr_writer :my_setter
5
13.08.2008 00:14:48

Единственная проблема, которую я имею с ними, состоит в том, что они не зашли достаточно далеко. В том же выпуске компилятора, в котором добавлены автоматические свойства, добавлены частичные методы. Почему они не соединили их, мне не под силу. Простое «частичное On <PropertyName> Changed» сделало бы эти вещи действительно очень полезными.

2
13.08.2008 01:36:03
Вы можете поместить несколько частичных методов в другой метод. Создание какого-либо автоматического шаблона для них было бы непонятным.
Matthew Whited 12.09.2010 12:23:53

Да, он просто сохраняет код. Это намного легче читать, когда у вас их много. Их быстрее написать и легче поддерживать. Сохранение кода всегда хорошая цель.

Вы можете установить разные области:

public string PropertyName { get; private set; }

Так что свойство может быть изменено только внутри класса. Это не является неизменным, так как вы все еще можете получить доступ к приватному сеттеру через рефлексию.

Начиная с C # 6 вы также можете создавать истинные readonlyсвойства - то есть неизменяемые свойства, которые нельзя изменить вне конструктора:

public string PropertyName { get; }

public MyClass() { this.PropertyName = "whatever"; }

Во время компиляции это станет:

readonly string pName;
public string PropertyName { get { return this.pName; } }

public MyClass() { this.pName = "whatever"; }

В неизменяемых классах с большим количеством членов это экономит много лишнего кода.

61
7.10.2015 08:17:29
«Таким образом, вы не теряете никакой функциональности». как вы их отлаживаете?
wal 25.10.2010 03:43:47
@wal - что там для отладки? С этой точки зрения вы в основном имеете дело с переменными-членами.
Keith 26.10.2010 11:17:26
@wal - Вы можете поставить на них точку останова, точно так же, как вы можете получить доступ к переменной-члену, вы просто не можете войти в них. Но почему вы хотите? То, что на самом деле делают авто-свойства, является тривиальным и автоматически генерируемым, если у вас есть ошибки, это одно из мест, где они крайне маловероятны.
Keith 27.10.2010 14:45:19
нам может понадобиться вынести это за пределы Кита. :)
wal 28.10.2010 13:10:42
Но хорошо, предположим, у вас есть много вызовов setter для myObj.Title ... вы хотите увидеть, где значение меняется с «text» на null, то есть на условную точку останова. как ты этого добиваешься? Вы даже не можете установить точку останова на сеттере
wal 28.10.2010 13:12:45

Здесь следует отметить, что, насколько я понимаю, это всего лишь синтаксический сахар на стороне C # 3.0, означающий, что IL, сгенерированный компилятором, одинаков. Я согласен избегать черной магии, но, тем не менее, меньшее количество строк для одной и той же вещи, как правило, хорошо.

1
17.08.2008 22:40:15

На мой взгляд, вы всегда должны использовать авто-свойства вместо открытых полей. Тем не менее, вот компромисс:

Начните с внутреннего поля, используя соглашение об именах, которое вы бы использовали для свойства. Когда вы первый

  • нужен доступ к полю снаружи его сборки, или
  • необходимо прикрепить логику к получателю / установщику

Сделай это:

  1. переименовать поле
  2. сделать это частным
  3. добавить публичную собственность

Ваш код клиента не нужно будет менять.

Однако когда-нибудь ваша система вырастет, и вы разложите ее на отдельные сборки и несколько решений. Когда это произойдет, любые открытые поля снова будут преследовать вас, потому что, как упоминал Джефф, изменение открытого поля на публичное свойство является критическим изменением API .

1
17.08.2008 23:19:30

Авто-свойства - такая же черная магия, как и все остальное в C #. Когда вы думаете об этом с точки зрения компиляции в IL, а не вначале для расширения до обычного свойства C #, это становится намного менее черной магией, чем многие другие языковые конструкции.

8
18.08.2008 00:27:08

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

Сделать это:

 private string title;
public string Title
{
    get { return title;  }
    set { title = value;  }
}

Требуется всего восемь нажатий клавиш.

0
21.08.2008 11:13:54
Если я удерживаю клавиши CTRL и V, я могу вставить очень много вещей / очень быстро /, но это не делает его 'лучше'. Как это отвечает на оригинальный вопрос?
JBRWilkinson 18.02.2010 14:59:07

Ну, с фрагментами кода авто-свойство с тем же именем будет в общей сложности семь нажатий клавиш;)

0
26.08.2008 09:01:06

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

private readonly string title;
public string Title
{
    get { return this.title; }
}

(где поле инициализируется в конструкторе с помощью переданного параметра, а затем доступно только для чтения.)

Так что это имеет преимущества перед простым get/ private setautoproperty.

18
27.08.2008 18:04:14
Если у вас есть структура, изменение какого-либо свойства приводит к новой структуре. Это было бы проблемой только в том случае, если вам нужен внутренне неизменяемый ссылочный тип - я не вижу причины, по которой он вам понадобится.
Keith 13.02.2009 12:55:57
@Keith: Ваше первое предложение кажется фактически неверным.
Domenic 18.02.2009 21:27:49
Не public string Title { get; private set; }приведет ли это к тому же результату? Конечно, вы сможете изменить его из класса, но если вы сделаете это, у вас возникнут другие проблемы ...: p
Svish 31.08.2009 08:14:46
@Svish - по этому аргументу никогда не следует использовать ключевое слово readonly в C #, потому что его использование означало бы, что мы скрываем эти «разные проблемы»
Zaid Masud 12.09.2011 15:55:53
Я просто имею в виду, что с точки зрения внешнего API это не будет иметь большого значения. И так, авто-свойства могут быть использованы при желании. Лучше всего было бы, конечно, если бы вы могли сделать что-то вродеpublic string Title { get; private readonly set; }
Svish 13.09.2011 11:01:38

@ Domenic: я не понимаю .. ты не можешь сделать это с авто-свойствами ?:

public string Title { get; }

или

public string Title { get; private set; }

Это то, что вы имеете в виду?

0
30.08.2008 11:59:37
Вы можете (последнее; первое не будет компилироваться), но тогда поле не является неизменным внутри вашего объекта.
Domenic 19.09.2008 22:21:29
Слово предостережения, только структуры являются неизменными, когда помечены только для чтения, классы просто не назначаются.
Guvante 8.10.2008 11:21:22

Это просто, это коротко, и если вы хотите создать реальную реализацию внутри тела свойства где-то вниз по линии, это не нарушит внешний интерфейс вашего типа.

Так просто, как, что.

2
7.09.2008 08:06:44

От Бьярне Страуструпа, создателя C ++:

Мне особенно не нравятся классы с большим количеством функций get и set. Это часто указывает на то, что это не должен был быть класс в первую очередь. Это просто структура данных. И если это действительно структура данных, сделайте ее структурой данных.

И знаешь, что? Он прав. Как часто вы просто оборачиваете приватные поля в get и set, фактически ничего не делая внутри get / set, просто потому, что это «объектно-ориентированная» вещь, которую нужно сделать. Это решение Microsoft от проблемы; это в основном публичные поля, которые вы можете связать.

29
12.12.2018 08:35:03
Я действительно думаю, что это должно иметь больше очков. Слишком много людей видят свойства auto как зеленый свет для написания ужасно инкапсулированных (или вовсе не инкапсулированных) классов, которые представляют собой нечто большее, чем прославленное публичное поле. Конечно, это больше связано с тем, как люди используют инструмент, а не с самим инструментом, но я думаю, что важно упомянуть при обсуждении свойств в целом.
sara 3.09.2015 14:56:37

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

Чего не хватает VS2008, так это рефактора взрыва Auto-Property .

Тот факт, что у нас есть рефакторинг инкапсулированных полей, позволяет мне быстрее использовать открытые поля.

0
5.12.2008 10:24:51

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

12
5.12.2008 10:59:42