CA1018:用 AttributeUsageAttribute 标记特性

属性
规则 ID CA1018
标题 用 AttributeUsageAttribute 标记特性
类别 设计
修复是中断修复还是非中断修复 重大
在 .NET 8 中默认启用 作为建议

原因

自定义特性上不存在 System.AttributeUsageAttribute 特性。

规则说明

当定义自定义特性时,用 AttributeUsageAttribute 标记该特性,以指示源代码中可以应用自定义特性的位置。 特性的含义和预定用法将决定它在代码中的有效位置。 例如,你可以定义一个特性,该特性标识负责维护和增强库中的每个类型的人员,并且此责任始终在类型级别上分配。 在这种情况下,编译器应在类、枚举和接口上启用该特性,但不应在方法、事件或属性上启用它。 组织策略和过程将规定是否应在程序集上启用该特性。

System.AttributeTargets 枚举定义可为自定义特性指定的目标。 如果省略 AttributeUsageAttribute,则自定义特性将对所有目标有效,如 AttributeTargets 枚举的 All 值所定义。

如何解决冲突

若要解决此规则的冲突,请使用 AttributeUsageAttribute 指定特性的目标。 请参阅以下示例。

何时禁止显示警告

应解决此规则的冲突,而不是排除消息。 即使该特性继承 AttributeUsageAttribute,也应该提供该特性以简化代码维护。

示例

下面的示例定义了两个特性。 BadCodeMaintainerAttribute 错误地省略了 AttributeUsageAttribute 语句,但 GoodCodeMaintainerAttribute 正确实现了本部分前面所述的特性。 (设计规则 CA1019:定义特性参数的访问器要求属性 DeveloperName,出于完整性考虑,此属性包含在内。)

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

请参阅