Posted on 6. June 2024

Рефакторинг коду з використанням псевдонімів будь-якого типу

Рефакторинг коду з використанням псевдонімів будь-якого типу

Ця стаття є третьою в серії з чотирьох частин, в яких ми розглянемо різні можливості C# 12. У цій частині ми зануримося у функцію «псевдонім будь-якого типу», яка дозволяє створювати псевдонім для будь-якого типу за допомогою директиви using. Ця серія статей дійсно починає набувати гарних рис:


  1. Рефакторинг вашого C# коду за допомогою первинних конструкторів

  2. Рефакторинг вашого C# коду за допомогою виразів колекцій

  3. Рефакторинг C# коду за допомогою псевдонімів для будь-яких типів (ця стаття)

  4. Рефакторинг вашого C# коду для використання лямбда-параметрів за замовчуванням

 

Всі ці можливості продовжують наш шлях до того, щоб зробити наш код більш читабельним і зручним для супроводу, і вважаються «повсякденними можливостями C#», які повинні знати розробники. Давайте зануримося!

Псевдонім будь-якого типу *️⃣

У C# 12 з’явилася можливість псевдонімізувати будь-який тип за допомогою директиви using. Ця функція дозволяє вказувати псевдоніми, які відображаються на інші типи. Це стосується типів кортежів, вказівників, масивів і навіть не відкритих узагальнених типів, і всі вони будуть доступні у вашому коді. Ця можливість є особливо корисною:


  • При роботі з довгими або складними іменами типів.

  • Коли вам потрібно розмежувати типи і вирішити потенційні конфлікти імен.

  • При визначенні типів кортежів значень, які ви маєте намір спільно використовувати у збірці.

  • Коли ви хочете додати ясності до вашого коду, використовуючи більш описові імена.

Офіційна документація C# містить багато прикладів використання цієї можливості, але замість того, щоб повторювати ці приклади тут, я вирішив написати демонстраційну програму, яка ілюструє різні аспекти цієї можливості.

Типи посилань з нульовим значенням

_________________________________________________________________________

 

Ця функція підтримує більшість типів, за єдиним винятком типів посилань, які можна обнулити. Тобто, ви не можете створити псевдонім для nullable reference type, і компілятор C# повідомить про помилку CS9132: Using alias cannot be a nullable reference type. Наступні біти були вилучені зі специфікації функції, щоб допомогти прояснити цей момент:

Зразок додатку: Спостереження НЛО 🛸 

Демонстраційний додаток доступний на GitHub за адресою IEvangelist/alias-any-type. Це простий консольний додаток, який імітує спостереження за непізнаними літаючими об’єктами (НЛО). Якщо ви хочете приєднатися до нього локально, ви можете зробити це будь-яким з наведених нижче способів у робочій директорії на ваш вибір:

За допомогою Git CLI:

git clone https://github.com/IEvangelist/alias-any-type.git


За допомогою GitHub CLI:

gh repo clone IEvangelist/alias-any-type

Завантажте zip-файл:


Якщо ви бажаєте завантажити вихідний код, zip-файл доступний за наступною URL-адресою:

Щоб запустити програму, з кореневого каталогу виконайте наступну команду .NET CLI:

dotnet run —project ./src/Alias.AnyType.csproj


Коли програма запускається, вона друкує вступ до консолі і чекає на введення даних користувачем, перш ніж продовжити роботу.


Після натискання будь-якої клавіші, наприклад, клавіші Enter, програма випадковим чином генерує дійсні координати (широту і довготу), а потім, використовуючи ці координати, отримує метадані геокоду, пов’язані з координатами. Координати представлені у форматі градусів-хвилин-секунд (включаючи кардинальність). Під час роботи програми обчислюються відстані між згенерованими координатами, які подаються як спостереження НЛО.



Щоб зупинити програму, натисніть клавіші Ctrl + C.


