Я являюсь студентом по обмену из российского ГМИГ имени Трофима Лысенко (Главный Мурманский Институт Генетики). Учился на инженера-программиста и пол года назад был отправлен в Америку в качестве студента по обмену. Это у меня получилось благодаря двойному гражданству (я гражданин Ирана и России).

К нам на лекцию пришел один из разработчиков Microsoft и рассказал про .NET 10, подробнее в самом низу статьи под спойлером.

.NET 10 или как его теперь начнут называть .NET X - это новая версия .NET, которая выйдет уже в 2024 году. Большая часть этой статьи посвящена именно новым возможностям C# 13.

Почему .NET 10 и где .NET 9?

"У нас так принято." - Дословный перевод. Больше комментариев разработчик не дал.

Упрощение создание экземпляров класса

Не буду тянуть время и сразу покажу самое лучшее нововведение. Допустим у нас есть класс Person и нам надо создать его экземпляр.

public class Person
{
  public string Name {get; set;}
  public int Age {get; set;}
  public Person(string name, int age)
  {
    Name = name;
    Age = age;
  }
}

Раньше у нас было всего 3 способа создание класса.

Person man1 = new Person("Mike", 32);
var man2 = new Person("Mike", 32);
Person man3 = new("Mike", 32);

Новая версия C# позволяет комбинировать var и new(). Это легко читается и экономит место.

var man1 = new("Mike", 32);

Новые инкременты

Были добавлены аналоги инкремента для деления и умножения.
i++ эквивалентно i = i + 1
i// эквивалентно i = i / 1
i** эквивалентно i = i * 1

