CA1018:用 AttributeUsageAttribute 标记特性
类型名 |
MarkAttributesWithAttributeUsage |
CheckId |
CA1018 |
类别 |
Microsoft.Design |
是否重大更改 |
是 |
原因
System.AttributeUsageAttribute 特性不在自定义特性中。
规则说明
当定义自定义特性时,用 AttributeUsageAttribute 标记该特性,以指示源代码中可以应用自定义特性的位置。 特性的含义和预定用法将决定它在代码中的有效位置。 例如,可以定义一个特性,用于标识由谁来负责维护和增强库中的每种类型,并且始终在类型级别分配责任。 在这种情况下,编译器应该在类、枚举和接口上启用此特性,而不应在方法、事件或属性上启用它。 组织策略和过程将指示是否在程序集上允许该特性。
System.AttributeTargets 枚举定义可以为自定义特性指定的目标。 如果省略 AttributeUsageAttribute,自定义特性将对所有目标有效,如 AttributeTargets 枚举的 All 值所定义的那样。
如何解决冲突
要修复与该规则的冲突,请使用 AttributeUsageAttribute 为特性指定目标。 请参见下面的示例。
何时禁止显示警告
应当修复与该规则的冲突,而不应排除警告消息。 即使特性继承了 AttributeUsageAttribute,为了简化代码维护,也应该显示该特性。
示例
下面的示例定义了两个特性。 BadCodeMaintainerAttribute 错误地省略 AttributeUsageAttribute 语句,而 GoodCodeMaintainerAttribute 正确地实现节前面所述的特性。 请注意,设计规则CA1019:定义特性参数的访问器需要属性 DeveloperName,为了保持完整性,包含了该属性。
Imports System
Namespace DesignLibrary
' Violates rule: MarkAttributesWithAttributeUsage.
NotInheritable Public Class BadCodeMaintainerAttribute
Inherits Attribute
Private developer As String
Public Sub New(developerName As String)
developer = developerName
End Sub 'New
Public ReadOnly Property DeveloperName() As String
Get
Return developer
End Get
End Property
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)> _
NotInheritable Public Class GoodCodeMaintainerAttribute
Inherits Attribute
Private developer As String
Public Sub New(developerName As String)
developer = developerName
End Sub 'New
Public ReadOnly Property DeveloperName() As String
Get
Return developer
End Get
End Property
End Class
End Namespace
using System;
namespace DesignLibrary
{
// Violates rule: MarkAttributesWithAttributeUsage.
public sealed class BadCodeMaintainerAttribute :Attribute
{
string developer;
public BadCodeMaintainerAttribute(string developerName)
{
developer = developerName;
}
public string DeveloperName
{
get
{
return developer;
}
}
}
// Satisfies rule: Attributes specify AttributeUsage.
// The attribute is valid for type-level targets.
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Enum | AttributeTargets.Interface | AttributeTargets.Delegate)]
public sealed class GoodCodeMaintainerAttribute :Attribute
{
string developer;
public GoodCodeMaintainerAttribute(string developerName)
{
developer = developerName;
}
public string DeveloperName
{
get
{
return developer;
}
}
}
}