CA1018:用 AttributeUsageAttribute 标记特性
属性 | 值 |
---|---|
规则 ID | CA1018 |
标题 | 用 AttributeUsageAttribute 标记特性 |
类别 | 设计 |
修复是中断修复还是非中断修复 | 重大 |
在 .NET 9 中默认启用 | 作为建议 |
原因
自定义特性上不存在 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