Автоматические свойства C # 3.0 — полезны или нет?[закрыто]
-
08-06-2019 - |
Вопрос
Примечание:Это было опубликовано, когда я только начинал изучать 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 ничего не делают.Но когда я хочу на самом деле реализовать какую-то логику получения / установки, мне все равно приходится использовать пару private / public.
Я вижу преимущество в том, что я экономлю много кода (одну против шести строк), не теряя возможности изменить логику получения / установки позже, но опять же, я уже могу это сделать, просто объявив общедоступное поле "Public string Title" без необходимости { get;установленный;} блокировать, тем самым даже экономя больше кода.
Итак, чего же мне здесь не хватает?Зачем кому-то на самом деле хотеть использовать автоматические свойства?
Решение
Мы постоянно используем их при переполнении стека.
Вам также может быть интересно обсудить Свойства противОбщедоступные переменные.ИМХО, это действительно то, на что это реакция, и для этой цели это здорово.
Другие советы
Да, это так просто сохраните код.Читать намного легче, когда у вас их много.Они быстрее пишутся и их проще поддерживать.Сохранение кода - это всегда хорошая цель.
Вы можете установить различные области действия:
public string PropertyName { get; private set; }
Так что свойство может быть изменено только внутри класса.На самом деле это не является неизменяемым, поскольку вы все еще можете получить доступ к частному установщику через отражение.
Начиная с C # 6, вы также можете создать true 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"; }
В неизменяемых классах с большим количеством членов это экономит много лишнего кода.
Тремя большими недостатками использования полей вместо свойств являются:
- Вы не можете привязать данные к полю, тогда как вы можете привязать к свойству
- Если вы начнете использовать поле, позже вы не сможете (легко) изменить его на свойство
- Есть некоторые атрибуты, которые вы можете добавить к свойству, но которые вы не можете добавить к полю
Лично мне нравятся автоматические свойства.Что плохого в сохранении строк кода?Если вы хотите что-то делать в геттерах или установщиках, позже нет проблем преобразовать их в обычные свойства.
Как вы сказали, вы могли бы использовать поля, и если бы вы хотели добавить к ним логику позже, вы бы преобразовали их в свойства.Но это может создать проблемы при любом использовании reflection (и, возможно, в других местах?).
Также свойства позволяют вам устанавливать разные уровни доступа для средства получения и установки, чего вы не можете сделать с полем.
Я предполагаю, что это то же самое, что и ключевое слово var.Это вопрос личных предпочтений.
От Бьярне Страуструпа, создателя C++:
Мне особенно не нравятся классы с большим количеством функций get и set.Это часто указывает на то, что это вообще не должно было быть классом.Это всего лишь структура данных.И если это действительно структура данных, сделайте ее структурой данных.
И знаешь что?Он прав.Как часто вы просто оборачиваете частные поля в get и set, фактически ничего не делая внутри get / set, просто потому, что это "объектно-ориентированная" вещь.Это решение Microsoft для этой проблемы;по сути, это общедоступные поля, к которым вы можете привязываться.
Одна вещь, о которой, похоже, никто не упоминал, - это то, что автоматические свойства, к сожалению, бесполезны для неизменяемых объектов (обычно неизменяемых структур).Потому что для этого вам действительно следует сделать:
private readonly string title;
public string Title
{
get { return this.title; }
}
(где поле инициализируется в конструкторе с помощью переданного параметра, а затем доступно только для чтения.)
Так что у этого есть преимущества перед простым get
/private set
собственность на авто.
Я всегда создаю свойства вместо общедоступных полей, потому что вы можете использовать свойства в определении интерфейса, вы не можете использовать общедоступные поля в определении интерфейса.
Автоматические свойства - это такая же черная магия, как и все остальное в C #.Как только вы подумаете об этом с точки зрения компиляции вплоть до IL, а не расширения до обычного свойства C #, это будет намного меньше черной магии, чем во многих других языковых конструкциях.
Я постоянно пользуюсь автоматическими свойствами.До C # 3 я не мог заморачиваться со всем набором текста и просто использовал вместо этого открытые переменные.
Единственное, чего мне не хватает, так это возможности сделать это:
public string Name = "DefaultName";
Вы должны перенести значения по умолчанию в свои конструкторы со свойствами.утомительно :-(
Я думаю, что любая конструкция, которая интуитивно понятна И сокращает количество строк кода, является большим плюсом.
Такого рода функции - это то, что делает такие языки, как Ruby, такими мощными (это и динамические функции, которые также помогают сократить избыточный код).
У Руби это было с самого начала, как:
attr_accessor :my_property
attr_reader :my_getter
attr_writer :my_setter
Единственная проблема, с которой я сталкиваюсь, заключается в том, что они заходят недостаточно далеко.В том же выпуске компилятора, который добавил автоматические свойства, были добавлены частичные методы.Почему они не соединили эти два понятия вместе, выше моего понимания.Простое "частичное включение<PropertyName>Изменено" сделало бы эти вещи действительно полезными.
Это просто, коротко, и если вы хотите создать реальную реализацию внутри тела свойства где-нибудь в дальнейшем, это не нарушит внешний интерфейс вашего типа.
Вот так просто.
Здесь следует отметить одну вещь: насколько я понимаю, это просто синтаксический сахар на конце C # 3.0, означающий, что IL, сгенерированный компилятором, тот же самый.Я согласен с тем, что нужно избегать черной магии, но все равно, меньшее количество строк для одного и того же обычно полезно.
На мой взгляд, вы всегда должны использовать автоматические свойства вместо общедоступных полей.Тем не менее, вот компромисс:
Начните с внутренний поле, использующее соглашение об именовании, которое вы бы использовали для свойства.Когда вы впервые либо
- необходим доступ к полю извне его сборки, или
- нужно прикрепить логику к получателю / установщику
Сделай это:
- переименуйте поле
- сделайте это приватным
- добавить общедоступное свойство
Ваш клиентский код не нужно будет менять.
Однако когда-нибудь ваша система вырастет, и вы разделите ее на отдельные сборки и множество решений.Когда это произойдет, любые открытые поля вернутся, чтобы преследовать вас, потому что, как упоминал Джефф, изменение общедоступного поля на общедоступное свойство является критическим изменением API.
Я использую CodeRush, это быстрее, чем авто-свойства.
Чтобы сделать это:
private string title;
public string Title
{
get { return title; }
set { title = value; }
}
Всего требуется восемь нажатий клавиш.
Ну, с фрагментами кода автоматическое свойство с тем же именем будет состоять всего из семи нажатий клавиш ;)
@Доминик :Я этого не понимаю..разве вы не можете сделать это с помощью автоматических свойств?:
public string Title { get; }
или
public string Title { get; private set; }
Это то, что вы имеете в виду?
Моя самая большая проблема с автоматическими свойствами заключается в том, что они предназначены для экономии времени, но я часто обнаруживаю, что позже мне приходится расширять их до полноценных свойств.
Чего не хватает VS2008, так это Автоматическое изменение свойства рефакторинг.
Тот факт, что у нас есть инкапсулировать поле рефакторинг ускоряет мою работу, позволяя просто использовать общедоступные поля.