CA1018:用 AttributeUsageAttribute 标记特性
属性 | 值 |
---|---|
规则 ID | CA1018 |
标题 | 用 AttributeUsageAttribute 标记特性 |
类别 | 设计 |
修复是中断修复还是非中断修复 | 重大 |
在 .NET 9 中默认启用 | 作为建议 |
原因
自定义特性上不存在 System.AttributeUsageAttribute 特性。
规则说明
当定义自定义特性时,用 AttributeUsageAttribute 标记该特性,以指示源代码中可以应用自定义特性的位置。 特性的含义和预定用法将决定它在代码中的有效位置。 例如,你可以定义一个特性,该特性标识负责维护和增强库中的每个类型的人员,并且此责任始终在类型级别上分配。 在这种情况下,编译器应在类、枚举和接口上启用该特性,但不应在方法、事件或属性上启用它。 组织策略和过程将规定是否应在程序集上启用该特性。
System.AttributeTargets 枚举定义可为自定义特性指定的目标。 如果省略 AttributeUsageAttribute,则自定义特性将对所有目标有效,如 All
枚举的 AttributeTargets 值所定义。
如何解决冲突
若要解决此规则的冲突,请使用 AttributeUsageAttribute 指定特性的目标。 请参阅以下示例。
何时禁止显示警告
应解决此规则的冲突,而不是排除消息。 即使该特性继承 AttributeUsageAttribute,也应该提供该特性以简化代码维护。
示例
下面的示例定义了两个特性。 BadCodeMaintainerAttribute
错误地省略了 AttributeUsageAttribute 语句,但 GoodCodeMaintainerAttribute
正确实现了本部分前面所述的特性。 (设计规则 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