Udostępnij za pośrednictwem


Почему нет свойств расширения?

Меня часто спрашивают «парни, вы добавили методы расширения в C# 3, так почему бы не добавить ещё и свойства расширения?»

Хороший вопрос.

Давайте, сначала я чуть поговорю о C# 3.0. Явно главной новостью в C# 3 был LINQ. В некотором смысле, у нас было всего три новых возможности в C# 3:

  • всё необходимое для LINQ – неявно типизированные переменные, анонимные типы, лямбда-выражения, методы расширения, инициализаторы объектов и коллекций, конструкторы запросов, деревья выражений, улучшенный вывод типов
  • частичные методы
  • автоматически реализуемые свойства

Последние два были крошечными по сравнению с пунктами из первой пачки. С точки зрения проектирования, синтаксис и семантика обеих возможностей прямолинейны. С точки зрения реализации, у нас уже были механизмы для устранения вызовов; частичные методы и условные методы – почти одно и то же за кулисами. Авто-свойства также были весьма прямолинейны в анализе и генерации кода. Нагрузка по тестировнию тоже была для них не особенно большой.

Команда C# была «длинным шестом» в 2008 релизе Visual Studio и .NET Framework. Под этим я имею в виду то, что если бы вы взяли количество времени, нужно для выполнения работы, на которую подписалась каждая команда, с учётом численности персонала, всё такое, и сделали шесты пропорциональной этому длины для каждой команды в Developer Division, то шест C# оказался бы самым длинным. Что означает, что у любой другой команды в DevDiv был запас в расписании, но если бы мы отстали на день от своего расписания, то новая студия и CLR тоже были бы выпущены на день позже. Если бы любая другая команда отстала на день, ну, до тех пор, пока это не делало их шест длиннее нашего, у них всё ещё было бы всё в порядке. Внутри нашей команды, при разделе работы между разными её участниками, «длинным шестом» были задачи привязывания лямбд и вывода типов методов, отданные мне. Так что, в некотором смысле, каждый день моего опоздания одначал запаздывание выхода продукта на столько же дней. (Никакого давления!)

К счастью, у нас тут превосходная команда, мы все очень хорошо помогали друг другу в течение этого релиза, подхватывая задачи друг друга при необходимости, и выполнили качественный релиз за долгое время. Моя мысль – в том, что если что-то не было либо необходимым для LINQ , либо маленьким, ортогональным, и легковыбрасываемым в случае необходимости (как остальные две), это выбрасывали немедленно. Ни в коем случае мы не собирались рисковать задержать выход всего продукта для какой-то штуки, которая была бы сразу и сложной и не необходимой. Конечно же, сразу было очевидно, что естественным спутником методов расширения являются свойства расширения. Менее очевидно, по какой-то причине, что события расширения, операторы расширения, конструкторы расширения (также известные, как «паттерн «фабрика»»), и так далее, тоже являются естественными спутниками. Но мы даже не рассматривали вопрос проектирования свойств расширения в C# 3; мы знали, что без них можно обойтись, и они добавят риск в и итак уже рискованное расписание, без привлекательного выигрыша.

Ну, теперь мы дошли до C# 4.

Как я люблю напоминать, ответ на все вопросы вида «почему в продукте X нет возможности Y?» один. Этопотому, что для того, чтобы в продукте была некоторая возможность, эта возможность должна быть

  • в первую очередь продумана
  • нужна
  • спроектирована
  • специфицирована
  • реализована
  • протестирована
  • задокументирована
  • доставлена потребителям

Мы должны пройти каждый из этих пунктов, иначе – никаких новшеств.

Когда мы начали работать над C# 4, мы составили список всех запросов, о которых мы только слышали. В нём были сотни возможностей. Как я описывал в прошлом году, мы рассортировали тот список по корзинкам «стоит сделать / неплохо бы / плохая идея». Свойства расширения были в корзинке «стоит сделать». Затем мы посмотрели на доступный нам бюджет – который измерялся не столько в долларах, сколько в доступных проектировщиках, разработчиках, тестерах, писателях, и менеджерах, умноженных на доступное время – и определили, что у нас хватит ресурсов на реализацию примерно половины вещей в корзинке «стоит сделать». Так что мы выбросили половину этого. Свойства расширения пережили это урезание. Затем мы спроектировали эту возможность. У нас были многочасовые споры о предполагаемом синтаксисе деклараций, способах «прямого» вызова методов чтения и записи как статических методов, и так далее. Мы придумали и согласовали приемлемый синтаксис, спроектировали семантику, написали черновик спецификации, и начали писать код и планы тестирования.

К моменту, когда код дошёл до приличного состояния – еще не до конца протестирован, но работает и соответствует спецификации – мы стали устраивать собрания с командой WPF. Разработчики WPF были предполагаемыми основными потребителями свойств расширения. В WPF уже есть механизм, похожий на свойства расширения; было бы неплохо унифицировать этот механизм с нашим. К сожалению, рассмотрев хорошенько их реальные сценарии, мы прили к разочаровывающему выводу о том, что мы спроектировали не то; эта возможность на самом деле не решала их проблемы. Это, надо признать, провал процесса проектирования. Мы должны были поинтересоваться мнением основного потребителя намного раньше. Сделай мы это – и они могли бы либо повлиять на дизайн и получить что-то, пригодное для них, или бы мы выбросили эту возможность из плана без затрат на написание спецификации, кода, и планов тестирования.

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

Так что, к сожалению, никаких свойств расширения в C# 4. Возможно, в гипотетической будущей версии C#.

Comments

  • Anonymous
    February 28, 2011
    А вопрос, где вообще собирают предложения для следующих версий языка? Просто иногда удивляет то, какой бред реализуется (типа того-же динамика). И то, что отсутствуют действительно полезные вещи, о отсутствии которых говорят многие программисты, работающие действительно с большими проектами. например нормальный const/mutable - что действительно улучшит безопасность кода, HashSet, NotNull и т.д. Ну а вообще, сшарп - очень красивая штука. спасибо вам за неё.