Превью Функции в .NET 6. Начало
В .NET 6 представлены несколько новых функций, пока в виде превью. Это значит, что они не поддерживаются для использования в производственной среде в .NET 6. Они пока выпущены для оценки сообществом и предоставления обратной связи относительно сценариев их использования и возможных улучшений.
Для использования этих новых функций добавлен новый атрибут
RequiresPreviewFeatures и соответствующий анализатор. Новые функции в стадии превью будут помечены этим атрибутом. Также им следует пометить все классы, использующие превью функции. Анализатор проверит наличие атрибута у потребителей превью функций и в случае его отсутствия, сборка завершится неудачей.1. Статические абстрактные члены интерфейсов
Как видно из названия, это означает, что теперь вы можете объявлять статические абстрактные методы как часть интерфейса и реализовывать их в производном типе. Простой, но мощный пример этого -
IParseable, который позволяет определять контракт парсинга строки для создания данного типа:public interface IParseable<TSelf>Особенности:
where TSelf : IParseable<TSelf> {
static abstract TSelf Parse(
string s,
IFormatProvider? provider);
static abstract bool TryParse(
[NotNullWhen(true)] string? s,
IFormatProvider? provider,
out TSelf result);
}
public readonly struct Guid : IParseable<Guid>
{
public static Guid Parse(
string s, IFormatProvider? provider)
{
/* Реализация */
}
public static bool TryParse(
[NotNullWhen(true)] string? s,
IFormatProvider? provider, out Guid result)
{
/* Реализация */
}
}
- Теперь вы можете объявлять элементы интерфейса, которые одновременно являются статическими и абстрактными.
- В настоящее время это не поддерживается для методов интерфейса с реализацией по умолчанию, поэтому сочетание
static virtual не является допустимой комбинацией.- Эта функциональность доступна только для интерфейсов, она недоступна для других типов, таких как абстрактный класс.
- Эти члены недоступны через интерфейс, то есть
IParseable<Guid>.Parse(someString, null) приведет к ошибке компиляции.Поясним последний пункт. Обычно абстрактные или виртуальные члены вызываются через какую-либо виртуальную диспетчеризацию (при полиморфном использовании). Для статических методов у нас нет объекта или экземпляра, поэтому среда выполнения не сможет определить, что
IParseable<Guid>.Parse(…) должно разрешиться в Guid.Parse. Чтобы это работало, нужно где-то указать фактический тип, и это можно сделать с помощью дженериков:public static T InvariantParse<T>(string s)В этом случае среда выполнения может определить, какой метод Parse следует разрешить, подсмотрев его на конкретном используемом
where T : IParseable<T>
{
return T.Parse(s, CultureInfo.InvariantCulture);
}
T. Если пользователь указал InvariantParse<int>(someString), он будет преобразован в метод Parse из System.Int32. А InvariantParse<Guid>(someString) будет преобразован в метод Parse из System.Guid и так далее.Более подробную информацию об изменениях среды выполнения, внесённых для поддержки этой функции, можно найти здесь.
Продолжение следует…
Источник: https://devblogs.microsoft.com/dotnet/preview-features-in-net-6-generic-math/