类型名 |
MarkAttributesWithAttributeUsage |
CheckId |
CA1018 |
类别 |
Microsoft.Design |
是否重大更改 |
是 |
原因
AttributeUsageAttribute 特性不在自定义特性中。
规则说明
当定义自定义特性时,用 AttributeUsageAttribute 标记该特性,以指示源代码中可以应用自定义特性的位置。特性的含义和预定用法将决定它在代码中的有效位置。例如,可以定义一个特性,用于标识由谁来负责维护和增强库中的每种类型,并且始终在类型级别分配责任。在这种情况下,编译器应该在类、枚举和接口上启用此特性,而不应在方法、事件或属性上启用它。组织策略和过程将指示是否在程序集上允许该特性。
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;
}
}
}
}