13. 定义自定义属性参数的访问属性
翻译概述:
一个比较无聊的规则,实在看不出在什么情况下,一个开发者会做出违反这条规则的设计。没有别的内容,只是说应该为自定义特性的构造函数中的参数提供一个相关的属性去读取它们的值。
一个让我比较费解的规则,即没有看出其中所传达的设计思想,也没发现任何优秀的设计技巧。
原文引用:
Define accessors for attribute arguments
Rule Description
Attributes can define mandatory arguments that must be specified when applying the attribute to a target. These are sometimes called positional arguments because they are supplied to attribute constructors as positional parameters. For every mandatory argument, the attribute should also provide a corresponding read-only property so that the value of the argument can be retrieved at execution time. This rule checks to see that for each constructor parameter, you have defined the corresponding property. Attributes can also define optional arguments, called named arguments. These arguments are supplied to attribute constructors by name and should have a corresponding read/write property. For mandatory and optional arguments, the corresponding properties and constructor parameters should use the same name but different casing. (Properties use Pascal casing, and parameters use camel casing.) How to Fix Violations
To fix a violation of this rule, add a read-only property for each constructor parameter that does not have one. When to Exclude Messages
Exclude a message from this rule if you do not want the value of the mandatory argument to be retrievable. Example Code
The following example shows two attributes that define a mandatory (positional) parameter. The first implementation of the attribute is incorrectly defined. The second implementation is correct. [Visual Basic] Imports System Namespace DesignLibraryNamespace DesignLibrary &#39; Violates rule: DefineAccessorsForAttributeArguments. <AttributeUsage(AttributeTargets.All)> _ NotInheritable Public Class BadCustomAttributeClass BadCustomAttribute Inherits Attribute Private data As String &#39; Missing the property that corresponds to &#39; the someStringData parameter. Public Sub New()Sub New(someStringData As String) data &#61; someStringData End Sub &#39;New End Class &#39;BadCustomAttribute &#39; Satisfies rule: Attributes should have accessors for all arguments. <AttributeUsage(AttributeTargets.All)> _ NotInheritable Public Class GoodCustomAttributeClass GoodCustomAttribute Inherits Attribute Private data As String Public Sub New()Sub New(someStringData As String) data &#61; someStringData End Sub &#39;New &#39;The constructor parameter and property &#39;name are the same except for case. Public ReadOnly Property SomeStringData()Property SomeStringData() As String Get Return data End Get End Property End Class End Namespace [C#] using System; namespace DesignLibrary { // Violates rule: DefineAccessorsForAttributeArguments. [AttributeUsage(AttributeTargets.All)] public sealed class BadCustomAttribute :Attribute { string data; // Missing the property that corresponds to // the someStringData parameter. public BadCustomAttribute(string someStringData) { data &#61; someStringData; } } // Satisfies rule: Attributes should have accessors for all arguments. [AttributeUsage(AttributeTargets.All)] public sealed class GoodCustomAttribute :Attribute { string data; public GoodCustomAttribute(string someStringData) { data &#61; someStringData; } //The constructor parameter and property //name are the same except for case. public string SomeStringData { get { return data; } } } } Related Rules
Avoid unsealed attributes See Also
Attribute Usage Guidelines |
引起的原因&#xff1a;
没有为一个自定义特性&#xff08;Attribute&#xff09;的构造函数中的所有参数定义相应的属性来访问这些参数。
描述&#xff1a;
自定义特性可以定义一组强制参数&#xff0c;当将特性应用到目标上时&#xff0c;必须指定这些参数。因为他们被定义为特性的构造函数的位置参数&#xff08;非命名参数&#xff09;&#xff0c;通常称它们为位置参数。对于每一个强制参数&#xff0c;自定义特性应该同时提供一个相关的制度属性&#xff0c;这样&#xff0c;才能在需要的时候获得这些参数的值。这条规则检查你是否为每一个参数定义了相关属性。
自定义特性也可以定义可选参数&#xff0c;称之为命名参数。在自定义特性的构造函数中可以使用名字指定它们的值。应该为它们定义可读可写属性。
对于强制的和可选的参数&#xff0c;他们相关的属性应该和构造函数参数有类似的名字&#xff0c;仅仅使用大小写区分它们。&#xff08;属性使用Pascal命名规则&#xff0c;参数使用骆峰命名规则&#xff09;
修复&#xff1a;
为构造函数中的每一个参数提供一个只读属性。
例外&#xff1a;
如果你不打算获得强制参数的值&#xff0c;可以忽略这条规则。
例程&#xff1a;
原文中给出了两个自定义特性类&#xff08;分别给出了使用VB.NET和C#的实现&#xff09;&#xff0c;它们都定义了一个强制参数。其中第一个自定义特性类违反了这条规则&#xff0c;没有为强制参数实现相关的属性。第二个自定义特性类修复了这个问题。