Меня очень возмутил вчерашний пост Что будет с C# и причём здесь Страуструп? Конечно, каждый имеет право на мнение, но автор использует множество манипулятивных техник, таким образом негативно влияя на мнение молодых читателей. Да и сам текст является маркетинговым переводом, что меня сильно удивляет. Потому и захотелось развенчать мифы из данной статьи.

Не поймите меня неправильно, я не фанбой C#. Буквально недавно в подкасте DotNet & More №53 C# 10 и не только я жаловался на то, что C#10 не впечатляет. Но в своих высказываниях необходимо стараться быть хоть немного объективным. Или, хотя бы, иронизировать над необъективностью.

Разбор оригинальной статьи

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

  • Оценочное суждение: "непонятный код", "хакерское исправление"

  • Бессмысленные, но колкие фразочки: "Я не знаю более эффективного способа, чем расползание функциональности, чтобы уничтожить язык программирования"

  • Неточное сравнение: путь из C в C++, современный C++ (с тяжелым наследием Александреску) совершенно не похож на C#. Сравнение напоминает "тарелка плоская, лежит на земле, значит земля плоская".

  • Ведение логических цепочек на основе изначально слабой гипотезы: если усомниться, что сложность языка программирования ведет к его краху, то все доводы теряют силу

  • Странная и однобокая статистика

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

Мифы

Далее я хочу попробовать развенчать часть мифов. Будет много личного мнения, так что не судите строго.

  • Сложность языка не так сильно влияет на порог входа. Я опросил множество молодых ребят и не встретил ни одно джуна, который бы жаловался на сложность синтаксиса. Для них фундаментальные понятия, типа DI, модульного тестирования, оказываются гораздо сложнее, нежели оператор switch

  • А вот среди "вечных мидлов" встречается достаточно людей, "остановившихся в развитии" на C# 5 или 6. Под "вечными мидлами" я подразумеваю программистов, которые в силу опыта (5-10 лет) уже не могут считаться джунами, но по квалификации не дотягивают до сеньоров.

    • P.S. автор изначальной статьи https://www.linkedin.com/in/andrewzuo/ имеет всего 2 года опыта работы с C#. Так что можно было бы как-то экстраполировать вышесказанное, но мы не будем этого делать.

  • Разобраться с новыми синтаксическими конструкциями очень помогает IDE. И VisualStudio, и Rider подсвечивают "новые" способы выполнить задачу короче и яснее.

  • Автор пишет "C# умирает, Microsoft убивает его, добавляя случайные штуки, о которых никто не просил". Но это не так! Начиная с C#6 все фичи предлагаются сообществом. Более того, сам процесс выбора proposal champion открытый и, более менее, независимый.

  • Автор пишет "Просто бросьте в это макрос", создавая ощущение неструктурированности развития C#. Только если бы он посмотрел в сторону F#, Scala и других ФП, то лучше понял вектор развития.

    • P.S. не очень корректно обвинять автора в узколобости, так его основной опыт работы с C# в контексте Unity, а для игр очень плохо подходят концепции функционального программирования

Заключение

Уже лет 10 я слышу из каждого утюга, что C# умирает. В какой-то момент так и происходило, но .Net Core дал технологии новую жизнь.

  • У нас есть уникальная возможность работать с библиотеками без legacy соплей. Сравните что сейчас в Spring и AspNet, чтобы понять, кто тут настоящий смузи хипстер. Спросите у Kotlin разработчиков, как много врапперов вокруг стандартных библиотек они пишут. Писать же на современном .Net очень приятно!

  • C# не на хайпе? Мы были свидетелями, когда все ломанулись в php, потом в ruby, потом в node.js, сейчас в go. И часто они оставляли за собой не очень приятный код. Вам не кажется, что это все были одни и те же люди?

  • 10 лет назад .Net был популярен, по большей части, благодаря Desktop разработке. Но падение популярности формочек лишь немного пошатнуло позиции .Net, Backend разработка растет и тащит.

  • Важно найти свое место. Ни одна технология не сможет быть универсальной, C++ занял свою нишу, и даже Rust не может его ощутимо подвинуть. Ниша C# это Backend, и фичи выходят для Backend разработчиков.

  • Иногда происходят нелогичные вещи: Java для BigData, C# для GameDev (в Unity он смотрится откровенно плохо), Go для бизнес логики. Это невозможно предсказать, сложно понять, приходится с этим просто жить.

