Поделиться через


Устранение ошибок и предупреждений, связанных с объявлениями атрибутов или использованием атрибутов в коде

В этой статье рассматриваются следующие ошибки компилятора:

  • CS0181: параметр конструктора атрибутов имеет тип, который не является допустимым типом параметра атрибута
  • CS0243: условный атрибут недействителен в методе, так как он является методом переопределения.
  • CS0404: Атрибут недопустим для данного типа объявления.
  • CS0415: этот атрибут действителен только для индексатора, который не является явным объявлением члена интерфейса.
  • CS0416: тип параметра: аргумент атрибута не может использовать параметры типа.
  • CS0447: атрибут нельзя использовать с аргументами типа.
  • CS0577: условный атрибут недопустим, поскольку он является конструктором, деструктором, оператором, лямбда-выражением или явной реализацией интерфейса.
  • CS0578: условный атрибут недействителен для функции, так как его возвращаемый тип не является пустым.
  • CS0579: повторяющийся атрибут
  • CS0582: условный атрибут недопустим для элементов интерфейса.
  • CS0592: атрибут недопустим для этого типа объявления. Допустимо только для определенных объявлений.
  • CS0609: не удается задать атрибут для индексатора, который переопределен.
  • CS0616: тип не является классом атрибутов
  • CS0625: поле экземпляра в типах, помеченных с помощью StructLayout(LayoutKind.Explicit), должно иметь атрибут FieldOffset.
  • CS0629: Условный элемент 'member' не может реализовать элемент интерфейса 'элемент базового интерфейса' в типе 'Type Name'.
  • CS0636: атрибут FieldOffset может быть помещен только на элементы типов, помеченных как StructLayout(LayoutKind.Explicit).
  • CS0637: атрибут FieldOffset не разрешен для статических или константных полей.
  • CS0641: этот атрибут действителен только для классов, производных от System.Attribute.
  • CS0646: не удается указать атрибут DefaultMember для типа, содержащего индексатор.
  • CS0647: атрибут выдачи ошибок
  • CS0653: не удается применить класс атрибута "class", так как он является абстрактным.
  • CS0657: расположение не является допустимым расположением атрибута для этого объявления. Указаны допустимые расположения атрибутов для этого объявления. Все атрибуты в этом блоке будут игнорироваться.
  • CS0658: расположение не является распознаваемым расположением атрибута. Указаны допустимые расположения атрибутов для этого объявления. Все атрибуты в этом блоке будут игнорироваться.
  • CS0668: два индексатора имеют разные имена; атрибут IndexerName должен использоваться с одинаковым именем для каждого индексатора в типе.
  • CS0685: Условный элемент "member" не может иметь выходной параметр.
  • CS0735: недопустимый тип, указанный в качестве аргумента атрибута TypeForwardedTo
  • CS0739: Повторяющийся типForwardedToAttribute
  • CS1608: атрибут RequiredAttribute не разрешен для типов C#
  • CS1614: имя атрибута неоднозначно. Используйте "@name" или явно включите суффикс "Атрибут".
  • CS1618: Не удается создать делегат с использованием метода, поскольку он или метод, который он переопределяет, помечен условным атрибутом
  • CS1667: Атрибут недопустим для свойств или аксессоров событий. Это допустимо только для определенных объявлений.
  • CS1689: атрибут действителен только для методов или классов атрибутов.
  • CS7014: атрибуты недопустимы в этом контексте.
  • CS7046: необходимо указать параметр атрибута.
  • CS7047: необходимо указать параметр атрибута "parameter1" или "parameter2".
  • CS7067: параметр конструктора атрибутов является необязательным, но значение параметра по умолчанию не указано.
  • CS8959. CallerArgumentExpressionAttribute нельзя применить, так как стандартные преобразования типа1 в type2 не существуют.
  • CS8960: callerArgumentExpressionAttribute, примененный к параметру, не будет иметь эффекта. Он переопределяется callerLineNumberAttribute.
  • CS8961: метод CallerArgumentExpressionAttribute, примененный к параметру, не будет иметь никакого эффекта. Он переопределяется callerFilePathAttribute.
  • CS8962: CallerArgumentExpressionAttribute, примененный к параметру, не будет иметь эффекта. Он переопределяется callerMemberNameAttribute.
  • CS8963: callerArgumentExpressionAttribute, примененный к параметру, не будет иметь эффекта. Он применяется с недопустимым именем параметра.
  • CS8968: аргумент типа атрибута не может использовать параметры типа
  • CS8970: тип нельзя использовать в этом контексте, так как он не может быть представлен в метаданных.
  • CS9331: атрибут не может применяться вручную.

Аргументы атрибутов и параметры

При неправильном использовании аргументов или параметров атрибутов возникают следующие ошибки:

  • CS0181: параметр конструктора атрибутов имеет тип, который не является допустимым типом параметра атрибута
  • CS0416: тип параметра: аргумент атрибута не может использовать параметры типа.
  • CS0447: атрибут нельзя использовать с аргументами типа.
  • CS0647: атрибут выдачи ошибок
  • CS7046: необходимо указать параметр атрибута.
  • CS7047: необходимо указать параметр атрибута "parameter1" или "parameter2".
  • CS7067: параметр конструктора атрибутов является необязательным, но значение параметра по умолчанию не указано.
  • CS8968: аргумент типа атрибута не может использовать параметры типа
  • CS8970: тип нельзя использовать в этом контексте, так как он не может быть представлен в метаданных.

Чтобы исправить эти ошибки, выполните следующие правила:

  • Параметры конструктора атрибутов должны использовать допустимые типы параметров атрибута (CS0181). Спецификация языка C# ограничивает типы параметров атрибута примитивными типами (bool, byte, char, double, float, int, long, short, и string), object, System.Type, типами перечисления и одномерными массивами этих типов. Указатели функций и другие типы, которые не могут быть представлены в метаданных, не являются допустимыми типами параметров атрибутов.
  • Аргументы атрибутов должны быть константными значениями во время компиляции, поэтому нельзя использовать параметры типа в качестве аргументов атрибутов (CS0416). Компилятор должен разрешать аргументы атрибутов во время компиляции, а параметры типа не известны до создания универсального типа.
  • Аргументы типа нельзя применять к не универсальному атрибуту (CS0447). Если класс атрибута не является универсальным, его использование не может включать аргументы типа в угловые скобки.
  • Все значения, передаваемые конструктору атрибутов, должны быть правильно отформатированы и в допустимом диапазоне для каждого параметра (CS0647). Например, требуется допустимая GuidAttribute строка формата GUID.
  • При применении атрибута необходимо указать все необходимые параметры атрибута (CS7046, CS7047). Проверьте сигнатуру конструктора атрибута, чтобы определить, какие параметры являются обязательными, и укажите допустимые аргументы для каждого параметра.
  • При определении пользовательского атрибута с необязательными параметрами конструктора укажите значения по умолчанию для этих параметров (CS7067). Используйте синтаксис parameterType parameterName = defaultValue в конструкторе атрибутов, чтобы вызывающие элементы могли опустить эти аргументы.
  • Аргументы универсального типа атрибутов должны быть конкретными типами, а не параметрами типа (CS8968). Компилятор должен полностью определить аргументы универсального типа атрибутов во время компиляции, поэтому открытые параметры типа не разрешены.
  • Типы, используемые в качестве аргументов атрибутов, должны представляться в метаданных (CS8970). Некоторые созданные типы, такие как те, которые включают dynamic или определенные имена элементов кортежа, не могут быть закодированы в метаданных и не допускаются в качестве аргументов типа атрибутов.

Дополнительные сведения см. в разделе "Атрибуты", "Универсальные" и "Спецификация языка C#" по атрибутам.

Замечание

CS0447 и CS0647 устарели. Текущий компилятор не выдает эти ошибки.

Требования к классу атрибутов

При определении классов атрибутов, которые не соответствуют необходимым ограничениям, возникают следующие ошибки:

  • CS0404: атрибут недопустим для этого типа объявления.
  • CS0579: повторяющийся атрибут
  • CS0616: тип не является классом атрибутов
  • CS0641: этот атрибут действителен только для классов, производных от System.Attribute.
  • CS0653: не удается применить класс атрибута "class", так как он является абстрактным.
  • CS1614: имя атрибута неоднозначно. Используйте "@name" или явно включите суффикс "Атрибут".

