Проблема в том, что CompletableFuture — это аналог TaskCompletionSource, возвращать его из public API не айс, это нарушает инкапсуляцию — кто угодно снаружи может вызвать complete(). Казалось бы, можно возвращать CompletionStage, но оно не реализует Future. Более того, у CompletionStage есть toCompletableFuture(), что возвращает нас к изначальной проблеме. Всё это выглядит как ошибка проектирования.
Вышесказанное, а так же исторические причины, приводит к тому, что многие популярные либы возвращают свои собственные фьючи (см Netty, Lettuce). Можно представить, как здорово смотрятся 3 разных фьючи в рамках одного проекта.
На java написано много всякого распределенного и высоконагруженного. См spark, hadoop, kafka, lucene, elasticsearch. На C#/.NET ничего такого практически нет (RavenDB, что ещё?)
Как результат, на C# много вакансий клепать круды и формочки, а на java больше интересных вариантов.
C# кажется лучшим языком общего назначения на данный момент:
Лучший тулинг
Лучшая стандартная библиотека
Лучшая документация
Перформанс близок к нативному коду
Высокая скорость разработки
Нормальный асинк
LINQ
Низкоуровневые возможности, лёгкий интероп с нативным кодом
Kotlin наступает на пятки, но пока ещё недостаточно популярен.
В дотнете на все есть практики, и все им следуют
Да, и это прекрасно. Взять ту же асинхронщину. Да, тема сложная, но всё стандартизировано, расписано в доках, изучи и будет хорошо. В Java, к примеру, полный бардак и зоопарк, в каждой либе свои Future, культура асинхронного кода отсутствует, далеко не все даже "синьёры" знают, как правильно с этим всем работать.
Просто запомнил, что в некоторых случаях надо смотреть внимательно (FirstOrDefault и ко, вызовы сторонних библиотек). А в других случаях можно не напрягать мозг — если скомпилилось, то будет работать (работа с вложенными DTO, проверки аргументов в конструкторах и методах).
фича приятная, но не более того
Ну вот опять, мне такие высказывания не очень понятны. Про любую фичу так можно сказать, а звучит не очень. Я бы сформулировал так: "фича предотвращает основную часть NRE ошибок, но есть исключения, о них полезно знать".
NR типы носят скорее рекомендательный характер, ведь нам никто строго не запрещает передать null в NNR тип
На мой взгляд, вывод неправильный.
При должном старании все гарантии компилятора и рантайма носят рекомендательный характер — при помощи unsafe и указателей можно поломать что угодно. В том же духе можно сказать "GC — отличная идея, но мне не запрещают вызвать Marshal.AllocHGlobal и память утекает".
Проблема в другом — даже при включенном warnings as errors и без единого использования ! нет 100% защиты от NRE. Помимо этого, фреймворк не весь проаннотирован, что уж говорить о сторонних библиотеках. Так что по-прежнему приходится держать nullability в уме. Хотя даже в таком виде фича, безусловно, очень полезная — довелось внедрить её на свежем небольшом проекте. В 95% случаев можно полагаться на гарантии и не ломать голову на ревью, нужны ли проверки на null, или нет.
Да просто string.Empty как дефолтное значение. Для коллекций — пустая коллекция, и так далее. По аналогии с value types, у которых есть значение по умолчанию.
Чуть больше кода, зато решение очевидное и надёжное. null! лучше всё-таки избегать.
Посыл статьи хороший, выучить что-то новое — очень полезно для кругозора. Я тоже давно на сишарпе, и всегда стараюсь "щупать" все свежие языки/стеки. Но JavaScript — это шаг назад. Почему не TypeScript? В нём-то есть, чему поучиться (развитая система типов).
унифицировать backend и frontend
Это можно сделать на F# (Blazor или Fable) — получается вполне элегантно, и, опять же, интересный язык для изучения.
А ещё это можно сделать на Rust ( Yew ) — для коммерческой разработки не могу рекомендовать на данном этапе, но для хобби проектов — отличный вариант. По перформансу и минимальному размеру в топе. Сам Rust тоже очень рекомендую к изучению — показывает некоторые вещи с новой стороны (концепция ownership).
.Net Core, который претендует на кроссплатформенность
Что значит "претендует"? У него кроссплатформенность получше многих других языков/фреймворков
уровень жизни senior developers выше, чем в Европе
А это так и есть, и сей факт неоднократно перемолот во всяких чатиках удалёнщиков и постах о переездах. Платят в европах не больше, чем в Москве, а вот жить дороже.
Да, она есть, но порядок повествования, кажется, нарушен. После dotnet new -i предлагается выполнить dotnet build и dotnet run. Я следовал инструкциям из статьи и получил ошибку в этом месте.
Команда dotnet new -i Microsoft.AspNetCore.Blazor.Templates::3.2.0-preview1.20073.1 только устанавливает шаблоны Blazor. Перед dotnet run Не хватает команды dotnet new blazorwasm, которая создаст проект.
Причины исторические — шарп был долгое время с закрытым кодом и только под винду — никак не годился под такие задачи, и момент был упущен.
Проблема в том, что
CompletableFuture
— это аналогTaskCompletionSource
, возвращать его из public API не айс, это нарушает инкапсуляцию — кто угодно снаружи может вызватьcomplete()
. Казалось бы, можно возвращатьCompletionStage
, но оно не реализуетFuture
. Более того, уCompletionStage
естьtoCompletableFuture()
, что возвращает нас к изначальной проблеме. Всё это выглядит как ошибка проектирования.Вышесказанное, а так же исторические причины, приводит к тому, что многие популярные либы возвращают свои собственные фьючи (см Netty, Lettuce). Можно представить, как здорово смотрятся 3 разных фьючи в рамках одного проекта.
Какую роль в 2020 играет регион? Все на удаленке. Важна глобальная ситуация.
На java написано много всякого распределенного и высоконагруженного. См spark, hadoop, kafka, lucene, elasticsearch. На C#/.NET ничего такого практически нет (RavenDB, что ещё?)
Как результат, на C# много вакансий клепать круды и формочки, а на java больше интересных вариантов.
C# кажется лучшим языком общего назначения на данный момент:
Kotlin наступает на пятки, но пока ещё недостаточно популярен.
Да, и это прекрасно. Взять ту же асинхронщину. Да, тема сложная, но всё стандартизировано, расписано в доках, изучи и будет хорошо. В Java, к примеру, полный бардак и зоопарк, в каждой либе свои Future, культура асинхронного кода отсутствует, далеко не все даже "синьёры" знают, как правильно с этим всем работать.
Статья супер, спасибо! Кажется, самая подробная из всех, что я видел — на английском в том числе.
Это полумеры, лучше в корень репы в
Directory.Build.props
:Спасибо за уточнение, это я и имел ввиду — даже в грядущей новой версии .NET не 100% покрытие аннотациями в стандартной библиотеке.
Просто запомнил, что в некоторых случаях надо смотреть внимательно (
FirstOrDefault
и ко, вызовы сторонних библиотек). А в других случаях можно не напрягать мозг — если скомпилилось, то будет работать (работа с вложенными DTO, проверки аргументов в конструкторах и методах).Ну вот опять, мне такие высказывания не очень понятны. Про любую фичу так можно сказать, а звучит не очень. Я бы сформулировал так: "фича предотвращает основную часть NRE ошибок, но есть исключения, о них полезно знать".
На мой взгляд, вывод неправильный.
При должном старании все гарантии компилятора и рантайма носят рекомендательный характер — при помощи unsafe и указателей можно поломать что угодно. В том же духе можно сказать "GC — отличная идея, но мне не запрещают вызвать Marshal.AllocHGlobal и память утекает".
Проблема в другом — даже при включенном warnings as errors и без единого использования
!
нет 100% защиты от NRE. Помимо этого, фреймворк не весь проаннотирован, что уж говорить о сторонних библиотеках. Так что по-прежнему приходится держать nullability в уме. Хотя даже в таком виде фича, безусловно, очень полезная — довелось внедрить её на свежем небольшом проекте. В 95% случаев можно полагаться на гарантии и не ломать голову на ревью, нужны ли проверки на null, или нет.lubuntu работает сносно на полумёртвом EEE PC 901 с 2 гигами.
За Resolve — будущее, все прошники на него переходят, лучше потратить вечерок и освоить, чем с виндой маяться.
Благодаря Resolve вопрос с видео на линухе закрыт окончательно. А вот альтернатив фотошопу или лайтруму даже близко нет.
Да просто
string.Empty
как дефолтное значение. Для коллекций — пустая коллекция, и так далее. По аналогии с value types, у которых есть значение по умолчанию.Чуть больше кода, зато решение очевидное и надёжное.
null!
лучше всё-таки избегать.Посыл статьи хороший, выучить что-то новое — очень полезно для кругозора. Я тоже давно на сишарпе, и всегда стараюсь "щупать" все свежие языки/стеки. Но JavaScript — это шаг назад. Почему не TypeScript? В нём-то есть, чему поучиться (развитая система типов).
Это можно сделать на F# (Blazor или Fable) — получается вполне элегантно, и, опять же, интересный язык для изучения.
А ещё это можно сделать на Rust ( Yew ) — для коммерческой разработки не могу рекомендовать на данном этапе, но для хобби проектов — отличный вариант. По перформансу и минимальному размеру в топе. Сам Rust тоже очень рекомендую к изучению — показывает некоторые вещи с новой стороны (концепция ownership).
Что значит "претендует"? У него кроссплатформенность получше многих других языков/фреймворков
Замеры проводились? Звучит крайне сомнительно.
А это так и есть, и сей факт неоднократно перемолот во всяких чатиках удалёнщиков и постах о переездах. Платят в европах не больше, чем в Москве, а вот жить дороже.
Может, молодёжь на хайп ведётся.
Ubuntu 19.10
На пустой системе Ubuntu 19.10 проверял, после установки .NET SDK эта последовательность команд работает и приложение открывается в браузере:
dotnet new -i Microsoft.AspNetCore.Blazor.Templates::3.2.0-preview1.20073.1
dotnet new blazorwasm
dotnet run
В официальных доках нигде не упоминается установка Mono:
https://docs.microsoft.com/en-us/aspnet/core/blazor/get-started?view=aspnetcore-3.1&tabs=netcore-cli
Да, она есть, но порядок повествования, кажется, нарушен. После
dotnet new -i
предлагается выполнитьdotnet build
иdotnet run
. Я следовал инструкциям из статьи и получил ошибку в этом месте.Команда
dotnet new -i Microsoft.AspNetCore.Blazor.Templates::3.2.0-preview1.20073.1
только устанавливает шаблоны Blazor. Передdotnet run
Не хватает командыdotnet new blazorwasm
, которая создаст проект.