CA1018: Marcar atributos com AttributeUsageAttribute

Property Valor
ID da regra CA1018
Título Marcar atributos com AttributeUsageAttribute
Categoria Projetar
Correção interruptiva ou sem interrupção Quebra
Habilitado por padrão no .NET 8 Como sugestão

Causa

O atributo System.AttributeUsageAttribute não está presente no atributo personalizado.

Descrição da regra

Ao definir um atributo personalizado, marque-o usando AttributeUsageAttribute para indicar onde o atributo personalizado pode ser aplicado no código-fonte. O significado e o uso desejado de um atributo determinarão seus locais válidos no código. Por exemplo, você pode definir um atributo que identifica a pessoa responsável por manter e aprimorar cada tipo em uma biblioteca, e essa responsabilidade sempre é atribuída no nível do tipo. Nesse caso, os compiladores devem habilitar o atributo em classes, enumerações e interfaces, mas não devem habilitá-lo em métodos, eventos ou propriedades. Políticas e procedimentos organizacionais determinam se o atributo deve ser habilitado em assemblies.

A enumeração System.AttributeTargets define os destinos que você pode especificar para um atributo personalizado. Se você omitir AttributeUsageAttribute, seu atributo personalizado será válido para todos os destinos, conforme definido pelo valor All da enumeração AttributeTargets.

Como corrigir violações

Para corrigir uma violação dessa regra, especifique destinos para o atributo usando AttributeUsageAttribute. Veja o exemplo a seguir.

Quando suprimir avisos

Você deve corrigir uma violação dessa regra em vez de excluir a mensagem. Mesmo se o atributo herdar AttributeUsageAttribute, ele deve estar presente para simplificar a manutenção do código.

Exemplo

O exemplo a seguir define dois atributos. BadCodeMaintainerAttribute omite incorretamente a instrução AttributeUsageAttribute e GoodCodeMaintainerAttribute implementa corretamente o atributo descrito anteriormente nesta seção. (A propriedade DeveloperName é exigida pela regra de design CA1019: definir acessadores para argumentos de atributo e está incluída para integridade.)

using System;

namespace ca1018
{
    // Violates rule: MarkAttributesWithAttributeUsage.
    public sealed class BadCodeMaintainerAttribute : Attribute
    {
        public BadCodeMaintainerAttribute(string developerName)
        {
            DeveloperName = developerName;
        }
        public string DeveloperName { get; }
    }

    // Satisfies rule: Attributes specify AttributeUsage.
    // This attribute is valid for type-level targets.
    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Enum | AttributeTargets.Interface | AttributeTargets.Delegate)]
    public sealed class GoodCodeMaintainerAttribute : Attribute
    {
        public GoodCodeMaintainerAttribute(string developerName)
        {
            DeveloperName = developerName;
        }
        public string DeveloperName { get; }
    }
}
Imports System

Namespace ca1018

    ' Violates rule: MarkAttributesWithAttributeUsage.
    Public NotInheritable Class BadCodeMaintainerAttribute
        Inherits Attribute

        Public Sub New(developerName As String)
            Me.DeveloperName = developerName
        End Sub 'New

        Public ReadOnly Property DeveloperName() As String
    End Class

    ' Satisfies rule: Attributes specify AttributeUsage.
    ' The attribute is valid for type-level targets.
    <AttributeUsage(AttributeTargets.Class Or AttributeTargets.Enum Or
   AttributeTargets.Interface Or AttributeTargets.Delegate)>
    Public NotInheritable Class GoodCodeMaintainerAttribute
        Inherits Attribute

        Public Sub New(developerName As String)
            Me.DeveloperName = developerName
        End Sub 'New

        Public ReadOnly Property DeveloperName() As String
    End Class

End Namespace

Confira também