TGViewer
.NET Разработчик .NET Разработчик @netdeveloperdiary · 6.74K subscribers
Post #2453 2.61K
День 2028. #ЧтоНовенького #CSharp13
Альтернативный Доступ к Коллекциям

До C#13 ref-структуры не могли быть аргументами параметра-типа в обобщённых типах. Теперь в объявление обобщённого типа после ключевого слова where добавлено «анти-ограничение» allows ref struct, которое сообщает, что аргументом для параметра типа может быть ref-структура. Анти-ограничение оно, потому что по факту оно не ограничивает возможный набор параметров типа, а расширяет его. Это анти-ограничение налагает все доступные для ref-структур правила (вроде запрета размещения в куче) на все экземпляры параметра-типа. Смысл этого изменения также в том, чтобы можно было использовать типы Span в обобщённых-алгоритмах.

Например, таблицы поиска (lookup-таблицы) типа Dictionary<TKey,TValue> и HashSet<T> часто используются в качестве своего рода кэша. Однако, так как ключи таблиц обычно строкового типа, раньше приходилось выделять строку, чтобы обратиться в lookup-таблицу по ключу. Теперь упомянутое выше «анти-ограничение» добавляет новые возможности для этих типов коллекций.

Следующий код считает количество различных слов в тексте, используя так называемые альтернативные ключи словаря:
static Dictionary<string, int> 
CountWords(ReadOnlySpan<char> input)
{
Dictionary<string, int> counts =
new(StringComparer.OrdinalIgnoreCase);

Dictionary<string, int>.AlternateLookup<ReadOnlySpan<char>>
lookup = counts.GetAlternateLookup<string, int, ReadOnlySpan<char>>();

foreach (Range r in Regex.EnumerateSplits(input, @"\b\W+\b"))
{
ReadOnlySpan<char> word = input[r];
lookup[word] = lookup
.TryGetValue(word, out int count) ? count + 1 : 1;
}

return counts;
}

Сначала мы создаём lookup-словарь counts и указываем, что нам не важен регистр ключей.
Затем, чтобы искать в словаре по spanам, а не по строкам, мы создаём структуру lookup для альтернативного доступа к элементам. Здесь она вот такого длинного типа Dictionary<string, int>.AlternateLookup<ReadOnlySpan<char>>. В примере указан тип полностью для демонстрации. В реальном коде это можно заменить на var. Заметьте, что тут используется обобщённый тип AlternateLookup с параметром типа виде ref-структуры ReadOnlySpan<char>.
Далее мы разбиваем текст по «не-словам», используя Regex.EnumerateSplits. В результате получаем перечислитель диапазонов результатов. С его помощью мы делаем срезы исходного текста, которые представляют собой отдельные слова. Это переменная word типа ReadOnlySpan<char>. И вот здесь, чтобы не создавать строк для доступа в словарь counts по строковому ключу, нам и потребуется структура lookup, которая обеспечит доступ к словарю по альтернативному ключу типа ReadOnlySpan<char>. В данном случае мы увеличиваем счётчик для текущего слова.

Теперь мы можем взять текст и посчитать в нём слова:
var text = "<какой-то длинный текст>";
foreach (var word in CountWords(text))
Console.WriteLine(word);


Источник: https://learn.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-13
  • 👍 20
More from @netdeveloperdiary
  1. Sep 26, 2026День 2796. #ЗаметкиНаПолях #AI Рабочий процесс с Copilot для .NET. Продолжение Начало Три…
  2. Sep 25, 2026День 2795. #ЗаметкиНаПолях #AI Рабочий процесс с Copilot для .NET. Начало Проблема с позиц…
  3. Sep 24, 2026День 2794. #Оффтоп #Здоровье Сегодня будет необычный пост. Завтра в Москве стартует конфер…
  4. Sep 23, 2026День 2793. #ЗаметкиНаПолях #SQL 10 Редких Возможностей SQL, Которые Стоит Знать Каждому. Ч…
  5. Sep 22, 2026День 2792. #ЗаметкиНаПолях #SQL 10 Редких Возможностей SQL, Которые Стоит Знать Каждому. Ч…
  6. Sep 21, 2026🔍Тестовое собеседование с Senior C# разработчиком уже завтра 22 сентября(уже завтра!) в 1…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →