Pull to refresh

Comments 25

Довольно неоднозначные нововведения.

Частота применения field довольно странно описана. Все новые дата классы в wpf могут быть затронуты этой фичей. Тело свойства можно спокойно копировать, менять понадобится только название и тип. Ошибка записи в не то backing field уйдет полностью.

После появления required свойств можно ожидать появления PostInit конструктора. То есть сначала вызывается основной конструктор, далее инициализируются основные свойства и в конце происходит окончательная инициализация объекта, в которой используются эти свойства.

Частота применения, конечно, субъективна и зависит от сценариев. В WPF это действительно большая фича, но в вебе такое нужно крайне редко, а в Unity не берусь судить. При этом в WPF иногда делают нотификацию изменения объекта через аспекты и тогда field не нужен. Ещё field не очень хорошо сочетается с первичным конструктором, который будет создавать поля явно.

required действительно выглядит как потенциальная смена парадигмы инициализации объектов, к которой нужно будет допиливать экосистему ещё. Потому что, например, record выглядит прекрасной фичей, но с AutoMapper сочетается довольно плохо. Если PostInit  конструкторы хорошо встроятся в DI, первичные конструкторы и другие фичи с полями и свойствами, то это будет интересное изменение. Это будет довольно сложно успеть к C# 12, так что пока значимость фичи не так понятна.

required будет иметь проблемы с сериализаторами/десериализаторами.

Зависит от реализации.
Вообще тот же STJ умеет создавать объекты через конструктор с параметрами.
Ещё вполне возможно, что required будет как и init - существовать только при компиляции.

И надо понимать, что половина написанного здесь может не доехать не только до 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>(); в конструкторе.

а чем плохо вот это?

public List<string> Names {get;} = new();

А Ваше исходное предложение к какой версии относится? Может сначала стоит сделать апгрейд до актуальной версии языка?

C# всё больше концептуально тяготеет к C++...

Ну наконец-то, field в свойствах, недавно думал, почему его еще нет, теперь поля для свойств уже не понадобятся. А вообще, C# с такими фичами, как первичные конструкторы, field, val больше становится похож на Kotlin. В Kotlin например, вообще полей нет, и это хорошо.

В Kotlin например, вообще полей нет, и это хорошо.

Объясните, пожалуйста, чем это хорошо?

Упрощается синтаксис, и унифицируется механика ООП взаимодействий. Но Kotlin - это ещё не идеал, хотя и важная веха

Мне нравится val в Kotlin. То что C# берёт или становится похож на Kotlin в этом ничего плохого нету. Я когда попробовал Kotlin после C# сам ловил себя на мысли, что очень много схожего и хотелось бы такую штуку и в C#. Да и разрабы Kotlin'a на выступлениях говорили, что много чего взяли из C# и частично переработали и т.п.

М.б у меня нетипичные потребности, но частота применения на мой взгляд указана странная. field и required - это то, что мне постоянно требуется, и постоянно вызывало у меня вопрос: почему этого до сих пор нет? Я меня частота применения будет очень высокой.

Sign up to leave a comment.

Articles