Комментарии (130)


  1. csl
    28.10.2021 15:03

    Можете указать в вашем посте, что публикация, вызвавшая ваше возмущение, уже в черновиках (ведь ссылка фактически никуда не ведёт)?

    PS: Во время коммента пост выглядел так (возле названия поста в первом предложении нет пометки (уже скрыта, например)


    1. KAW Автор
      28.10.2021 15:47
      +4

      Странное дело, но у меня ссылка работает. Проверил в режиме инкогнито.

      У других ребят может не работаь в хроме, но работать в сафари и наоборот


      1. csl
        28.10.2021 16:03

        Спасибо за ответ, отправил запрос поддержке.


        1. csl
          28.10.2021 18:29
          +3

          Номер заявки HLT-FTHXK-341 .

          Их ответ: "При попытке перейти напрямую в пост https://habr.com/en/company/skillfactory/blog/585884 из поста https://habr.com/ru/post/586020/, он не открывается. Но если открыть в новой вкладке или вставить адрес в адресную строку, пост открывается."

          Ждём.


          1. KAW Автор
            28.10.2021 18:50
            +1

            Спасибо!


            1. csl
              29.10.2021 10:31
              +1

              Обнаружил, что при попытке перейти напрямую в пост https://habr.com/en/company/skillfactory/blog/585884 из поста https://habr.com/ru/post/586020/, как локаль в URL подставляется и ru, и en. Дописал Команде поддержки.


  1. m_a_d
    28.10.2021 15:05
    +4

    Не сказал бы, что ниша C# - backend. Скорее (судя по вакансиям) ниша C# - fullstack. Чисто бэкэндных задач на C# по-прежнему откровенно мало (по сравнению с go и java) и это печалит. Но, надеюсь, в будущем это изменится.


    1. dabrahabra
      28.10.2021 15:09
      +10

      Fullstack это FE + BE. FE на C# это Blazor - он не готов к масс продакшен. BE - то самое место где C# чувствует себя замечательно.


      1. Vadim_Aleks
        28.10.2021 16:04
        +3

        Скорее всего, речь была про связку C#+TS, а не C# для всего. Соглашусь, C# fullstack встречается чаще чем хотелось бы.


        1. KAW Автор
          28.10.2021 16:05
          +2

          Ныл я про это недавно знакомому джависту, а он мне сказал, что у них тоже самое.


          1. UncleJo
            29.10.2021 16:32

            Так всем по кайфе найти человек-оркестр :)


            1. marshinov
              30.10.2021 15:29

              Ой блин, ну ужас там разница между C#, Java и TypeScript. Сиподобные языки ж все.


              1. mvv-rus
                30.10.2021 16:05
                +1

                Главное — императивные. Вон, с БД всу куда хуже ;): там SQL декларативный — и ничо, все терпят.


                1. marshinov
                  30.10.2021 18:38

                  Вот да:))


    1. alex1t
      28.10.2021 23:04
      +2

      IMHO превалирование full-stack вакансий - это скорее желание бизнеса сэкономить. Full-stack конечно неплохо, но всё же приходится объять необъятное и какая-то часть определённо будет страдать: либо бек, либо фронт.


      1. KAW Автор
        29.10.2021 08:18
        +1

        Это называется TShaped Skills


  1. marshinov
    28.10.2021 15:10

    А static в интерфейсах тоже не впечатляет? Или логика такая, что они не успеют похоже его запилить и он в превью останется?


    1. KAW Автор
      28.10.2021 15:50

      ИМХО, такие фичи просто никто не будет использовать. А если и будут, то вреда много не нанесут


      1. ApeCoder
        28.10.2021 16:23

        Чем они принципиально отличаются от статиков в классах?


        1. marshinov
          28.10.2021 17:11
          +1

          множественным наследованием


          1. mvv-rus
            28.10.2021 22:07

            А почему бы просто не ввести множественное наследование?
            Я, например, на C++ эти самые интерфейсы эмулировал в свое время именно через множественное наследование — от виртуального базового класса (абстрактного или не совсем).


            1. marshinov
              28.10.2021 22:24
              +1

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


              1. mvv-rus
                28.10.2021 22:38

                Мне не очевидно, зачем разбираться в цепочке наследования в случае виртуального базового класса. Ведь достаточно просто добавить public virtual base_class в список классов, от которых наследуется данный, и все. А если от этого же базового класса было наследование (виртуальное) ещё где-то в цепочке, то с этим уже сам компилятор разберется.


                1. marshinov
                  28.10.2021 22:42

                  Кажется, вы меня тролите:) Ну не просто так же запретили после плюсов множественно наследование везде. Получается, всем понятно зачем запретили, вам непонятно.


                  1. mvv-rus
                    28.10.2021 23:01
                    +1

                    Про множественное наследование вообще мне понятно: знаю, что множественное наследование бывает отнюдь не только виртуальным, и способно наплодить множество экземпляров одного и того же базового класса внутри производного, что бывает, так скажем, неудобно (лично сталкивался, если чо).
                    Но виртуальные-то базовые классы лишены этого недостатка, не так ли?
                    Но в целом я ваше возражение, вроде бы, понял.


                    1. qrKot
                      29.10.2021 22:14

                      способно наплодить множество экземпляров одного и того же базового класса внутри производного

                      Там же, вроде, на diamond в мотивации отказа обычно ссылаться принято?


                      1. mvv-rus
                        30.10.2021 00:28

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


                      1. qrKot
                        02.11.2021 18:38

                        Множественное наследование позволяет унаследоваться от двух и более разных классов, имеющих метод с одной и той же сигнатурой. Неоднозначность того, какой из методов становится частью интерфейса производного класса, вроде, и называют "diamond problem". Явное указание вызываемого метода при использовании = "текущая" абстракция. Все остальное порождает ещё бОльший ворох проблем.

                        Но я тоже не то чтобы великий теоретик, тоже больше по гешефтам.


                      1. DistortNeo
                        02.11.2021 19:17

                        Но виртуальные-то базовые классы лишены этого недостатка, не так ли?

                        У виртуального наследования есть недостаток в виде реализации (при наличии полей) — это несколько vfptr в одном объекте, это ненулевые смещения базовых классов. То есть банально сравнить два объекта через object.ReferenceEquals будет в принципе невозможно.


                        В общем, я уже понял, что зря не написал, что надо разрешить только виртуальное множественное наследование

                        Ну а виртуальное множественное наследование при отсутствии полей — это и есть интерфейсы.


            1. DistortNeo
              29.10.2021 02:23
              +1

              Да пофиг на множественное наследование. С интерфейсами у меня никогда не было в нём необходимости. А вот чего реально не хватает, так это наследования структур.


              1. KAW Автор
                29.10.2021 08:20
                +1

                А вот это физически невозможно сделать :( но мне тоже не хватает


                1. ksbes
                  29.10.2021 10:29
                  +1

                  Почему невозможно? Всё "ООП" в чистых С на таком построено.

                  Тут просто вопрос о целесооборазности тянуть в нерезиновый стек лишние поля с информацией о разметке. Структуры изначально задумывались как сверх-легковесное DTO.


                  1. DistortNeo
                    30.10.2021 13:59

                    Структуры изначально задумывались как сверх-легковесное DTO.

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


                1. marshinov
                  30.10.2021 15:30

                  Инлайнить?


                  1. KAW Автор
                    30.10.2021 17:58
                    +1

                    Или инлайнить :(


          1. ApeCoder
            28.10.2021 23:36

            А как статики то наследуются?


            1. marshinov
              28.10.2021 23:43

              Посмотрите proposal champion на гите. Там достаточно подробно описано.


              1. ApeCoder
                29.10.2021 02:54

                Если про вот это то я не вижу там наследования реализации соответственно такая же ситуация как и с нестатиками. ( Все равно что имплемент метода либо явно определяем какой интерфейс реализуем либо неявно, но нет такого что две реализации пришли из разных веток даймонда)


                1. marshinov
                  29.10.2021 10:13
                  +1

                  Все так: static abstract и static sealed. Подмешивать поведение можно, мутировать стейт и создавать неочевидные цепочки наследования нельзя.


      1. marshinov
        28.10.2021 17:11

        Я буду еще как. Это ж тайпклассы почти. Супер-нужная мега-недооцененная фича. Дайте еще улучшеный вывод типов для generic'ов и abstract sealed.


        1. KAW Автор
          28.10.2021 17:20
          +1

          Да, с такой точки зрения я не смотрел


          1. WhiteBlackGoose
            28.10.2021 17:39
            +2

            Хорошая есть фраза, смысл примерно такой.

            Да, фича пилится для 1% разработчиков. Но то, что этот 1% делает, будет потом использоваться остальными 99% разработчиками.


        1. ksbes
          28.10.2021 17:55

          Ну так почему бы напрямую тайпклассы и не ввести? Зачем так?


          1. KAW Автор
            28.10.2021 17:56
            +3

            Тот же вопрос к default interface methods вообще. Может лучше было ввести новую сущность trait?


            1. marshinov
              28.10.2021 22:26

              Смотрим "На плечах гигантов" Бреслава. Там почему в Kotlin не стало трейтов. На гитхабе в issue C# тоже аргументы против трейтов приведены.


          1. marshinov
            30.10.2021 15:32

            В proposal champion написано почему решили интерфейсы расширять, а не вводить новую сущность. Там бритва Оккама.


      1. alex1t
        28.10.2021 23:15
        +2

        Лучше бы сделали поддержку более умных перечислений. Или не только методы расширения, но и свойства-расширения или статические расширения.

        P.S. Навеяно Swift. Пришлось делать проект на нём и эти вещи мне понравились


  1. anonymous
    00.00.0000 00:00


    1. byme
      28.10.2021 16:21
      +1

      Просто static ещё можно как-то понять и простить. Cамому иногда такого хочется в связке с дженериками. Но там всё прикольней - static abstract и static virtual в интерфейсах... это уже перебор


      1. marshinov
        28.10.2021 17:12

        Да нормас. Там же стейт не наследуется. Так что все ок


    1. 0xd34df00d
      28.10.2021 19:50
      +2

      А мультипараметрические тайпклассы так можно запилить?


  1. eyudkin
    28.10.2021 15:23
    +2

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

    Нормально бизнес логика на го пишется. Простая логика просто выглядит везде, а сложная логично сложно пишется и выглядит на любом языке. Может где-то она чуть проще или чуть сложнее просто благодаря наличию синтаксического сахара, но чаще всего всё просто зависит от прокладки между спинкой стула и монитором: если программист умеет писать понятно и правильно (и в меру!) использовать абстракции, то никаких проблем с написанием и восприятием такого кода не будет.

    В го зачастую "плохой" код связан с двумя явлениями, оба из которых к самому го прямого отношения не имеют:

    1. Код часто пишут джависты, а они способны писать на спринге джаве даже на фортране. Идеологически чуждый код действительно может смотреться странно и непонятно ;

    2. В го есть тяжёлое наследие в виде большого количества сишников и плюсовиков, которые тоже сильно травмированы своими языками и зачастую вообще не считают нужным думать о качестве кода в смысле читаемости, переиспользуемости и тп, просто по привычке тратя 99% "мыслетоплива" на оптимизации. В итоге иногда получается месиво из однобуквенных переменных и прочей магии и все в одном файле.

    При этом сам го я не боготворю, у него есть свои проблемы и недостатки, взять то же отсутствие енамов. Просто я часто встречаю мнения, что дескать это язык для консольных приложений или типа для выноса пары нагруженных функций из монолита, что довольно странно звучит (что вообще такое, язык для консольных приложений? Что угодно, способное запуститься из консоли?) и истине не соответствует: го вполне нормальный язык высокого уровня, со своими плюсами и минусами. Разве что чуть более низкоуровневый и чуть менее "засахаренный".


    1. KAW Автор
      28.10.2021 15:57
      +4

      Спасибо за ответ, хотелось бы послушать подробности:

      1. Как вы управляете зависимостями? DI контейнер через кодогенерацию?

      2. На сколько удобно работать без нативной иммутабельности? Обычно с ростом кодовой базы именно баги в мутациях становятся главной болью

      3. Встречались ли с проблемами отделения бизнес логики от инфраструктуры? Это важный вопрос, посколько реализация паттерна Спецификация крайне многословна (а потому и излишня) в go


      1. Vadim_Aleks
        28.10.2021 16:50
        +3

        1. Отвечу как происходит у нас. Среди более тысячи микросервисов, зависимости инициализируются и внедряются руками. Один из нагруженных проект 5-летней давности имеет ~500 строчек инициализации разных клиентов, сервисов, хендлеров, крон джоб и прочего. Конечно же, с примесью if err != nil :) Есть возможность использовать кодогенерацию (google/wire), но на моей практике, ее используют только для очень больших приложений.

          Признаться, было неудобно после перехода с ASP.NET на Go, но зато никогда не ловил баги в рантайме из-за регистрации зависимости как Scoped, а не Transient (или наоборот). Не было рантайм ошибок из-за неправильной настройки сервиса. Особенно раздражает в ASP.NET, что, когда скопипастил шаблонный проект, есть нужда поменять Startup.cs и час-два пытаться понять почему у тебя какие-то непонятные исключения при инициализации сервисов. Часто такое было с IdentityServer и иногда с EF. Возможно, я просто неправильно читал документацию, но у меня часто появлялась необходимость зайти на stackoverflow и заучивать в какой последовательности нужно описывать свой startup :)

          В Go все многословно, много действий нужно делать руками, но меньше боязни что при запуске всё разломается


        1. KAW Автор
          28.10.2021 17:23

          Спасибо, а как вообще ощущение от работы с ЯП "без магии"?


          1. Vadim_Aleks
            28.10.2021 18:02
            +3

            Ощущения смешанные. Без LINQ и обобщенных коллекций иногда неприятно. Зато как легко провалиться в библиотечную функцию или случайный проект, быстро прочитать нужный код, и понять что происходит. Но не без исключений - тот же k8s читать сложно, хотя его писали джависты)


            1. eyudkin
              29.10.2021 16:07

              Возможно, именно поэтому :D


        1. marshinov
          28.10.2021 17:37

          В бесплатном Identity Server плохая обработка ошибок внутри к сожалению...


        1. VanKrock
          28.10.2021 22:51
          +1

          В ASP.Net core 3 добавили возможность валидации DI контейнера, её нужно включать

          public static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args) .ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup<Startup>(); }) // Add a new service provider configuration .UseDefaultServiceProvider((context, options) => { options.ValidateScopes = context.HostingEnvironment.IsDevelopment(); options.ValidateOnBuild = true; });


          1. lair
            29.10.2021 14:15
            +1

            В ASP.Net core 3 добавили возможность валидации DI контейнера, её нужно включать

            … только для дефолтного провайдера. Так что на самом деле, это не в "ASP.NET Core 3", а в Microsoft.Extensions.DependencyInjection.


            1. marshinov
              30.10.2021 15:34

              Ну в Simple Injector самодиагностика сразу была… так что не только:)


      1. eyudkin
        28.10.2021 17:14

        1. Обычно для тестов юзаю DI контейнер, а продовый код - напрямую, руками (можно и кодогенерировать, но если честно нужды не возникает, один файлик на пару сотен строк отлично менеджится руками. Если разрастется, прикручу кодген), чтобы иметь компайл тайм гарантии ;

        2. В целом, нормально. Со встроенной в язык иммутабельностью было бы чуть проще, но вообще здесь выручает простое правило: не меняй по ссылке, не создавай сайд эффектов без необходимости и тп. В общем весь секрет как всегда в том, чтобы думать, что делаешь и где. За последние пару лет я не помню, чтобы у меня с этим возникали какие-то баги или проблемы. Может что-то стреляло в каком-то единичном случае, конечно, а я успел забыть.

        3. Особых проблем не возникает, обычно я по ddd выделяю инфраструктурный слой, слой приложения и доменный, и связываю их через интерфейсы и реализации. Конкретно спецификацию я использую не очень часто, это правда, чаще просто прячу логику например внутри разных методов репозитория. С переиспользованием кода и всеми ништяками, и тд.


        1. KAW Автор
          28.10.2021 17:23
          +1

          Спасибо,

          Выглядит многословно, но "должно работать" :)


    1. qrKot
      29.10.2021 22:35
      -1

      Не, в целом склонен с вами не согласиться. Утиная интерфейсная типизация - это, конечно, хорошо для решения задач, покрывающихся мелкими интерфейсами, но полноценным дженерикам, имхо, достаточно слабая замена.

      Ну и в целом откровенная бедность набора доступных коллекций в комплекте с текущими местами абстракциями, имхо, говорят не в пользу применения Go в бизнес-логике.

      Исключения vs ошибки-значения, конечно, вкусовщина, но в целом внятный самодокументированный интерфейс библиотеки на Go соорудить сложнее.

      А вот горутины/каналы - божественная штука. Как и большая часть стандартных интерфейсов. Только все это заточено под сценарий, когда нужно прожевать максимальное количество мелких задач в единицу времени, утилизировав все доступные вычислителлные ресурсы (не всегда оптимально, зато все).

      Ввиду описанной специфики, многие вещи в Go приносятся в жертву именно этому сценарию (очевидно, сценарию апи-сервера), что таки порождает проблемы в описании бизнес-логики в некоторых очень неожиданных местах.


  1. rsashka
    28.10.2021 15:28

    Сложность языка не так сильно влияет на порог входа. Я опросил множество молодых ребят и не встретил ни одно джуна, который бы жаловался на сложность синтаксиса. Для них фундаментальные понятия, типа DI, модульного тестирования, оказываются гораздо сложнее, нежели оператор switch

    Оригинальный способ сбора статистики о пороге входа только у тех, кто его успешно преодолел ;-)


    1. KAW Автор
      28.10.2021 15:57
      +4

      "Нам не нужны неудачники" :)


      1. mvv-rus
        28.10.2021 22:44
        +1

        Насколько я понимаю, отрасль разработки ПО не может позволить себе такой поход: ведь нехватка кадров достаточной квалификации — это одна из ее основных проблем, не так ли?
        PS Нет, лично я как программист (хоть и не настоящий) не против того, чтобы порог вхождения был побольше, а зарплаты — повыше.
        Но ведь общество в целом должно как-то эти зарплаты потом компенсировать?


  1. ncr
    28.10.2021 15:37
    +1

    с тяжелым наследием Александреску
    «Лично я ничего не понял, а поэтому оно тяжелое и вообще ненужное», так?


    1. KAW Автор
      28.10.2021 15:58

      Именно :)


      1. marshinov
        30.10.2021 15:37

        Ну хз, у меня как не инфраструктурный код, так сплошной Александреску. Зря вы так про Андрея.


    1. TargetSan
      28.10.2021 16:26
      +3

      Фраза "укушенный Александреску" существует не зря :)


  1. svpra
    28.10.2021 15:57
    +1

    Со всеми суждениями автора согласен. Особенно с тем, что у Шарпа лёгкий синтаксис. Это действительно так - когда я только начинал учиться, проблем с ним не особо испытывал. Смотря в прошлое, понимаю какой у меня был говнокод, и как неумело я пользовался паттернами. Но мне кажется все с этого начинали))


  1. umbarov
    28.10.2021 15:58
    +1

    1. KAW Автор
      28.10.2021 15:58

      Странно, не у всех работает


      1. csl
        29.10.2021 10:35

        А именно ссылка из коммента выше работает? Потому что при попытке перейти напрямую в пост https://habr.com/en/company/skillfactory/blog/585884 из поста https://habr.com/ru/post/586020/, как локаль в URL подставляется и ru, и en, получается ссылка именно вида https://habr.com/ru/en/company/skillfactory/blog/585884/ , в этом всё и дело.


  1. poletos
    28.10.2021 15:58
    +1

    • P.S. не очень корректно обвинять автора в узколобости, так его основной опыт работы с C# в контексте Unity, а для игр очень плохо подходят концепции функционального программирования

    Можно раскрыть тезис про "для игр очень плохо подходят концепции функционального программирования"? Насколько я знаю Джон Кармак высказывался в пользу использования функционального программирования для разработки игр. Не знаю, какие конкретно проблемы в Unity для использования идей из фп, но не вижу вообще никаких проблем в их использовании.


    1. KAW Автор
      28.10.2021 16:04
      +2

      1. Иммутабельность плохо уживается с изменчивостью игрового мира

      2. Если мы будет строить pipeline в каждом цикле game loop, то не факт что сможем "уместить" все в один кадр

      3. Достаточно удобный подход в асинхронном выполненияя кода в функциональном стиле, но это требует "слома головы"

        1. А вот если писать императивно, но с async/await или корутинами, получается даже удобнее

      Самое неприятное, что ФП стиль неплохо ложится на многие тулы в Unity (то же DOTween), но сложно это жкстраполировать на все.

      Про перфоманс не буду говорить, а то захоливаримся:)


      1. 0xd34df00d
        28.10.2021 19:56
        +2

        ФП не означает иммутабельность. Современный ФП про контроль эффектов в типах, и мутабельность там ничему не противоречит. Хоть в монады заворачивайся, хоть линейными типами обмазывайся.

        А перформанс из хаскеля я достаточно регулярно выжимаю на уровне плюсов. Да, получается не всегда, но и на плюсах-то не всегда достижима топовая производительность.


        1. mvv-rus
          28.10.2021 23:26

          ФП не означает иммутабельность. Современный ФП про контроль эффектов в типах, и мутабельность там ничему не противоречит.

          Но как с этим в C#? AFAIK — никак и не планируется.
          А без этого, с одними делегатами как воплощением first class function, нельзя ни в чем быть уверенным. И, оборачивая переданный в качестве параметра делегат в свой, чтобы сделать, к примеру, композицию, вы не можете быть уверены, что вызов этого вашего делегата не отдаст, условно, команду начать ядерную войну через делегат-параметр.


      1. orthoxerox
        05.11.2021 01:51

        А вот если писать императивно, но с async/await

        Я такое из коробки видел только в Paradox/Xenko/Stride, в Unity вроде бы через генераторы извращались. Буду признателен за ссылку.


    1. SShtole
      29.10.2021 09:17
      +1

      Можно раскрыть тезис про «для игр очень плохо подходят концепции функционального программирования»?

      Есть такой очень умный человек — Эрик Липперт. А комиксы рисуют почему-то про Джона Скита... Серьёзно, можно зайти на StackOverflow, открыть его страницу и начать читать ответы как статьи. Хотел бы я уметь ТАК излагать мысли.

      Так вот, он, по-моему, приводит замечательный пример pure FP в игрострое:

      Because all those advantages are also disadvantages.

      >Stateless programs; No side effects

      Real-world programs are all about side effects and mutation. When the user presses a button it's because they want something to happen. When they type in something, they want that state to replace whatever state used to be there. When Jane Smith in accounting gets married and changes her name to Jane Jones, the database backing the business process that prints her paycheque had better be all about handling that sort of mutation. When you fire the machine gun at the alien, most people do not mentally model that as the construction of a new alien with fewer hit points; they model that as a mutation of an existing alien's properties.


  1. DarthVictor
    28.10.2021 16:15
    +4

    Как человек, который недавно только решил поизучать C# могу сказать, что у меня действительно некоторый функционал вызывал недоумение. Вроде наличия делегатов / ламбда-функций / анонимных-методов. Но оно не то чтобы непонятно как, скоре непонятно почему сразу не добавили функции как объекты первого рода (если бы язык с нуля писали то возможно так и было бы). Или зачем нужны out параметры при наличии возможности возвращать несколько значений, но out параметры появились раньше, странно было бы их удалять. Null-safety тоже вот зачем-то (на самом деле понятно зачем) сделали через warning, а не через ошибку компиляции.

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

    Вы можете добавить pattern-matching в switch, но не можете удалить старый switch. В лучшем случае задеприкейтеть его и удалить лет через 10.


    1. byme
      28.10.2021 16:39
      +2

      Или зачем нужны out параметры при наличии возможности возвращать несколько значений, но out параметры появились раньше, странно было бы их удалять.

      Они очень часто используются для вызова С/С++ библиотек. А это то на чем живет dotnet внутри. Плюс они уже прижились в разных API-аях те же TryParse/TryGet и т.д.

      Вы можете добавить pattern-matching в switch, но не можете удалить старый switch. В лучшем случае задеприкейтеть его и удалить лет через 10.

      Они все-таки не однозначны. pattern-matching switch не может заменить все старые switch.


    1. NN1
      28.10.2021 18:00
      +1

      Null-safety тоже вот зачем-то (на самом деле понятно зачем) сделали через warning, а не через ошибку компиляции

      Потому как ломает много кода, по желанию легко превратить предупреждения в ошибки: .editorconfig


    1. KvanTTT
      28.10.2021 20:21

      Удалять функционал сильно сложнее, чем добавлять.

      Удалять как раз проще, сохранять обратную совместимость сложно. А то получится как в Swift, в котором старый код может не скомпилироваться новым компилятором.


    1. marshinov
      28.10.2021 23:52

      Ну есть такой момент… многие уже начали говорить, что C# идёт по кривой дорожке C++. Однако команда C# тратит просто очень много времени на дизайн и анализ. Будьте уверены, что все новые фичи продумываются от и до.


  1. oOKIBrTlUTohw4Sc
    28.10.2021 16:38

    Спросите у Kotlin разработчиков, как много врапперов вокруг стандартных библиотек они пишут. 

    Отвечаю - ноль. А зачем? Большинство популярных библиотек поддерживают котлин, те что не поддерживают - есть альтернативы, а если и этого нет, то все взаимодействия с джава либой - это правильно расставить ? и !! (и то не обязательно), что как бы даже близко не "написать враппер". Это вам какие-то оверинженеры попались. Хотя я отвечаю с точки зрения бэкенда, что там у андроидщиков не знаю.

    ИМХО, я не понимаю как язык может умирать. Язык + область его применения - это целая отдельная тусовка людей, со своими взглядами на то "как нужно писать код". Поэтому и появляется как выше писали "джависты которые на любом языке пишут на джаве". Я вот и сам гуглю, когда начинаю писать на новом языке "<lang name> dependency injection".

    До котлина моим любимым языком была скала, но "тусовка" скалистов мне вообще не зашла. Я не мог смириться, например, с DSL в духе, где №%?(Й; - это не маты в комментариях, а имя функции. Котлин мне понравился своим балансом. Помню, натыкался на статьи про упоротое ФП для котлина как в скале, в комментариях все писали "фу, нафиг оно надо". В комментариях к статьям по скале очень часто же встречается код на хаскеле. Хотя казалось бы, в скале есть все, что есть в котлине, зачем котлин вообще нужен то.

    Даже если с# вдруг перестанет существовать, этой тусовке нужно будет куда-то деться. Если вот котлина вдруг не станет, гипотетически, я лично с удовольствием перейду на TypeScript + NestJS. Одиноким вы точно не окажетесь. А если все ваше профессиональное мировоззрение крутится только вокруг языка... Что ж, сочувствую, видимо пора двигаться дальше...


    1. marshinov
      28.10.2021 17:40
      +1

      А как джависты про Котлин вообще: с удовольствием переходят или есть те, кто "фу-фу-фу эти ваши лямбды, сложна-сложна непонятна, лучше уж на восьмерочке оставаться"? Понятно, что люди разные, но если взять среднюю температуру по больнице?


      1. Reformat
        29.10.2021 07:46
        +1

        Переходят постепенно. Kotlin медленно но верно отжимает и backend разработку.


        1. ksbes
          29.10.2021 10:37
          +2

          Как джавист с опытом скажу: с семёрки (привет Android!)/восьмерки приятнее переходить на Kotlin, чем на Java 11++ (при условии, что используем новый функционал).

          Дело даже не в удобстве, а в ощущении полноты и логичности. Т.е. если переходим на новые парадигмы - так сразу, везде и полностью. И не в год по чайной ложке.


          1. marshinov
            30.10.2021 15:38

            А то что статиков нет и есть корутины не вызывает дискомфорта?


            1. ksbes
              02.11.2021 09:51
              +1

              Статики - есть. Корутины - наоборот очень комфортно (в Java немного подзадалбывает всем в экзекюторах ручками управлять), в С# сильно не хватает.


              1. marshinov
                02.11.2021 10:31

                Ну все-таки есть object и companion. Да, я знаю про @JvmStatic,но мы говорим про язык, а не байткод. async/await, yield чем не корутины в C# или вы свои корутины пишете когда-нибудь? Если пишете, очень интересно узнать какие real-world scenarios для этого. Из очевидного - arrow, но я не уверен, что все понравятся конструкции вида:

                result {
                  val smth = r.bind()
                  //...
                }  

                Лично мне нравятся. Я бы еще и инфиксную нотацию или оператор для bind добавил, но вот студенты жалуются :)


                1. ksbes
                  02.11.2021 10:52
                  -2

                  В меня простите, но вот эти ваши откровения:

                  async/await, yield чем не корутины в C# или вы свои корутины пишете когда-нибудь?

                  мне говорят о том, что вы слабо понимаете что такое корутины и что такое Task в C#.

                  Если вам интересен real-world scenario - то я, в том числе, на корутинах писал middle-ware - т.е. сервер, который собирает данные с активных и пассивных датчиков и предоставляет их через REST службу потребителю. Корутины (да, "самописные") сократили изначально джавовский код в разы, при этом в разы подняв его читаемость и исключив падучесть.

                  Из очевидного - arrow, но я не уверен, что ...

                  ??? Вас вообще куда понесло-то?


                  1. marshinov
                    02.11.2021 12:25
                    +1

                    мне говорят о том, что вы слабо понимаете что такое корутины и что такое Task в C#.

                    Ну просветите, по мне разница только в том что в Kotlin концепт обобщенный, а в C# гвоздями прибили ключевые слова. В обоих случаях CPS получаем. Опять же async/await можно же перебить на свои awaiter'ы, просто это не нужно никому.

                    Корутины (да, "самописные") сократили изначально джавовский код в разы, при этом в разы подняв его читаемость и исключив падучесть.

                    Ну т.е. вы описали типовой сценарий использования акторов. Т.е. скорее всего можно не писать свои корутины, а использовать существующие.

                    ??? Вас вообще куда понесло-то?

                    Я об этом.


                    1. ksbes
                      02.11.2021 13:18
                      -2

                      Ну просветите...

                      Не нанимался.

                      Для того чтобы начать - корутины это не про стиль написания кода и не про ключевые слова. Это способ организации ("параллельных") вычислений. И да, в Kotlin тоже "прибиты" ключевые слова (точнее слово - suspend). А CPS - можно вообще в однопоточном коде безо всякой асинхронности организовать. С корутинами, конечно, продолжения связанны но это всё-таки другая опера.

                      Т.е. скорее всего можно не писать свои корутины <...>

                      Каково ваше определение фразы "писать свои корутины"? Свой корутинный фреймворк что-ли? Конечно я его не писал.

                      >??? Вас вообще куда понесло-то?

                      Я об этом.

                      Так и я об этом. Куда вас понесло и зачем?

                      И самое главное, как ваши аргументы относятся к вашему изначальному тезису, что в Котлине "дискомфортно" из-за корутин?


  1. viruseg
    28.10.2021 19:29
    +6

    >>C# для GameDev (в Unity он смотрится откровенно плохо)
    В статье про манипулятивные техники используются манипулятивные техники. Вот это поворот.

    Чем плох шарп в юнити? После того как появился Burst (трансляция IL/.NET в LLVM) и Jobs system (многопоточный код), то о каких-либо проблемах с производительностью можно забыть. С каждой версией Unity всё большее количество апи поддерживает работу с NativeContainer. Даже если не утруждать себя написанием многопоточного кода, а только пропустить тяжёлый метод через Burst, можно получить буст производительности в 10-20 раз. Также в методах, которые невозможно вынести из основного потока можно использовать unsafe context. В результате на выходе получится игра сравнимая по производительности с аналогом на c++.


    1. HelpOrMe
      29.10.2021 13:43
      +2

      Осталось переписать весь движок с поддержкой новых Jobs, Burst и ECS. Я вообще не понял зачем они решили доказать что c# может быть такой же быстрый как с++, и добавили туда Burst (трансляция в LLVM), NativeContainer'ы (освобождение памяти или утечка) и оперирование этим всем с указателями в unsafe. Могли сразу просто прямую поддержку плюсов впилить да и всё на этом.

      Ещё эти Jobs + ECS с просто тьмой бойлерплейта, для того, чтобы просто проитерировать компоненты в IJobChunk надо сначала объявить их хенделры как поля, потом получить списки с компонентами у чанка, а потом уже по индексу получить компонент, в итоге если тебе надо использовать в Job'e к примеру, 5 компонентов, у тебя уже 15 строк просто для того чтоб просто их получить.

      Может статью напишу про то, как у юнити в данный момент все плохо с переходом на DOTS.


      1. KAW Автор
        29.10.2021 13:44
        +1

        Жду статью :)

        Вообще с Burst не так все плохо, а вот с ECS беда. Там любое действие требует танцев с бубном


        1. SH42913
          01.11.2021 10:30
          +1

          Хочу заметить, что "с ECS беда" конкретно в DOTS, сам по себе ECS как паттерн штука хорошая и в большинстве фреймворков не требует танцев с бубном, но юнитеки ради гипер-производительность очень переусложнили фреймворк


          1. KAW Автор
            01.11.2021 13:58

            LeoEcs это прям супер пример, показывающий как надо делать ECS фреймворк. Особенно в сравнении с Entitas и ОСОБЕННО с UnityECS


            1. SH42913
              01.11.2021 15:01

              Это да. После LeoECS количество годных ECS-фреймворков для шарпа начало увеличиваться: Actors, Morpeh, ME.ECS, DefaultECS... Такая тенденция не может не радовать.


      1. viruseg
        29.10.2021 14:38

        Чтобы получить все преимущества Jobs и Burst, к счастью, необязательно использовать DOTS.

        >>Могли сразу просто прямую поддержку плюсов впилить да и всё на этом.
        Unity очень долго развивалась, а Burst появился не так давно. Менять сейчас c# на c++ не лучшая идея. Поэтому Burst это отличное решение.


      1. DistortNeo
        29.10.2021 14:54
        +1

        Могли сразу просто прямую поддержку плюсов впилить да и всё на этом.

        Так был же Managed C++. Правда, его достаточно быстро похоронили из-за его неэффективности.


        В результате на выходе получится игра сравнимая по производительности с аналогом на c++.

        Ну да. Вообще, даже JIT-компиляция в современном .NET не так уж и плоха (я даже замеры в задачах обработки изображений делал, сравнивая C# и C++ реализации — почти паритет). Тормоза C# — это миф, растущий корнями с .NET 1.0. Сейчас такого уже давно нет.


        1. marshinov
          30.10.2021 15:40

          А сейчас в 6 ещё pgo завезут…


    1. KAW Автор
      29.10.2021 13:46
      +1

      Сборка мусора. Да, есть incremental gc, но это не панацея, так как он дает лишь небольшой послабление, в любом случае необходимо все подряд пулить.


      1. marshinov
        30.10.2021 15:41

        Ну можно не аллоципоывать на хипе и хрен с ним с GC:))


        1. mvv-rus
          30.10.2021 17:32

          Можно, но сложно. Очень. Все самое вкусное — это managed типы, и, к примеру, массив из них на стеке через stackalloc/Span не разместить, если без unsafe.
          По крайней мере, я попробовал, покрутил туда-сюда и плюнул на это дело.


          1. marshinov
            30.10.2021 18:40

            Не, ну не совсем. Пока уровень грузится аллоцировал, а потом не аллоцируешь. В open world правда не прокатит


  1. SShtole
    28.10.2021 19:31
    +5

    Всё это можно было написать гораздо короче )

    В первом примере речь идёт о pattern matching. Хотя автор не видит ничего, кроме извращённой формы switch. PM появился в 60-х годах прошлого века. В дотнет он проложил путь 18 лет назад, когда вышел Nemerle. Наконец, его включили в C#. Да, да, дело не в узком кругозоре и непонимании контекста нововведения автором статьи, а авторы сишарпа не знают чем себя занять (нет). Кстати, зачем нужен PM и как он поможет писать более выразительный код — в принципе, можно было понять, просто 5 минут поглядев на пример, приведённый MS.

    Во втором примере сначала var называют «уже достаточно спорным». Серьёзно?! Выведение типов, которое позволяет по выразительности подойти вплотную к динамической типизации, без которого руки начинают болеть через полчаса кодирования — спорное? Разумеется, нет. Но проблема с ним была в том, что не всюду выведение типов можно засунуть. В параметры функций — нельзя, в описание полей — нельзя. Но с параметрами функций ничего и не сделаешь (наверно), а вот в описании полей — очевиднейший копипаст, который так и напрашивается на сокращение. Его и сократили, только с другого конца. И правильно сделали — не описывать же поля с var'ом.

    Итого: два примера, показывающих очень слабое понимание + набор неверных выводов из них. Больше ничего.


    1. ksbes
      29.10.2021 10:47
      +1

      описании полей — очевиднейший копипаст, который так и напрашивается на сокращение. Его и сократили, только с другого конца. И правильно сделали — не описывать же поля с var'ом.

      А почему бы и не описывать поля с var'ом? Что мешает в C# тип поля выводить? Вон в "дальнеродственном" Котлине - работает. Так не делают в С++ - но у них свои заморочки с типами вообще.


      1. SShtole
        29.10.2021 11:13

        Как ни странно, я вчера как раз об этом же подумал. Может, потому, что сишарп — в первую очередь сишарп? ) И так-то недовольных полно, а тут совсем вонь поднимется до небес.

        На самом деле, я очень люблю всё, что начинается на «си-», но со временем осознал, что есть свои преимущества в:

        field Foo : int = 5;
        field Bar = 5;
        field Bas = new Hyper.Mega.SuperObject(42);


      1. marshinov
        30.10.2021 15:43
        +1

        Компилируется только Котлин подольше


  1. Tuwogaka
    29.10.2021 13:01
    +1

    Смотрю со стороны с момента убийства Silverlight. Поэтому мало понимаю. Особенно в комментариях.

    В исходной статье ссылка на тенденции Stack Overflow. Данные показывают однозначно - С# умирает. Смотрим на Go, Rust, Java, Kotlin, Dart, Flutter, Swift - выглядит правдоподобно. Значит, тенденции работают и то, что C# умирает - наблюдаемый факт. Если и спорить, то о том, продолжит ли умирать.

    Как обстоит дело на самом деле, лучше всех знает Микрософт. Узнать что она знает не имея личной разведки и группировки спутников можно только по её действиям, а это .NET 6, который под пандемические оправдания опаздывает на один год, и MAUI, который на пол года минимум опаздывает ещё. Впечатление такое - полная (macOS, iPadOS, iOS, Android, Windows) кроссплатформенность считается условием выживания. MAUI опаздывает, Uno зато есть уже. Как можно говорить о будущем C# без неё - не понимаю, разве что фактическое наличие будущей кроссплатформенности, которая увы тенденции не ломает, может не нравиться.

    Не только C# с .NET 6 и MAUI озаботилась кроссплатформенностью. Flutter сначала записал альфу и бету, macOS и Windows, в релиз, а потом прикрыл заднюю результатами опроса - мобилки и Интернет, дескать, людям важнее. Ну ладно, это для Микрософт Blazor - игрушка, а для Гугол Web - единственный источник дохода. Но тут и Go и Rust и Python и C++, у всех так или иначе полная кроссплатформенность уже есть. И Kotlin Native вроде как из беты выходит.

    Почему все засуетились я думать не буду, а то ещё внесу запрещённую законом рознь упомянув Эппл. Но вопрос о том, всё ли хорошо будет у C#, вроде как сводится к двум. На сколько кроссплатформенность поможет и если поможет, то кому в первую очередь?


    1. KReal
      29.10.2021 15:45

      .Net 6 вроде бы production ready. Мы используем уже)


      1. ksbes
        29.10.2021 15:48

        Вроде пока только release candidate. Т.е. пользоваться можно - но осторожно.


        1. KReal
          29.10.2021 16:17

          devblogs.microsoft.com/dotnet/announcing-net-6-release-candidate-2

          We are excited to release .NET 6 Release Candidate 2. It is the second of two “go live” release candidate releases that are supported in production


    1. DistortNeo
      29.10.2021 16:18

      Не только C# с .NET 6 и MAUI озаботилась кроссплатформенностью

      Не озаботилась. Поддержка Linux в MAUI не планируется в .NET 6.


      1. Tuwogaka
        29.10.2021 17:25

        Я так понимаю, что .NET 6 в каком-то виде на Линуксе будет, только MAUI приложений ни разрабатывать ни выполнять будет нельзя. Тогда в какой-то мере озаботилась, в какой-то нет. Как по мне, лучше так, чем, например, поддерживать Убунту и только Убунту.


        1. DistortNeo
          29.10.2021 18:14

          .NET 6 в каком-то виде на Линуксе будет

          .NET уже давно существует и прекрасно себя чувствует под Linux ещё со времён .NET Core, а до того момента была вполне себе полноценная реализация .NET Framework в виде Mono. Но вот кросс-платформенного GUI от Microsoft как не было, так и до сих пор нет.


    1. Eltaron
      29.10.2021 17:03
      +2

      В исходной статье ссылка на тенденции Stack Overflow. Данные показывают однозначно - С# умирает.

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


      1. Tuwogaka
        29.10.2021 22:33
        +1

        В принципе, может такое быть. Поэтому я и посмотрел остальное, а там результаты ожидаемые. Получается, что если JavaScript с его порогом, то действует он только на C# - тоже может в принципе так быть, но верится в последнюю очередь. Скорее если бы порог входа на что-то влиял, то в первую очередь убился бы Rust.


  1. locky37
    29.10.2021 13:48
    +1

    Согласен, что статья про очередную смерть C# не совсем корректна.

    На данный момент гляжу на Unity и что творит Burst, это магия какая-то.

    А .NET 6 с заявленной кросс-платформенностью выглядит очень интересно.


  1. Beren007
    29.10.2021 13:48
    +4

    Я новичок. Новичок, который только начал свой путь разработчика. Пишу на работе по необходимости консольные утилиты на C#, скрипты на T-SQL.

    Во-первых, дойдя до места, где в статье появляются ссылочки на курсы - я испытал откровенно негативные эмоции (т.к. потратил кучу времени на бесполезные курсы, где якобы за год из вас сделают fullstack - не сделают, проверил на себе). Во-вторых, статья вызывает грусть от ощущения, что очередной автор страдает синдромом утёнка...

    Недавно я наткнулся на статью, где человек сравнивает доли языков бекенда при создании веб-сайтов. PHP, Ruby, Python...и туда же автор "анализов" запихнул фреймворк Asp.Net. Наверное многие, кто интересуется или разрабатывает на C#, видели эту статью. Там что-то около 78% доли PHP и слова о том, что Microsoft должна испугаться этих цифр....Почему? Мне не понятно.

    Одни рекламируют свои курсы, пописывая всякий бред, другие сравнивают ЯПы с фреймворками, говоря об превосходстве конкретного ЯП на фреймворком... Хочу сказать им спасибо. Они из раза в раз все сильнее укрепляют моё желание самостоятельно изучать C#, со всеми его улучшениями, с Microsoft которая "убивает" язык, с 1.5% доли сайтов на Asp.Net...


    1. Arlekcangp
      30.10.2021 02:40

      Всё правильно делаете. "Собака лает, корован идëт" Смерть сишарпу горе-пророки предрекали ещё до выхода первой версии... Что касается сравнений с другими ЯП, то тут вообще клоунада: сравнивают по всей видимости те, кто не знает ни одного ЯП. Сейчас пишу на сишарп и джаве одновременно. С сишарпом имел опыт ещё в 2010-11 годах, потом был перерыв. Вернулся полгода назад. Вижу, что язык подрос и вполне себе живёт. Также и джава - многое туда перешло из котлина. Как идея, но как правило сделано это с оглядкой на прошлый опыт, а не просто "ну мы решили ещё и эту свистоперделку добавить". Это кстати одна из проблем новомодных (и не очень) языков - расширяем не что бы пользоваться, а потому что " это круто". За 20+ лет в ит я понял, что спешить некуда, идеи всë теже, только реализация с каждой итерацией лучше. И реально выходит, что нужно 5-7 итераций что бы продукт дорос до качества предшественника (разумеется исправив некоторые из его недостатков) Не много дорастает. Большая часть сваливается в забвение. Поэтому тут выбирать надо первым делом уже твёрдо стоящих на ногах. И сишарп, и джава, и плюсы безусловно к таким относятся. Остальным же ещё предстоит доказать, что они эту планку перешагнуть могут. А потому на них время нужно тратить по остаточному принципу. Ради интереса, хобби и т д. Но уж совсем глупо думать, что эти новички могут в одночасье "подсидеть" "титана".


  1. Raimon
    29.10.2021 17:04
    +1

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

    хорошо что починили главные проблемы экосистемы и рантайма: открытость, кросплатформенность, производительность (раньше например не возможно было сделать сериализаторы или сокет сереверы которые не будут неистово генерировать мемори трафик).


    1. KAW Автор
      30.10.2021 09:53

      А про какие тонкости Вы говорите? С моей точки зрения в C# стало даже меньше способов отстрелить себе ногу, по сравнению с 5 версией.

      1. Пофиксили проблемы с лямбдами в цикле

      2. Добавили полноценную иммутабельность, не нужно костыли писать

      3. В основных фреймворках убрали привязки в событиям, так что исключили массу проблем

      Из новых проблем я бы отметил только Tuples в коллекциях: они изменяемые структуры


      1. marshinov
        30.10.2021 15:51
        +1

        На прошлой неделе наткнулся: рекорды поддержали в model binding, но Display(Name=***) в конструкторе забыли поддержать:) А так dto-шки рекордами - милое дело.


  1. korsetlr473
    30.10.2021 16:53

    ушел когда появился первый .net core

    Подскажите в текущем .net core webapi из коробки поддерживается DI для инициализации классов с дефолтным конструктором без мэппинга при старте приложения? (Ninject так работает)


    1. lair
      30.10.2021 17:07

      Если я правильно понимаю, что вы хотите — да, поддерживается.


      Но лучше приведите пример.