Чтобы исправить эти ошибки, выполните следующие правила:

  • Примените атрибуты только к типам объявлений, разрешенным атрибутом AttributeUsageAttribute (CS0404). Проверьте значение, указанное AttributeTargets в атрибуте AttributeUsage , чтобы увидеть, какие целевые объекты допустимы.
  • Если один и тот же атрибут применяется несколько раз к одному целевому объекту, удалите дубликаты или установите AllowMultiple = true его в атрибуте AttributeUsageAttribute (CS0579). По умолчанию атрибуты могут отображаться только один раз в каждом целевом объекте.
  • Тип, используемый в синтаксисе атрибута, должен наследоваться от System.Attribute (CS0616). В качестве атрибутов можно использовать только классы, производные от System.Attribute. Другие типы вызывают эту ошибку, даже если они имеют аналогичное имя.
  • Можно применять AttributeUsageAttribute только к классам, производным от Attribute (CS0641). Атрибут AttributeUsage управляет тем, как используются другие атрибуты, и сам по себе ограничивается классами атрибутов.
  • Классы атрибутов не могут быть abstract , так как компилятор должен создать их экземпляр (CS0653). abstract Удалите модификатор из класса атрибутов или наследуйте конкретный класс из абстрактной базы.
  • Когда существуют оба класса атрибутов, компилятор не может определить, к какому относится [Example] (CS1614). Разделите, используя [@Example] для более короткого имени или [ExampleAttribute] для более длинного имени.

Дополнительные сведения см. в разделе "Создание настраиваемых атрибутов " и раздела спецификации языка C#по атрибутам.

Контекст расположения атрибутов

При применении атрибутов в недопустимых расположениях или использовании неправильных описателей целевых объектов возникают следующие ошибки:

  • CS0592: атрибут недопустим для этого типа объявления. Допустимо только для определенных объявлений.
  • CS0657: расположение не является допустимым расположением атрибута для этого объявления. Указаны допустимые расположения атрибутов для этого объявления. Все атрибуты в этом блоке будут игнорироваться.
  • CS0658: расположение не является распознаваемым расположением атрибута. Указаны допустимые расположения атрибутов для этого объявления. Все атрибуты в этом блоке будут игнорироваться.
  • CS1667: Атрибут не действителен для свойства или аксессоров событий. Он допустим только для конкретных объявлений.
  • CS7014: атрибуты недопустимы в этом контексте.

Чтобы исправить эти ошибки, следуйте этим правилам. Дополнительные сведения см. в разделе "Целевые объекты атрибутов " и в разделе спецификации языка C#, посвященном спецификации атрибутов.

  • Каждый атрибут AttributeUsageAttribute определяет, на какие типы объявлений он направлен. Атрибут должен применяться только к этим типам (CS0592). Например, нельзя применить атрибут, определенный с помощью AttributeTargets.Interface к классу.
  • При использовании спецификатора атрибута, например method: или property:, спецификатор должен быть допустимым для объявления, в котором он отображается (CS0657). Проверьте сообщение об ошибке, чтобы узнать, какие целевые описатели разрешены для конкретного объявления.
  • Используемый целевой спецификатор атрибута не является распознаваемым спецификатором (CS0658). Допустимые описатели включают assembly:, module:, type:, method:, property:, field:, event:, param: и return:.
  • Некоторые атрибуты, такие как ObsoleteAttribute и CLSCompliantAttribute, не являются допустимыми для свойств или методов доступа к событиям (CS1667). Переместите атрибут из аксессора непосредственно к объявлению свойства или события.
  • Атрибуты могут отображаться только в элементах программы, поддерживающих их (CS7014). Если вы применяете атрибуты уровня сборки или модуля, используйте assembly: или module: целевые описатели и поместите их в верхней части файла.

Предопределенные атрибуты

