| 属性 | 值 |
|---|---|
| 规则 ID | CA1018 |
| 标题 | 用 AttributeUsageAttribute 标记属性特征 |
| 类别 | 设计 |
| 修复会引起中断还是不会引起中断 | 突发 |
| 在 .NET 10 中默认启用 | 作为一种建议 |
| 适用的语言 | C# 和 Visual Basic |
原因
自定义特性上不存在 System.AttributeUsageAttribute 特性。
规则说明
当定义自定义特性时,用 AttributeUsageAttribute 标记该特性,以指示源代码中可以应用自定义特性的位置。 特性的含义和预定用法将决定它在代码中的有效位置。 例如,你可以定义一个特性,该特性标识负责维护和增强库中的每个类型的人员,并且此责任始终在类型级别上分配。 在这种情况下,编译器应在类、枚举和接口上启用该特性,但不应在方法、事件或属性上启用它。 组织策略和过程将规定是否应在程序集上启用该特性。
System.AttributeTargets 枚举定义可为自定义特性指定的目标。 如果省略 AttributeUsageAttribute,那么根据 All 枚举的 AttributeTargets 值,您的自定义属性将对所有目标有效。
如何解决违规
若要解决此规则的冲突,请使用 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