Заметка
Доступ к этой странице требует авторизации. Вы можете попробовать войти в систему или изменить каталог.
Доступ к этой странице требует авторизации. Вы можете попробовать сменить директорию.
Сопоставление шаблонов
Заметка
Эта статья является спецификацией компонентов. Спецификация служит проектным документом для функции. Она включает предлагаемые изменения спецификации, а также информацию, необходимую во время дизайна и разработки функции. Эти статьи публикуются до тех пор, пока предложенные изменения спецификации не будут завершены и включены в текущую спецификацию ECMA.
Может возникнуть некоторое несоответствие между спецификацией компонентов и завершенной реализацией. Эти различия зафиксированы в соответствующих заметках собраний по проектированию языка (LDM).
Дополнительные сведения о процессе внедрения спецификаций функций в стандарт языка C# см. в статье о спецификациях .
Вопрос чемпиона: https://github.com/dotnet/csharplang/issues/8640
Сводка
Разрешить совпадение шаблона для Span<char> и ReadOnlySpan<char> в константной строке.
Мотивация
Для производительности использование Span<char> и ReadOnlySpan<char> предпочтительнее по сравнению со строкой во многих сценариях. Платформа добавила множество новых API, которые позволяют использовать ReadOnlySpan<char> вместо string.
Распространенная операция со строками заключается в использовании переключателя для проверки того, является ли это определенное значение, и компилятор оптимизирует такой коммутатор. Однако в настоящее время нет возможности сделать то же самое на ReadOnlySpan<char> эффективно, кроме как путем ручной реализации переключения и оптимизации.
Чтобы поощрять внедрение ReadOnlySpan<char>, мы разрешаем сопоставление шаблонов ReadOnlySpan<char>на константном string, что также позволяет использовать его в коммутаторе.
static bool Is123(ReadOnlySpan<char> s)
{
return s is "123";
}
static bool IsABC(Span<char> s)
{
return s switch { "ABC" => true, _ => false };
}
Подробный дизайн
Мы изменим спецификации для постоянных шаблонов следующим образом (предлагаемое добавление отображается полужирным шрифтом):
Учитывая входное значение шаблона
eи константный шаблонPс преобразованным значениемv.
- Если e имеет целочисленный тип или тип перечисления, или пустую форму одного из них, а v имеет целочисленный тип, шаблон
Pсоответствует значению e, если результат выраженияe == vравенtrue; иначе- Если e имеет тип
System.Span<char>илиSystem.ReadOnlySpan<char>, а c является константной строкой, а c не имеет константного значенияnull, то шаблон считается совпадающим, еслиSystem.MemoryExtensions.SequenceEqual<char>(e, System.MemoryExtensions.AsSpan(c))возвращаетtrue.- Шаблон
Pсоответствует значению e, еслиobject.Equals(e, v)возвращаетtrue.
Известные члены
System.Span<T> и System.ReadOnlySpan<T> совпадают по имени, должны быть ref structи могут быть определены вне corelib.
System.MemoryExtensions совпадает по имени и может быть определён вне corelib.
Сигнатура перегрузки System.MemoryExtensions.SequenceEqual должна соответствовать.
public static bool SequenceEqual<T>(System.Span<T>, System.ReadOnlySpan<T>)public static bool SequenceEqual<T>(System.ReadOnlySpan<T>, System.ReadOnlySpan<T>)
Подпись System.MemoryExtensions.AsSpan должна соответствовать:
public static System.ReadOnlySpan<char> AsSpan(string)
Методы с необязательными параметрами исключаются из рассмотрения.
Недостатки
Никакой
Альтернативы
Никакой
Неразрешенные вопросы
Следует ли задавать сопоставление независимо от
MemoryExtensions.SequenceEqual()и т. д.?... Шаблон считается соответствующим, если
e.Length == c.Lengthиe[i] == c[i]для всех символов вe.Рекомендация: Определите в терминах
MemoryExtensions.SequenceEqual()для повышения производительности. ЕслиMemoryExtensionsотсутствует, сообщите об ошибке компиляции.Разрешить ли соответствие с
(string)null?Если да, следует ли
(string)nullподчинить"", так какMemoryExtensions.AsSpan(null) == MemoryExtensions.AsSpan("")?static bool IsEmpty(ReadOnlySpan<char> span) { return span switch { (string)null => true, // ok? "" => true, // error: unreachable? _ => false, }; }Рекомендация : о шаблоне
(string)nullследует сообщать как об ошибке.Следует ли включать проверку типа во время выполнения для значений выражения
Span<char>илиReadOnlySpan<char>в соответствие с константными шаблонами?static bool Is123<T>(Span<T> s) { return s is "123"; // test for Span<char>? } static bool IsABC<T>(Span<T> s) { return s is Span<char> and "ABC"; // ok? } static bool IsEmptyString<T>(T t) where T : ref struct { return t is ""; // test for ReadOnlySpan<char>, Span<char>, string? }Рекомендация. Неявный тест типа среды выполнения для постоянного шаблона. (
IsABC<T>()разрешено в примере, так как тест типа является явным.)Эта рекомендация не реализована. Все предыдущие примеры создают ошибку компилятора.
Должно ли подведение учитывать шаблоны строковых констант, шаблоны списков и шаблон свойства
Length?static int ToNum(ReadOnlySpan<char> s) { return s switch { { Length: 0 } => 0, "" => 1, // error: unreachable? ['A',..] => 2, "ABC" => 3, // error: unreachable? _ => 4, }; }Рекомендация: Использовать такое же поведение подстановки, как при значении выражения
string. (Это означает, что между константными строками, шаблонами списков иLengthнет отношений подстановки, кроме случая, когда[..]рассматривается как совпадающий с любым?)
Встречи по дизайну
C# feature specifications