Хоча цей додаток простий, він включає в себе інші частини C#, які не обов’язково мають відношення до нашої теми в цій статті. Я намагатимусь не зачіпати периферійні теми, але торкатимусь їх, коли вважатиму їх важливими.

Покрокове ознайомлення з кодом 👀

 

Ми використаємо цей розділ, щоб разом пройтися по коду. Є кілька цікавих аспектів коду, які я хотів би висвітлити, включаючи файл проекту, GlobalUsings.cs, деякі розширення та файл Program.cs. З наявного коду є кілька речей, які ми не будемо розглядати, наприклад, моделі реагування та деякі утилітарні методи.


Почнемо з розгляду файлу проекту:
Перше, на що слід звернути увагу, це те, що властивість ImplicitUsings має значення enable. Ця властивість з’явилася у C# 10 і дозволяє цільовому SDK (у цьому випадку Microsoft.NET.Sdk) неявно включати набір просторів імен за замовчуванням. Різні SDK включають різні простори імен за замовчуванням, для отримання додаткової інформації див. документацію про неявне використання директив.

Директиви неявного використання 📜


Елемент ImplicitUsing є особливістю MS Build, тоді як ключове слово global є особливістю мови C#. Оскільки ми обрали глобальне використання, ми також можемо скористатися цією можливістю, додавши наші власні директиви. Одним із способів додавання цих директив є додавання елементів Using у групу ItemGroup. Деякі директиви використання додаються з атрибутом Static, встановленим у true, що означає, що всі їхні static члени доступні без обмежень – докладніше про це пізніше. Атрибут Alias використовується для створення псевдоніма для типу, у цьому прикладі ми вказали псевдонім AsyncCancelable для типу System.Runtime.CompilerServices.EnumeratorCancellationAttribute. У нашому коді тепер ми можемо використовувати AsyncCancelable як псевдонім типу для атрибуту EnumeratorCancellation. Інші елементи Using створюють нестатичні та неалієсовані директиви global using для відповідних просторів імен.

 

Закономірність, що з’являється 🧩 

 

Ми починаємо спостерігати, як у сучасних кодових базах .NET з’являється загальний шаблон, коли розробники визначають файл GlobalUsings.cs для інкапсуляції всіх (або більшості) директив використання в одному файлі. Ця демонстраційна програма слідує цьому шаблону, давайте подивимось на файл далі:


Все у цьому файлі є директивою global using, що робить типи псевдонімів, статичні члени або простори імен доступними у всьому проекті. Перші три директиви призначені для загальних просторів імен, які використовуються у багатьох місцях програми. Наступна директива – це директива global using static для простору імен System.Math, яка робить всі статичні члени Math доступними без обмежень. Решта директив – це директиви global using, які створюють псевдоніми для різних типів, включаючи кілька кортежів, потік координат і CancellationTokenSource, на яке тепер можна просто посилатися через Signal.


Варто врахувати, що коли ви визначаєте тип псевдоніма кортежу, ви можете легко перейти до типу record, якщо вам потрібно додати поведінку або додаткові властивості. Наприклад, пізніше ви можете вирішити, що дійсно хочете додати деяку функціональність до типу Coordinates, ви можете легко змінити його на тип record:


 

Коли ви визначаєте псевдонім, ви фактично створюєте не тип, а ім’я, яке посилається на існуючий тип. У випадку визначення кортежів, ви визначаєте форму кортежу значень. Коли ви називаєте тип масиву псевдонімом, ви не створюєте новий тип масиву, а скоріше називаєте його псевдонімом, можливо, з більш описовою назвою. Наприклад, коли я визначаю API, який повертає IAsyncEnumerable, це дуже багато для написання. Натомість тепер я можу посилатися на тип, що повертається, як CoordinateStream у своїй кодовій базі.

Посилання на псевдоніми 📚

 

Було визначено декілька псевдонімів, деякі у файлі проекту, а інші у файлі GlobalUsings.cs. Давайте подивимося, як ці псевдоніми використовуються у коді. Почнемо з розгляду файлу верхнього рівня Program.cs:

 

У попередньому фрагменті коду показано, як псевдонім Signal використовується для створення екземпляру CancellationTokenSource. Як ви знаєте, клас CancellationTokenSource є реалізацією IDisposable, тому ми можемо використовувати інструкцію using, щоб гарантувати, що екземпляр Signal буде належним чином утилізовано, коли він вийде за межі області видимості. Ваша IDE розуміє ці псевдоніми, і коли ви наведете на них курсор, ви побачите фактичний тип, який вони представляють. Погляньте на наступний знімок екрана:


Вступ записується на консоль з виклику WriteIntroduction, безпосередньо перед входом в try / catch. Блок try містить цикл await foreach, який перебирає IAsyncEnumerable. Метод GetCoordinateStreamAsync визначено в окремому файлі. Я частіше використовую функціональність partial class, коли пишу програми верхнього рівня, оскільки це допомагає ізолювати проблеми. Уся функціональність, що базується на HTTP, визначена у файлі Program.Http.cs, давайте зосередимося на методі GetCoordinateStreamAsync:


 

Ви помітите, що він повертає псевдонім CoordinateStream, який є IAsyncEnumerable. Він приймає атрибут AsyncCancelable, який є псевдонімом для типу EnumeratorCancellationAttribute. Цей атрибут використовується для оформлення маркера скасування таким чином, щоб він використовувався разом з IAsyncEnumerable для підтримки скасування. Поки скасування не запитується, метод генерує випадкові координати, отримує метадані геокоду і повертає новий екземпляр CoordinateGeoCodePair. Метод GetGeocodeAsync запитує метадані геокоду для заданих координат, і у разі успіху повертає модель відповіді GeoCode. Наприклад, Microsoft Campus має такі координати:

Щоб переглянути JSON, відкрийте це посилання у вашому браузері. Тип CoordinateGeoCodePair не є псевдонімом, але це readonly record struct, яка містить Coordinates та GeoCode:

Повертаючись до класу Program, коли ми повторюємо кожну пару координати-геокод, ми деконструюємо кортеж на екземпляри типу Coordinates і GeoCode. Тип Coordinates є псевдонімом для кортежу з двох double значень, що представляють широту і довготу. Знову ж таки, наведіть курсор на цей тип у вашому IDE, щоб швидко побачити тип, подивіться на наступний знімок екрана:


Тип GeoCode  - це модель відповіді, яка містить інформацію про метадані геокоду. Потім ми використовуємо метод розширення, щоб перетворити Coordinates в кардиналізований рядок, який є рядковим представленням координат у форматі градусів-хвилин-секунд. Особисто мені подобається, як легко використовувати псевдоніми у вашій кодовій базі. Давайте розглянемо деякі методи розширення, які розширюють або повертають псевдонімні типи:

 

 

Цей метод розширення розширює тип псевдоніма Coordinates і повертає рядкове представлення координат. Він використовує метод розширення ToDMS для перетворення широти і довготи у формат градусів-хвилин-секунд. Метод розширення ToDMS визначається наступним чином:

Якщо ви пам’ятаєте, псевдонім DMS – це кортеж з трьох значень, що представляють градуси, хвилини та секунди. Метод розширення ToDMS приймає значення double і повертає кортеж DMS. Метод розширення ToCardinal використовується для визначення кардинального напрямку координат і повертає значення N, S, E або W. Методи Abs, Sign і Floor є статичними членами простору імен System.Math, псевдонім якого міститься у файлі GlobalUsings.cs.


Крім того, програма відображає деталі спостереження НЛО на консолі, включаючи координати, метадані геокоду та відстань, пройдену між спостереженнями. Це відбувається постійно, доки користувач не зупинить програму комбінацією клавіш Ctrl + C.

Наступні кроки 🚀