int a = 3;
Console.WriteLine(a**); //3
Console.WriteLine(a//); //3

Этот код эквивалентен прошлому примеру:

int a = 3;
a = a * 1;
Console.WriteLine(a); //3
a = a / 1;
Console.WriteLine(a); //3

Из минусов т.к. оператор инкремента деления аналогичен началу комментария, то символ начала комментария будет изменен на свою экранированную версию.

int a = 10;
int b = a // "some comment"
\/\/ CS0019 Оператор "//" не может применяться к операнду типа "Int32" и "String"
\/\/ Look, I'm comment!

Улучшение синтаксиса интерполирования строк

Теперь можно создать интерполированную строку не только при помощи знака $, но и €.

string name = "Michael";

string a = €"Hello, {name}!";
string b = $"Hello, {name}!";

Console.WriteLine(a == b); \/\/ True

В версии .NET XI (.NET 11) обещают также ввести поддержку символа £.

Создание экземпляров абстрактных классов

Эта возможность уже была в версиях .NET Core 3.1 и .NET 5.0, но позже ее удалили. Как было раньше:

public abstract class AbstractShape
{
  public AbstractShape() { }
  
  public void Print()
  {
    Console.WriteLine("I have no area");
  }
}

class Program
{
  static void Main(string[] args)
  {
    Type AbstractShapeType = typeof(AbstractShape);
    ConstructorInfo magicConstructor = AbstractShapeType.GetConstructor(Type.EmptyTypes);//get Constructor

    Type TypeRuntimeMethodHandle = typeof(RuntimeMethodHandle);MethodInfo magicMethod = TypeRuntimeMethodHandle.GetMethod("InvokeMethod", BindingFlags.Static | BindingFlags.NonPublic);//get InvokeMethod from RunTimeMethodHandle

    PropertyInfo sigInfo = magicConstructor.GetType().GetProperty("Signature", BindingFlags.Public | BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Instance);//get signatureAbstractShape shape = (AbstractShape)magicMethod.Invoke(null, new object[] { null, null, sigInfo.GetValue(magicConstructor), true, null });

    shape.Print(); // I have no area
    Console.ReadLine();
    
  }
}

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

Ключевое слово unsaviest

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

unsaviest
{
  AbstractShape shape = new AbstractShape();
  \/\/ Или воспользумся облегченным созданием экземпляров
  var shape2 = new();
}

Отрицание сравнения

Теперь операнд ! можно применить к операндам сравнения.

Console.WriteLine(3 > 5); \/\/ False
Console.WriteLine(3 !> 5); \/\/ True

Console.WriteLine(5 >= 5); \/\/ True
Console.WriteLine(5 !>= 5); \/\/ False

Readonly constant

Теперь есть readonly константы, которые можно получить только через экземпляр класса

public class MyMath
{
  public readonly const double PI = 3.14;
}

public class Program
{
  static void Main()
  {
    var math = new();
    Console.WriteLine(math.PI); \/\/ 3.14
    Console.WriteLine(MyMath.PI); \/\/ Error
  }
}

На самом деле код класса на этапе компиляции превращается в:

public class MyMath
{
  private const double __value_PI = 3.14;
  public double PI
  {
    get
    {
      return __value_PI;
    }
  }
}

Мое личное мнение, что readonly const это излишний синтаксический сахар, хотя может кому-то и понравится.

Заключение

Интервью

К нам на лекцию пришел один из разработчиков Microsoft "Джеймс Хейлсберг" и рассказал про устройство .NET. Под конец лекции он вскользь упомянул про .NET 10. После лекции я подошел к нему с вопросами и слово за слово он согласился на интервью. В этой статье я привел выжимку и перевод 23 минутного интервью, которое я выложил на YouTube.

Оно на английском, но я добавил субтитры
https://www.youtube.com/watch?v=dQw4w9WgXcQ

Спасибо за прочтенье, всех с днем математика.

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


  1. gotoxy
    00.00.0000 00:00
    +17

    var man1 = new("Mike", 32);

    Наконец-то!

    Про private virtual инфы нет?


    1. Vest
      00.00.0000 00:00
      +5

      Можно еще сократить, убрав new, а потом и var. И так понято будет, type inference поможет.


      1. ildarin
        00.00.0000 00:00

        Убрать var и new как раз таки можно, оставив только название класса. Смысла в этих словах все равно нет.

        Тут я развил идею

        https://www.codeproject.com/Articles/5353397/QW-Quick-Write-The-Most-Succinct-Programming-Lang



    1. devlev
      00.00.0000 00:00

      Ура, круто!


    1. mikle305
      00.00.0000 00:00
      +1

      и в чем интересно польза? сократили 1 слово взамен на явность типа при чтении?



    1. NoofSaeidh
      00.00.0000 00:00

      Вообще private virtual вполне себе полезный кейс. Несколько раз натыкался когда он очень подходил, если бы был.

      Это бывает нужно в классе в котором наследник объявляен как nested class и метод не хочется открывать на публику, но при этом надо в этом наследнике переопределить.

      Воркэраунд - private protected virtual, но с тем же успехом можно сказать - зачем private, делай все internal.


  1. viordash
    00.00.0000 00:00
    +11

    i** эквивалентно i = i * 1apr

    очень актуально, отлично!!


    1. Ogoun
      00.00.0000 00:00
      +3

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


  1. Markscheider
    00.00.0000 00:00
    +2

    Я прошу прощения, это первоапрельский пост? В поисковике не нашел ничего о "Главном Мурманском Институте Генетики", да и "имени Трофима Лысенко" сильно озадачило.


    1. insighter
      00.00.0000 00:00
      +21

      Тэги к посту говорят, что всё серьезно. Уже переписываю пэт проекты.


    1. flygrounder
      00.00.0000 00:00
      +23

      Были добавлены аналоги инкремента для деления и умножения.
      i++ эквивалентно i = i + 1
      i// эквивалентно i = i / 1
      i** эквивалентно i = i * 1

      Как будто бы на этом моменте всё должно стать понятно


      1. Markscheider
        00.00.0000 00:00
        +4

        Как будто бы на этом моменте всё должно стать понятно

        Я досюда не дочитал, прифигел уже на первом абзаце :)


      1. fire64
        00.00.0000 00:00
        +9

        Я в начале думал все, приехали...

        Потом вспомнил, про первое апреля и отпустило....


      1. Myxach
        00.00.0000 00:00
        +4

        ну часть звучит как будто то что реально могут добавить


      1. user5000
        00.00.0000 00:00
        +2

        Я насторожился ещё на институте имени Трофима Денисовича Лысенко.


      1. equeim
        00.00.0000 00:00
        +3

        Я дочитал до интерполяции строк...


    1. s207883
      00.00.0000 00:00

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


    1. Dmitry_Dor
      00.00.0000 00:00
      +4

      это первоапрельский пост?… «имени Трофима Лысенко» сильно озадачило
      В каждой шутке есть доля шутки ???? — habr.com/ru/post/725468 ????
      /confused


    1. AndronNSK
      00.00.0000 00:00
      +4

      Нет, сегодня же 32.03.2023.


  1. acordell
    00.00.0000 00:00
    +2

    Спасибо, развлекли! Perosn только стоит поправить.


    1. Pastoral
      00.00.0000 00:00
      +9

      В смысле научить компилятор при виде неизвестного идентификатора получать известный перестановкой букв? Конечно стоит!


  1. AlexXYZ
    00.00.0000 00:00
    +2

    Никто не обратил внимание на замену символов начала однострочного комментария??? :D

    C первым апреля!!!


    1. 0Bannon
      00.00.0000 00:00
      +4

      Фу, отлегло


    1. vlivyur
      00.00.0000 00:00

      А мне понравилось.Только надо б сократить до \/\
      Кажется раньше у VS было что-то похожее в логотипе


      1. Proydemte
        00.00.0000 00:00
        +1

        \/\/


        это вообще то сиськи, как бы странно было сиськи заменять на какие-то \/\


        1. vlivyur
          00.00.0000 00:00

          Все знают как они выглядят (.)(.)


          1. Proydemte
            00.00.0000 00:00

            У кого как… у кого как ...


        1. MichaelSkirda Автор
          00.00.0000 00:00

          Как же я сам не додумался до этого, было бы еще лучше.


  1. whoisking
    00.00.0000 00:00
    +6

    Супер, понравились новые фишки C#, пожалуй, даже брошу свой петон ради них. Но больше всего зашла шутка про гражданство, на этом моменте я ещё думал что это просто совпадение)


  1. Morriarte
    00.00.0000 00:00
    +7

    Ёмае, а я ведь поверил и дочитал с фэйспалмом...


  1. lil_master
    00.00.0000 00:00
    +6

    i// эквивалентно i = i / 1
    i** эквивалентно i = i * 1

    Вау, это гениально!

    i00 эквивалентно i = i + 0; очень не хватает) добавьте ровно через год


  1. DikSoft
    00.00.0000 00:00
    +11

    Это лучший пост в честь 1 апреля!


  1. d_ilyich
    00.00.0000 00:00
    +7

    Надеюсь, через год добавят наконец возможность писать


    if ( 1 <= x < 4 ) ...
    // и/или даже
    if ( x in [1, 4) ) ...

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


    if ( 1 <= x && x < 4 )

    :)


    1. NN1
      00.00.0000 00:00
      +5

      Так уже можно: `x is >= 1 and < 4`


      1. d_ilyich
        00.00.0000 00:00

        Это же ещё длиннее!


        1. NN1
          00.00.0000 00:00
          +1

          Так вы имя переменной дайте нормальное и сразу будет короче.


  1. Starche
    00.00.0000 00:00
    +16

    В версии .NET XI (.NET 11) обещают также ввести поддержку символа £.

    Думаю, вы что-то перепутали. В версии .NET XI должна появиться поддержка ¥


  1. Helltraitor
    00.00.0000 00:00
    +3

    .NET 10 будет последней версией и останется с нами навсегда


  1. Magnetiq
    00.00.0000 00:00
    +5

    Если честно - эта пять! ???? Как водится, проскользил взглядом вступление (бла-бла, давайте к телу), на серьезных шах кивнул на "У нас так принято". На первом же 'нововведении' с классами решил что опечатка, полез в комменты, ну и немного подпортил себе сюрприз... ????


    1. Markscheider
      00.00.0000 00:00
      +1

      Как водится, проскользил взглядом вступление (бла-бла, давайте к телу)

      Сколько людей - столько мнений. Я не погроммист, поэтому содержательную часть не смог оценить критически. А вот на вступление как раз триггернулся :)


  1. St_Rus
    00.00.0000 00:00

    var man1 = new("Mike", 32);

    вот тут не пойму: а как там понимается, что это именно тот самый объект, не какой-то другой?! что это, к примеру, Person, а не Car? ну а вообще, очень даже классно, сильно ускоряет работу


    1. nagayev
      00.00.0000 00:00
      +8

      С 1 апреля!


    1. whoisking
      00.00.0000 00:00
      +8

      Новейший инференс с ChatGPT под капотом


    1. 0xd34df00d
      00.00.0000 00:00

      Вполне могут быть системы типов, где это на самом деле не проблема. Конкретный тип выведется дальше по контексту, либо, с row polymorphism, даже это не нужно — достаточно полиморфизма по полям.


  1. rootdefault
    00.00.0000 00:00
    +7

    Забыл что сегодня первое апреля, по 5 раз перечитывал новый синтаксис, думал всё, доработался к вечеру…


  1. darkinsideus
    00.00.0000 00:00
    +1

    Спасибо, это было забавно)


  1. ShutovKS
    00.00.0000 00:00
    +2

    Отличный пост на 1 апреля. Я сначала даже поверил


  1. MichaelSkirda Автор
    00.00.0000 00:00
    +2

    Кстати, про создание экземпляров абстрактных классов в .NET 5 и .NET Core 3.1 это не шутка, через reflection их можно было создать.


  1. usego
    00.00.0000 00:00
    +4

    Блин. Вот каждый раз даю себе слово, что на первое апреля не разведут, и на тебе. На полном серьёзе пытался осознать, как вот это var man1 = new("Mike", 32); может работать на уровне компилятора.


    1. a-tk
      00.00.0000 00:00

      В F# работает...


    1. Myxach
      00.00.0000 00:00

      Допустим в лоб - перебрать все классы, которые не скрыты namespace'ом. Правда это будет работать только для уникальных наборов аргуменов и фиг знает сколько времени надо


      1. MichaelSkirda Автор
        00.00.0000 00:00

        O(N)


  1. kaatula
    00.00.0000 00:00
    +4

    Спасибо, купился)

    Дошло только на знаке €

    Ждём .NET 30, или, как его начнут называть...


    1. Deosis
      00.00.0000 00:00
      +1

      То есть, вас не смутило сокращенное деление на 1? i//


      1. MichaelSkirda Автор
        00.00.0000 00:00

        Просто это улучшенный NOP


      1. kaatula
        00.00.0000 00:00

        Неа

        Я подумал, что это наверное отличный способ отбросить дробную часть от числа)

        Правда, в БЧ с комментариями я не поверил, но решил, что что-то не так понял.


  1. Ioanna
    00.00.0000 00:00
    +4

    Только на экранировании комментариев вспомнила, какой вчера был день.


  1. zfima
    00.00.0000 00:00
    +2

    Я гражданин Ирана, Израиля и Народной Республики Майя и у меня вопрос: почему в новой версии .NET XI не разрешили делить объект на 0? Например, на COBOL мы так всегда делаем.


  1. middle
    00.00.0000 00:00

    В расте это всё есть давным-давно.


    1. BASic_37
      00.00.0000 00:00

      Сочувствую... )


      1. middle
        00.00.0000 00:00

        А кому сейчас легко?


  1. donRumatta
    00.00.0000 00:00

    Просто топовый пост, до евро еще верил, но копил вопросы для комментов(= Очень жаль, что сюда зашли и порадовались только шарперы, может заголовок бы более общий(=