При неправильном использовании определенных предопределенных атрибутов .NET возникают следующие ошибки:

  • CS0415: этот атрибут действителен только для индексатора, который не является явным объявлением члена интерфейса.
  • CS0609: Нельзя задать атрибут для индексатора, отмеченного как переопределённый.
  • CS0625: поле экземпляра в типах, помеченных с помощью StructLayout(LayoutKind.Explicit), должно иметь атрибут FieldOffset.
  • CS0636: атрибут FieldOffset может быть помещен только на элементы типов, помеченных как StructLayout(LayoutKind.Explicit).
  • CS0637: атрибут FieldOffset не разрешен для статических или константных полей.
  • CS0646: не удается указать атрибут DefaultMember для типа, содержащего индексатор.
  • CS0668: два индексатора имеют разные имена; атрибут IndexerName должен использоваться с одинаковым именем для каждого индексатора в типе.
  • CS0735: недопустимый тип, указанный в качестве аргумента атрибута TypeForwardedTo
  • CS0739: Дублирующийся атрибут TypeForwardedToAttribute
  • CS1608: атрибут RequiredAttribute не разрешен для типов C#
  • CS9331: атрибут не может применяться вручную.

Чтобы исправить эти ошибки, следуйте этим правилам. Дополнительные сведения см. в разделе "Индексаторы", "Типы структур" TypeForwardedToAttributeи "Вызов платформы" (P/Invoke).

  • Можно IndexerNameAttribute применять только к индексаторам, которые не являются явными объявлениями членов интерфейса (CS0415). Удалите атрибут из явных индексаторов интерфейса, так как интерфейс уже определяет имя индексатора.
  • Нельзя применить IndexerName к индексаторам, помеченным как override, потому что индексаторы-переопределения наследуют своё имя от базового класса (CS0609). Удалите атрибут IndexerName из переопределенного индексатора.
  • Каждое поле экземпляра в типе, помеченном как StructLayout(LayoutKind.Explicit), должно иметь FieldOffsetAttribute (CS0625). Для явно заданного макета необходимо указывать смещение в байтах для каждого поля экземпляра.
  • Его FieldOffsetAttribute можно поместить только на элементы типов, для которых StructLayoutAttribute задано значение LayoutKind.Explicit(CS0636). Добавьте атрибут StructLayout к содержащему объявлению типа.
  • Атрибут FieldOffset недопустим для полей static или const, так как определённый макет применим только к полям экземпляров (CS0637). FieldOffset Удалите атрибут из статического или константного поля.
  • Невозможно применить DefaultMemberAttribute к типу, который уже содержит индексатор, так как компилятор автоматически определяет элемент по умолчанию для типов с индексаторами (CS0646). DefaultMember Удалите атрибут.
  • Все IndexerNameAttribute атрибуты в типе должны указывать то же имя (CS0668). Измените имена, чтобы они соответствовали, потому что среда выполнения использует одно имя для всех индексаторов в данном типе.
  • Тип, указанный в качестве аргумента TypeForwardedToAttribute, должен быть неуниверсальным, невложенным, неуказательным и не массивом (CS0735). Только именованные типы верхнего уровня являются допустимыми целевыми объектами пересылки.
  • Сборка может иметь единственный TypeForwardedToAttribute на каждый внешний тип (CS0739). Найдите и удалите повторяющееся TypeForwardedTo объявление.
  • В RequiredAttributeAttribute не разрешено использование на типах, определенных в C# (CS1608). Этот атрибут зарезервирован для других языков, которые должны принудительно требовать определенной функции компилятора.
  • Некоторые атрибуты зарезервированы для компилятора и не могут применяться вручную в исходном коде (CS9331). Замените атрибут эквивалентным синтаксисом языка C#, который приводит к его созданию компилятором.

Использование условного атрибута

Вы видите следующие ошибки, когда применяете ConditionalAttribute способами, нарушающими его ограничения по применению:

  • CS0243: условный атрибут недействителен в методе, так как он является методом переопределения.
  • CS0577: условный атрибут недопустим, поскольку он является конструктором, деструктором, оператором, лямбда-выражением или явной реализацией интерфейса.
  • CS0578: условный атрибут недействителен для функции, так как его возвращаемый тип не является пустым.
  • CS0582: условный атрибут недопустим для элементов интерфейса.
  • CS0629: условный оператор 'member' не может реализовать член интерфейса 'base class member' в типе 'Type Name'.
  • CS0685: условный член "member" не может иметь параметр out.
  • CS1618: Невозможно создать делегат для метода, поскольку этот метод или метод, который он переопределяет, имеет атрибут Conditional
  • CS1689: атрибут действителен только для методов или классов атрибутов.