Не забудьте спробувати це у своєму власному коді! Поверніться до останньої частини цієї серії статей, де ми розглянемо параметри лямбда за замовчуванням. Щоб продовжити дізнаватися більше про цю функцію, відвідайте наступні ресурси:

 




Posted on 17. November 2023

Announcing C# 12

Анонс C# 12

C# 12 доступний вже сьогодні! Ви можете отримати його, завантаживши .NET 8, останню версію Visual Studio або C# Dev Kit від Visual Studio Code.


Для існуючих проектів вам також потрібно вказати, що ви хочете змінити мовну версію. Ви можете змінити мовну версію, змінивши TargetFramework на .NET 8:

C# 12 підвищує продуктивність розробників завдяки спрощеному синтаксису та пришвидшенню виконання. Ви можете ознайомитися з подробицями про кожну функцію в статті Що нового в C# 12 на MS Learn. Стаття “Що нового” містить посилання на оновлення документації по C# на MS Learn, які відображають нові можливості.


Спрощення коду

Кожна версія C# допомагає вам писати кращий код – простіший код, який краще виражає ваші наміри. У порівнянні з кодом, який ви писали раніше, новий підхід працює так само швидко або швидше і займає стільки ж або менше ресурсів. Ви можете з упевненістю застосовувати ці нові функції. Однією з цілей проектування нових можливостей є забезпечення того, щоб використання нової можливості не погіршувало продуктивність.


У C# 12 введено вирази колекцій, первинні конструктори для всіх класів і структур, синтаксис для псевдонімів будь-якого типу та параметри за замовчуванням для лямбда-виразів, які спрощують ваш код.

Вирази колекцій

 

До C# 12 створення колекцій вимагало різного синтаксису для різних сценаріїв. Ініціалізація List вимагала іншого синтаксису, ніж int[] або Span. Ось лише декілька способів створення колекцій:

Вирази колекцій мають уніфікований синтаксис:

Ви не тільки можете використовувати єдиний синтаксис, але й компілятор створює для вас швидкий код. У багатьох випадках компілятор встановлює ємність колекції та уникає копіювання даних.


А якщо цього виявиться недостатньо – ви можете використовувати оператор new spread для включення елементів однієї або декількох колекцій або перечислювальних виразів у вираз колекції:

Реалізація будь-якого виразу поширення оптимізована і часто буде кращою, ніж код, який ви могли б написати для об’єднання колекцій.


Ми дуже зацікавлені у відгуках щодо можливої майбутньої роботи над виразами колекцій. Ми розглядаємо можливість розширення виразів колекцій за рахунок словників та підтримки var (природних типів) у майбутній версії C#.


Як і багато інших нових можливостей C#, аналізатори можуть допомогти вам перевірити нову функцію та оновити ваш код:

Дізнайтеся більше про вирази збору у цій статті на MS Learn.


Первинні конструктори для будь-якого класу або структури

 

У C# 12 розширено можливості первинних конструкторів для роботи з усіма класами та структурами, а не лише із записами. Первинні конструктори дозволяють вам визначати параметри конструктора під час оголошення класу:

Найпоширеніші способи використання первинного параметра конструктора


  • Як аргумент для виклику конструктора base().

  • Для ініціалізації поля або властивості члена.

  • Посилання на параметр конструктора у члені екземпляру.

  • Для усунення шаблонів при ін’єкції залежностей.


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


Ви можете додавати первинні конструктори до будь-якого типу: class, struct, record class та record struct. Параметри первинних конструкторів у class і struct є доступними для всього визначення class або struct. Ви можете використовувати параметри для ініціалізації полів або властивостей, або в тілі інших членів. При використанні з типами record компілятор генерує загальнодоступну властивість для кожного первинного параметра конструктора. Ці властивості є лише одними з багатьох членів, які автоматично генеруються для типів record.


Ми дуже зацікавлені у відгуках щодо можливої майбутньої роботи над первинними конструкторами. Ми розглядаємо можливість дозволити вам позначати параметри первинних конструкторів як readonly і вказувати, що ви хочете створити загальнодоступну власність.


