Комментарии 25
Довольно неоднозначные нововведения.
Частота применения field довольно странно описана. Все новые дата классы в wpf могут быть затронуты этой фичей. Тело свойства можно спокойно копировать, менять понадобится только название и тип. Ошибка записи в не то backing field уйдет полностью.
После появления required свойств можно ожидать появления PostInit конструктора. То есть сначала вызывается основной конструктор, далее инициализируются основные свойства и в конце происходит окончательная инициализация объекта, в которой используются эти свойства.
Частота применения, конечно, субъективна и зависит от сценариев. В WPF это действительно большая фича, но в вебе такое нужно крайне редко, а в Unity не берусь судить. При этом в WPF иногда делают нотификацию изменения объекта через аспекты и тогда field
не нужен. Ещё field
не очень хорошо сочетается с первичным конструктором, который будет создавать поля явно.
required
действительно выглядит как потенциальная смена парадигмы инициализации объектов, к которой нужно будет допиливать экосистему ещё. Потому что, например, record
выглядит прекрасной фичей, но с AutoMapper
сочетается довольно плохо. Если PostInit конструкторы хорошо встроятся в DI, первичные конструкторы и другие фичи с полями и свойствами, то это будет интересное изменение. Это будет довольно сложно успеть к C# 12, так что пока значимость фичи не так понятна.
И надо понимать, что половина написанного здесь может не доехать не только до C# 11, но и вообще до языка.
Это правда, хотя часть из описаных фич уже доставлена в C# 11 preview и много находятся в разработке или ревью уже сейчас. С большой вероятностью большая часть из описаного успеется к выходу C# 11 или по крайней мере не будут выброшены совсем.
Но при этом для некоторых фич всё ещё идут обсуждения дизайна и конечный вариант реализации может поменяться. Например, мне кажется, что params IEnumerable<T>
всё-таки не завезут из-за избыточности, а модификатор уровня доступа для области видимости в пределах файла вообще болтает — то ли он будет private, то ли всё-таки file, а ещё там в комментах сразу думают над модификатором уровня доступа в пределах неймспейса.
В той же папке с пропозалами есть не только те, что сейчас в работе, но и отложенные/ожидающие — у них вероятность доехать до будущих версий гораздо ниже, я даже примером readonly locals
в статью вынес, но ещё там есть в чём покопаться и о чём рассказать как о потенциальных направлениях развития языка.
Мне очень был нужен required , одобряю.
public required string FirstName { get; init; }
Но боюсь required и Первичные конструкторы для классов вызовут массу эксепшенов в обратной совместимости , особенно для тех кто использует nosql решения .
Если речь о новых мажорных версиях библиотеки (а делать такое изменение в рамках текущей мажорной версии немного странно) — то тут breaking changes могут служить усилением безопасности. Для первичных конструкторов с большой вероятностью типы и так были спроектированы для использования конструктора базового типа (как в DbContext
с options).
А вот обязательные члены меняют принцип инициализации объекта, ещё и требуют нужной области видимости, сейчас даже непонятно, как их хорошо встроить в контейнеры, чтобы те искали и инициализировали required
-члены так же из контейнера. Мне сейчас кажется, что required — это больше история про модели и их безопасное использование, так что любой breaking change будет подсвечивать существующую в коде проблему инициализации. И учитывая движение к неизменяемым объектам (с помощью того же init) код уже готов к этому, а init-only свойства достаточно безопасно помечать required.
Применимость: очень редко и иногда - некогда простой и элегантный язык превращается в лавку редкостей. Нет ощущения проработанности развития, вместо этого есть веник из нововведений вида "вроде всем полезно" и "а еще вот тут забыли".
Это "иногда" касается по большей части пользовательского кода — во внутренней реализации утилитарных библиотек это может использоваться довольно часто. Например, при работе с вебом utf8-литералы заменят большое количество конвертаций в рантайме, а изменения для generic math улучшат разработку новых типов, связанных с математикой.
Некоторые "иногда" значат, что прямо сейчас мало сценариев использования, но за счёт новых фич их может появиться больше. А другие "иногда" и "редко" — это про "очень часто в своей узкой нише", как полуавтоматические свойства для WPF.
При этом исходная простота языка не ломается — в пользовательском коде можно совсем не использовать эти фичи и не знать о них, зато при необходимости есть дополнительная гибкость.
Именно, что ломается - во-первых, раздувается формальный C# Language Specification и язык теряет обозримость. Во-вторых, язык распадается на куски нишевых применений. В-третьих, гибкость языка должна иметь логические пределы - ну нельзя притащить в язык всего хорошего понемножку отовсюду. Ну и к процессу вопросы - например, логично было бы, избавляясь от Main, сразу добавить специальные атрибуты. А про пользовательский код не понял - какой код имелся в виду?
С атрибутом для main — это скорее конфуз про "забыли частный случай, когда это нужно". Примерно такая же история, кстати, с переносом строк в выражениях интерполяции, они просто просматривались при парсинге выражения как часть строкового литерала, это скорее исправление недоработки, чем новая фича.
Под пользовательским кодом я имел в виду код конечного приложения, условная бизнес-логика как противопоставление инфраструктурному коду, где оптимизации уровня "делегат не кэшируется, поэтому перепишем менее кратко или менее понятно, зато быстрее" или "избавимся от замыкания" важны. Те же Span<T>
могут быть не так актуальны в каждом месте клиентского кода, а для поиска в словаре ключа, который является подстрокой полного имени машины, если это часть кода ServiceDiscovery и используется на каждом запросе — вполне.
Если те же params ReadOnlySpan<T>
помогут забустить логирование для случаев с string.Format
— отлично же будет. Надо смотреть бенчмарки будущих версий того же asp.net и других либ чтобы оценить значимость изменений.
Конечно, матричная математика и кровавый энтерпрайз хотят от языка разного. И я не говорю, что нововведения плохи сами по себе - совсем нет, но в целом от таких конфузов язык теряет стройность и внутреннюю согласованность. Кстати, почему-то C# Language Specification остановился где-то на C# 6 и дальше пошли только What's new - действительно единой спецификации последних версий C# не существует?
Да, всё так, что-то пошло не так и статус стандарта сейчас вот такой:
C# VERSION ECMA STANDARD ISO/IEC STANDARD
V1.0 ECMA-334:2003 ISO/IEC 23270:2003
V2.0 ECMA-334:2006 ISO/IEC 23270:2006
V3.0 none none
V4.0 none none
V5.0 ECMA-334:2017 ISO/IEC 23270:2018
V6.0 TBD TBD
V7.0 TBD TBD
Даже шестая версия считается черновиком.
А чего не хвататет для повседневной жизни?
Предлагаю использовать при инициализации ключевое слово "new":
public List<string> Names { get; new; }
Заменяет Names = new List<string>(); в конструкторе.
C# всё больше концептуально тяготеет к C++...
Ну наконец-то, field в свойствах, недавно думал, почему его еще нет, теперь поля для свойств уже не понадобятся. А вообще, C# с такими фичами, как первичные конструкторы, field, val больше становится похож на Kotlin. В Kotlin например, вообще полей нет, и это хорошо.
В Kotlin например, вообще полей нет, и это хорошо.
Объясните, пожалуйста, чем это хорошо?
Мне нравится val в Kotlin. То что C# берёт или становится похож на Kotlin в этом ничего плохого нету. Я когда попробовал Kotlin после C# сам ловил себя на мысли, что очень много схожего и хотелось бы такую штуку и в C#. Да и разрабы Kotlin'a на выступлениях говорили, что много чего взяли из C# и частично переработали и т.п.
М.б у меня нетипичные потребности, но частота применения на мой взгляд указана странная. field и required - это то, что мне постоянно требуется, и постоянно вызывало у меня вопрос: почему этого до сих пор нет? Я меня частота применения будет очень высокой.
22 новых фичи C# — каким будет C# 11+