Конструкторы c # против авто-свойств и инициализаторов объектов - PullRequest
8 голосов
/ 04 сентября 2010

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

Я считаю, что это делает мои классы более надежными и изящными с точки зрения ОО, и я бью себя за то, что не делал этого раньше.

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

Ответы [ 3 ]

13 голосов
/ 04 сентября 2010

Из разговоров я полагаю, что команда C # понимает, что они упростили написание изменяемых типов, не предоставляя аналогичных преимуществ для неизменяемых типов.Дело не в том, что с течением времени они усложнили неизменность - они просто не сделали это легче ... за исключением анонимных типов, которые являются неизменяемыми, но имеют ряд других недостатков.Я, конечно, не хотел бы, чтобы автоматические свойства были убраны - там, где они уместны, они действительно полезны.Я просто хотел бы иметь эквивалент для свойств только для чтения (позволяя устанавливать их только в конструкторе).

Я обнаружил, что именованные аргументы и необязательные параметры C # 4 облегчают создание неизменяемого типахотя случаи - вы все еще можете получить много преимуществ инициализаторов объектов, без недостатков изменчивости.Просто предоставьте значения по умолчанию для аспектов вашего типа, которые действительно являются необязательными, оставьте остальные как обязательные параметры конструктора, и вызывающая сторона может делать то, что они хотят - используя именованные аргументы для большей ясности.

Инициализаторы коллекций - более сложный вопросвзломать, к сожалению.Я хотел бы видеть «цепочечные» инициализаторы, которые могли бы работать с неизменяемыми коллекциями, чтобы вместо многократного вызова Add в одном и том же экземпляре, компилятор мог создавать вызовы Plus, которые объединялись в цепочку:

ImmutableList<string> x = new ImmutableList<string> { "a", "b", "c" };

будет идти по адресу:

ImmutableList<string> x = new ImmutableList<string>().Plus("a")
                                                     .Plus("b")
                                                     .Plus"(c");

Конечно, было бы неплохо иметь больше неизменяемых коллекций в рамках для начала:)

Ничто из этого не помогает в автореквизит, конечно.Я должен признать, что недавно я обманул определенную сумму, притворяясь неизменным, используя частные сеттеры:

public string Name { get; private set; }

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

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

Вы можете найти видео с NDC 2010 интересными - есть отличная дискуссия с Эриком Липпертом, Мэдс Торгерсен, Нил Гафтер (и я), и мои предложения по C # 5 в другом видео.

1 голос
/ 26 июля 2012

Я удаляю все сеттеры и добавляю обратно только если свойство явно нуждается в сеттере. Я считаю, что это делает мои уроки более надежными и элегантными. OO

Я полностью согласен с вами. Я столкнулся с устаревшим кодом, где для некоторой иерархии классов используется множество инициализаторов объектов. Мне нужно было добавить некоторые свойства, и тогда у меня возникла головная боль с поиском всех мест, где создаются экземпляры классов. Первый раз я представился. И теперь мне нужно добавить еще одно свойство. Это безумие!

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

0 голосов
/ 04 сентября 2010

Я считаю, что конструкторы очень редко используются в примерах кода на c #, и я думаю, что авто-свойства и инициализатор объекта являются большой частью этого

Если у вашего объекта много свойств, вы явно не хотите инициализировать их все из конструктора. Необходимость передавать больше, чем, скажем, 4 или 5 параметров довольно плохо для удобства чтения (даже если Intellisense позволяет легко писать). Кроме того, если вы хотите инициализировать только несколько свойств и использовать значение по умолчанию для других свойств, вам либо понадобится много перегрузок конструктора, либо вам придется явно передавать эти значения по умолчанию конструктору.

В таких случаях инициализаторы объектов очень удобны, если свойства не только для чтения (но, как указал Джон, хорошие параметры в C # 4 - хорошая альтернатива)

почему команда c # продвигает такие функции, а не фокусируется на предоставлении функций, продвигая лучшие практики

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

...