Дізнайтеся більше про первинні конструктори у цій статті. Щоб дізнатися більше про використання первинних конструкторів для записів і не-записів, перегляньте Підручник: Вивчення первинних конструкторів.


Псевдонім будь-якого типу

 

Псевдонімизація типів – це зручний спосіб прибрати складні сигнатури типів з вашого коду. Починаючи з C# 12, у директивах alias можна using додаткові типи. Наприклад, у більш ранніх версіях C# ці псевдоніми не працюють:



Ви можете ознайомитися зі специфікацією директиви Allow using alias, яка дозволяє посилатися на будь-який тип для using псевдонімів з вказівниками та небезпечними типами.


Як і інші псевдоніми, ці типи можна using у верхній частині файлу та у global using операторах.


Дізнайтеся більше про псевдонім будь-якого типу у цій статті.


Лямбда-параметри за замовчуванням

Починаючи з C# 12, у лямбда-виразах можна оголошувати параметри за замовчуванням:

Лямбда-параметри за замовчуванням дозволяють викликаючому коду пропускати значення, що передаються, і додавати параметри до існуючих лямбда-виразів, не вносячи змін у викликаючий код. Це спрощує доступ до лямбда-виразів так само, як параметри за замовчуванням у методах спрощують виклик методів.


Дізнайтеся більше про лямбда-параметри за замовчуванням у цій статті.


Прискорюємо ваш код

Ми продовжуємо вдосконалювати ваші можливості роботи з необробленою пам’яттю, щоб підвищити продуктивність додатків.


Покращення продуктивності, які ми зробили в C# за ці роки, важливі незалежно від того, чи використовуєте ви їх безпосередньо, чи ні. Більшість додатків працюють швидше, тому що середовище виконання .NET та інші бібліотеки використовують ці покращення. Звичайно, якщо ваш додаток використовує буфери пам’яті у гарячих шляхах, ви також можете скористатися цими можливостями. Вони зроблять вашу програму набагато швидшою.


У C# 12 ми додали параметри ref readonly та вбудовані масиви.


параметри ref readonly

Додавання параметрів ref readonly забезпечує остаточну комбінацію передачі параметрів за посиланням або за значенням. Аргумент параметра ref readonly повинен бути змінною. Подібно до аргументів ref та out, аргумент не повинен бути буквальним значенням або константою. Буквальний аргумент генерує попередження і компілятор створює тимчасову змінну. Як і in параметрах, параметр ref readonly не може бути змінений. Метод повинен оголошувати параметри ref readonly, якщо він не буде змінювати аргумент, але потребує його ділянку пам’яті.


Дізнайтеся більше про параметри ref readonly у цій статті.


вбудовані масиви

Інлайн-масиви забезпечують безпечний спосіб роботи з буферами пам’яті. Інлайн-масив – це тип масиву фіксованої довжини, заснований на структурі. Раніше ви могли маніпулювати блоком пам’яті за допомогою стекового сховища або вказівників. Але ці методи вимагали, щоб ваша збірка включала небезпечний код. Коли вашій програмі потрібно працювати з блоком пам’яті для зберігання масиву структур, ви можете оголосити вбудований тип масиву. Цей тип представляє собою масив фіксованого розміру. Ви можете використовувати їх у безпечному коді та покращити продуктивність програми при маніпулюванні буферами.


Дізнайтеся більше про вбудовані масиви у цій статті.


Допомагають нам працювати швидше

Час від часу ми додаємо функції до C# в якості експериментів або для того, щоб зробити розробку C# або .NET більш ефективною. У C# 12 з’явилися дві такі можливості: експериментальний атрибут та перехоплювачі.


Атрибут експериментальності

