С# 3.0 авто-свойства - полезно или нет?

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

Я использую для создания своих свойств в С# с помощью частного и публичного поля:

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

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

public string Title { get; set; }

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

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

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

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

Ответ 2

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

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

public string PropertyName { get; private set; }

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

С С# 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"; }

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

Ответ 3

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

  • Вы не можете привязать данные к полю, в то время как вы можете использовать свойство
  • Если вы начинаете использовать поле, вы не можете (легко) изменить его на свойство
  • Есть некоторые атрибуты, которые вы можете добавить к свойству, которое вы не можете добавить в поле

Ответ 4

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

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

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

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

Ответ 5

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

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

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

Ответ 6

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

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

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

Таким образом, это имеет преимущества перед простой автопроцессором get/private set.

Ответ 7

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

Ответ 8

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

Ответ 9

Я использую авто-свойства все время. До С# 3 меня не беспокоили все типизирующие и только используемые общедоступные переменные.

Единственное, что я пропустил, это сделать:

public string Name = "DefaultName";

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

Ответ 10

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

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

Ruby имел это все время как:

attr_accessor :my_property
attr_reader :my_getter
attr_writer :my_setter

Ответ 11

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

Ответ 12

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

Проще всего.

Ответ 13

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

Ответ 14

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

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

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

Сделайте это:

  • переименуйте поле
  • сделать его закрытым.
  • добавить публичное свойство

Код клиента не потребуется изменять.

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

Ответ 15

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

Для этого:

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

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

Ответ 16

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

Ответ 17

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

public string Title { get; }

или

public string Title { get; private set; }

Это то, о чем вы говорите?

Ответ 18

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

Отсутствие VS2008 - это рефакторинг Explode Auto-Property.

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