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

StackOverflow https://stackoverflow.com/questions/9304

  •  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"; }

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

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

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

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

Как вы сказали, вы могли бы использовать поля, и если бы вы хотели добавить к ним логику позже, вы бы преобразовали их в свойства.Но это может создать проблемы при любом использовании 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, сгенерированный компилятором, тот же самый.Я согласен с тем, что нужно избегать черной магии, но все равно, меньшее количество строк для одного и того же обычно полезно.

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

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

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

Сделай это:

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

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

Однако когда-нибудь ваша система вырастет, и вы разделите ее на отдельные сборки и множество решений.Когда это произойдет, любые открытые поля вернутся, чтобы преследовать вас, потому что, как упоминал Джефф, изменение общедоступного поля на общедоступное свойство является критическим изменением 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, так это Автоматическое изменение свойства рефакторинг.

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top