Іноді ми розміщуємо функції у випущених версіях .NET або C#, тому що ми хочемо отримати зворотній зв’язок або функція не може бути завершена за один цикл. У цих випадках ми хочемо дати зрозуміти, що ми ще не взяли на себе зобов’язань щодо цієї функції або її реалізації. Ми додали атрибут System.Diagnostics.CodeAnalysis.ExperimentalAttribute, щоб краще пояснити, коли це відбувається.


Коли код використовує експериментальні типи або члени, виникне помилка, якщо викликаючий код також не позначено як експериментальний. Кожне використання ExperimentalAttribute містить діагностичний ідентифікатор, який дозволяє приховати помилку для окремих експериментальних можливостей за допомогою явної опції компілятора або #pragma, щоб ви могли дослідити експериментальну можливість.


Типи, члени та збірки можуть бути позначені атрибутом ExperimentalAttribute. Якщо тип позначено як експериментальний, усі його члени вважаються експериментальними. Якщо збірку або модуль позначено як експериментальну, всі типи, що входять до неї, вважаються експериментальними.


Ми наполегливо рекомендуємо авторам бібліотек, які мають залежності від будь-чого з атрибутом Experimental, також позначати весь код, що використовує цей атрибут, атрибутом ExperimentalAttribute. Ми також заохочуємо авторів бібліотек використовувати атрибут ExperimentalAttribute, якщо у їхніх бібліотеках є експериментальні можливості.


Дізнайтеся більше про атрибут експериментальний у цій статті.


Перехоплювачі

Перехоплювачі є експериментальною можливістю, доступною у режимі попереднього перегляду у C# 12. Ця функція може бути змінена або вилучена у майбутньому випуску. Тому її не рекомендується використовувати у виробничих або випущених програмах. Якщо ви використовуєте перехоплювачі, позначте вашу бібліотеку атрибутом ExperimentalAttribute.


Перехоплювачі дозволяють перенаправляти виклики методів. Наприклад, це дозволить оптимізованій версії методу, згенерованій для конкретних параметрів, замінити менш ефективний узагальнений метод.


Якщо вам цікаво, ви можете дізнатися більше про перехоплювачі, прочитавши специфікацію перехоплювачів.


Наступні кроки

C# 12 – це лише частина захоплюючого випуску .NET 8. Ви можете дізнатися про інші можливості в блозі про .NET 8.


Завантажуйте .NET 8, Visual Studio 2022 17.8 і знайомтеся з C# 12!

 

Source






Posted on 20. July 2023

New C# 12 preview features

Нові можливості C# 12 preview

Visual Studio 17.7 Preview 3 та .NET 8 Preview 6 продовжують розвиток C# 12. Ця попередня версія включає функції, призначені для створення фундаменту для покращення продуктивності в майбутньому. Простий доступ до вбудованих масивів дозволить бібліотекам використовувати їх у більшій кількості програм без зайвих зусиль з вашого боку. У цій попередній версії дебютує експериментальна функція перехоплення, яка дозволяє генераторам перенаправляти код, наприклад, для забезпечення контекстно-залежної оптимізації.Нарешті, розширено можливості роботи функції nameof.

Ви можете отримати C# 12, встановивши останню попередню версію Visual Studio або останню версію .NET SDK. Щоб ознайомитися з можливостями C# 12, вам потрібно встановити мовну версію вашого проєкту на preview:

Оскільки перехоплювачі є експериментальними, вони потребують додаткового позначення у файлі проєкту.

nameof – доступ до елементів екземпляра

 

Відтепер ключове слово nameof працює з іменами елементів, включно з початковими значеннями, статичними елементами та атрибутами:

Ви можете дізнатися більше в статті Що нового в C# 12.

Вбудовані масиви

Атрибут InlineArrayAttribute був представлений у середовищі виконання у попередньому випуску .NET 8. Це розширена функція, яка буде використовуватися переважно компілятором, бібліотеками .NET та деякими іншими бібліотеками. Атрибут ідентифікує тип, який можна розглядати як безперервну послідовність примітивів для ефективних, безпечних за типом, захищених від перевиконання індексованих/зрізаних вбудованих даних. Бібліотеки .NET підвищують продуктивність ваших програм та інструментів, що використовують вбудовані масиви.

