Примечание
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Заметка
Эта статья является спецификацией компонентов. Спецификация служит проектным документом для функции. Она включает предлагаемые изменения спецификации, а также информацию, необходимую во время проектирования и разработки функции. Эти статьи публикуются до тех пор, пока предложенные изменения спецификации не будут завершены и включены в текущую спецификацию ECMA.
Может возникнуть некоторое несоответствие между спецификацией компонентов и завершенной реализацией. Эти различия фиксируются в соответствующем собрании по проектированию языка (LDM).
Дополнительные сведения о процессе внедрения спецификаций функций в стандарт языка C# см. в статье о спецификациях .
Проблема чемпиона: https://github.com/dotnet/csharplang/issues/124
Сводка
Когда универсальные шаблоны были введены в C# 2.0, классы атрибутов не были разрешены для участия. Мы можем сделать язык более компонуемым, удаляя это ограничение (скорее, ослабляя). Среда выполнения .NET Core добавила поддержку универсальных атрибутов. Теперь в компиляторе не хватает поддержки универсальных атрибутов.
Мотивация
В настоящее время авторы атрибутов могут принимать System.Type
в качестве параметра, а пользователи могут передавать typeof
выражение, чтобы предоставить атрибуту необходимые ему типы. Однако за пределами анализаторов нет способа ограничить автору атрибута, какие типы могут быть переданы атрибуту через typeof
. Если атрибуты могут быть универсальными, авторы атрибутов могут использовать существующую систему ограничений параметров типа для выражения требований к типам, которые они принимают в качестве входных данных.
Подробный дизайн
Следующий раздел изменен: §15.2.4.2
Прямой базовый класс типа класса не должен быть ни одного из следующих типов: System.Array, System.Delegate, System.MulticastDelegate, System.Enum или System.ValueType.
Более того, объявление универсального класса не может использовать System.Attribute в качестве прямого или косвенного базового класса.
Важно отметить, что следующий раздел спецификации не влияет на при ссылке на точку использования атрибута, т. е. в списке атрибутов: параметры типа — §8.5.
Параметр типа нельзя использовать в любом месте атрибута.
Это означает, что при использовании универсального атрибута его построение должно быть полностью закрытым, т. е. не содержит параметров типа, что означает, что следующее по-прежнему запрещено:
using System;
using System.Collections.Generic;
public class Attr<T1> : Attribute { }
public class Program<T2>
{
[Attr<T2>] // error
[Attr<List<T2>>] // error
void M() { }
}
Если универсальный атрибут используется в списке атрибутов, аргументы типа имеют те же ограничения, что и у typeof
аргумента. Например, [Attr<dynamic>]
является ошибкой. Это связано с тем, что типы, зависящие от атрибутов, такие как dynamic
, List<string?>
, nint
и т. д., не могут быть полностью представлены в окончательном IL для аргумента типа атрибута, так как не существует символа для подключения DynamicAttribute
или другого хорошо известного атрибута.
Недостатки
Удаление ограничения, обоснование последствий и добавление соответствующих тестов — это работа.
Альтернативы
Авторам атрибутов, желающим, чтобы пользователи могли обнаруживать требования к типам, которые они предоставляют атрибутам, необходимо писать анализаторы и рекомендовать пользователям использовать эти анализаторы в своих сборках.
Неразрешенные вопросы
- [x] Что означает
AllowMultiple = false
для универсального атрибута? Если у нас есть[Attr<string>]
и[Attr<object>]
, которые используются в символе, означает ли это, что используется несколько экземпляров атрибута?- В настоящее время мы склонны принять более строгий маршрут здесь и рассмотреть исходное определение класса атрибута при определении того, было ли применено несколько из них. Другими словами,
[Attr<string>]
и[Attr<object>]
применяются вместе, несовместимы сAllowMultiple = false
.
- В настоящее время мы склонны принять более строгий маршрут здесь и рассмотреть исходное определение класса атрибута при определении того, было ли применено несколько из них. Другими словами,
Встречи по проектированию
- https://github.com/dotnet/csharplang/blob/main/meetings/2017/LDM-2017-02-21.md#generic-attributes
- В то время существовала озабоченность по поводу того, что нам придется ограничить доступ к функции на том, поддерживает ли среда выполнения её. (Однако теперь мы поддерживаем только C# 10 в .NET 6. Было бы хорошо, чтобы реализация знала, какая минимальная целевая платформа поддерживает эту функцию, но кажется менее важной сегодня.)
C# feature specifications