Чтобы исправить эти ошибки, следуйте этим правилам. Дополнительные сведения см. в разделе ConditionalAttribute, Условные методы и атрибуты.

  • Компилятор привязывает вызовы к объявлению базового метода, а не переопределению, поэтому нельзя применить Conditional атрибут для переопределения методов (CS0243). Удалите атрибут Conditional из метода переопределения или удалите ключевое слово override.
  • Атрибут Conditional не применим к конструкторам, финализаторам, операторам, лямбда-выражениям или явным реализациям интерфейсов (CS0577). Эти типы элементов не могут быть условно опущены, так как они имеют необходимые роли в жизненном цикле или контракте типа.
  • Условные методы должны возвращать void , так как компилятор может полностью опустить вызов, и возвращаемое значение не будет доступно вызывающей функции (CS0578). Измените возвращаемый тип voidметода на или удалите Conditional атрибут.
  • Элементы интерфейса не могут быть условными, так как все члены интерфейса должны быть реализованы (CS0582). Удалите атрибут Conditional из объявления члена интерфейса.
  • Методы, реализующие элементы интерфейса, не могут быть условными, так как контракт интерфейса требует, чтобы они присутствовали во всех сборках (CS0629). Conditional Удалите атрибут из метода реализации.
  • Условные методы не могут иметь out параметры, так как out значение переменной будет неопределенным, когда компилятор опустит вызов метода (CS0685). out Удалите параметры из метода или удалите Conditional атрибут.
  • Невозможно создать делегат, ссылающийся на условный метод, так как метод может не существовать в сборках, где символ условия не определен (CS1618). Conditional Удалите атрибут из метода или не используйте его в качестве целевого объекта делегата.
  • Атрибут Conditional действителен только для методов и классов атрибутов (CS1689). Он недействителен для других типов объявлений, таких как неатрибутные классы, структуры или интерфейсы.

Использование атрибута CallerArgumentExpression

При неправильном применении CallerArgumentExpressionAttribute или конфликте с другими атрибутами информации вызывающего объекта возникают следующие ошибки:

  • CS8959. CallerArgumentExpressionAttribute нельзя применить, так как стандартные преобразования типа1 в type2 не существуют.
  • CS8960: CallerArgumentExpressionAttribute, применённый к параметру, не имеет эффекта, так как он переопределяется CallerLineNumberAttribute.
  • CS8961: метод CallerArgumentExpressionAttribute, примененный к параметру, не будет иметь никакого эффекта. Он переопределяется callerFilePathAttribute.
  • CS8962: CallerArgumentExpressionAttribute, примененный к параметру, не будет иметь эффекта. Он переопределяется callerMemberNameAttribute.
  • CS8963: callerArgumentExpressionAttribute, примененный к параметру, не будет иметь эффекта. Он применяется с недопустимым именем параметра.

Чтобы исправить эти ошибки, следуйте этим правилам. Дополнительные сведения см. в разделе "Атрибуты сведений о вызывающем объекте " и CallerArgumentExpressionAttribute.

  • Параметр, помеченный CallerArgumentExpression, должен иметь тип string или тип со стандартным преобразованием из string, так как атрибут внедряет string представление выражения аргумента вызывающей стороны (CS8959). Измените тип параметра на string или совместимый тип.
  • Атрибут CallerArgumentExpression не влияет на параметр, который также имеет CallerLineNumberAttributeCallerFilePathAttribute, или CallerMemberNameAttribute (CS8960, CS8961, CS8962). Эти атрибуты сведений вызывающего объекта имеют приоритет, поэтому удалите CallerArgumentExpression атрибут из параметра.
  • Строковый аргумент, переданный CallerArgumentExpression конструктору, должен соответствовать имени другого параметра в той же сигнатуре метода (CS8963). Если имя параметра имеет ошибку или ссылается на несуществующий параметр, атрибут не действует.