Компілятор створює різні IL для доступу до вбудованих масивів. Це призводить до деяких обмежень, наприклад, не підтримуються шаблони списків. У більшості випадків доступ до вбудованих масивів здійснюється так само, як і до інших масивів. Різні IL дають приріст продуктивності без зміни коду:

Більшість людей використовують вбудовані масиви, а не створюють їх. Але корисно розуміти, як це працює. Інтегровані масиви швидкі, тому що вони покладаються на точний план заданої довжини. Вбудований масив – це тип з одним полем, позначений атрибутом InlineArrayAttribute, який вказує довжину масиву. У типі, що використовувався у попередньому прикладі, завдяки параметру атрибута програма створює сховище рівно для десяти елементів у Buffer10:

Більше інформації в статті Що нового в C# 12.

Перехоплювачі

У цій версії представлено експериментальну можливість, яка називається interceptors (перехоплювачі). Вона призначена для розширених сценаріїв, зокрема для покращення випереджувальної компіляції (AOT). Як експериментальна частина .NET 8, вона може бути змінена або вилучена у майбутній версії. Таким чином, його не слід використовувати у продакшені.

Перехоплювачі дозволяють перенаправляти виклики певних методів до іншого коду. Атрибути визначають фактичне місцеперебування вихідного коду, тому перехоплювачі зазвичай підходять лише для генераторів коду. Ви можете прочитати статтю-пропозицію про перехоплювачі, щоб дізнатися більше про те, як вони працюють.

Оскільки перехоплювачі є експериментальною можливістю, вам потрібно буде явно увімкнути їх у файлі проєкту:

Перехоплювачі дозволяють створювати цікаві шаблони коду. Ось кілька прикладів:

Виклики, відомі під час компіляції, такі як Regex.IsMatch(@“a+b+”) з постійним шаблоном, можуть бути перехоплені, щоб використовувати статично згенерований код для оптимізації, сприятливої до AOT.

ASP.NET Мінімальні виклики API, такі як app.MapGet(“/products”, handler: (int? page, int? pageLength, MyDb db) => { … }) можна перехопити, щоб зареєструвати статично згенеровану thunk, яка викликає користувацький обробник напряму, минаючи виділення та індексацію.

У векторизації, де цикли foreach містять виклики користувацьких методів, компілятор може переписати код, щоб перевірити та використати відповідні властивості під час виконання, але повернутися до початкового коду, якщо ці властивості недоступні.

Статична роздільна здатність графів залежностей для впровадження залежностей, де provider.Register() може бути перехоплений.

Виклики до провайдерів запитів можна перехоплювати, щоб запропонувати переклад на іншу мову (наприклад, SQL) під час компіляції, замість того, щоб обчислювати дерева виразів для перекладу під час виконання.

Serializers (серіалізатори) можуть генерувати специфічну для типу (де)серіалізацію на основі конкретного типу викликів, таких як Serialize(), і все це під час компіляції.

Більшість програмістів не будуть використовувати перехоплювачі безпосередньо, але в будь-якому випадку вони відіграватимуть важливу роль у прагненні зробити ваші програми швидшими та простішими у розгортанні. Очікується, що перехоплювачі залишаться експериментальними у версії C# 12/.NET 8 і можуть бути включені в наступну версію C#.

Підсумок

Ви можете знайти більше інформації про всі функції, представлені на цей час, на сторінці Що нового в C# 12 в Microsoft Learn, а також відстежувати розвиток функцій C# 12 на сторінці Roslyn Feature Status.

Ви можете перевірити найновіші можливості C# 12, завантаживши останню попередню версію Visual Studio або останню версію .NET SDK і встановивши LangVersion для preview у файлі вашого проєкту.