Definir descriptores de acceso para los argumentos de atributo
Actualización: noviembre 2007
Nombre de tipo |
DefineAccessorsForAttributeArguments |
Identificador de comprobación |
CA1019 |
Categoría |
Microsoft.Design |
Cambio problemático |
No problemático |
Motivo
En el constructor, un atributo define argumentos que no tienen las propiedades correspondientes.
Descripción de la regla
Los atributos pueden definir argumentos obligatorios que deben especificarse al aplicar el atributo a un destino. Éstos también se denominan argumentos posicionales porque se proporcionan para atribuir constructores como parámetros posicionales. Para cada argumento obligatorio, el atributo debe proporcionar también una propiedad de sólo lectura correspondiente de modo que el valor del argumento se pueda recuperar en tiempo de ejecución. Esta regla comprueba que para cada parámetro de constructor se haya definido la propiedad correspondiente.
Los atributos también pueden definir argumentos opcionales, que también se denominan argumentos con nombre. Estos argumentos se proporcionan para atribuir constructores por nombre y deben tener una propiedad de lectura/escritura correspondiente.
Para los argumentos obligatorios y opcionales, las propiedades correspondientes y los parámetros de constructor deben utilizar el mismo nombre pero diferente grafía con mayúsculas y minúsculas. Propiedades utilizan el método Pascal de mayúsculas y minúsculas y los parámetros utilizan la convención Camel escribiendo la primera letra de cada palabra en mayúscula.
Cómo corregir infracciones
Para corregir una infracción de esta regla, agregue una propiedad de sólo lectura para cada parámetro de constructor que no tenga uno.
Cuándo suprimir advertencias
Suprima una advertencia de esta regla si no desea que el valor del argumento obligatorio sea recuperable.
Ejemplo de atributos personalizados
Descripción
El ejemplo siguiente muestra dos atributos que definen un parámetro obligatorio (posicional). Se ha definido incorrectamente la primera implementación del atributo. La segunda implementación es correcta.
Código
Imports System
Namespace DesignLibrary
' Violates rule: DefineAccessorsForAttributeArguments.
<AttributeUsage(AttributeTargets.All)> _
NotInheritable Public Class BadCustomAttribute
Inherits Attribute
Private data As String
' Missing the property that corresponds to
' the someStringData parameter.
Public Sub New(someStringData As String)
data = someStringData
End Sub 'New
End Class 'BadCustomAttribute
' Satisfies rule: Attributes should have accessors for all arguments.
<AttributeUsage(AttributeTargets.All)> _
NotInheritable Public Class GoodCustomAttribute
Inherits Attribute
Private data As String
Public Sub New(someStringData As String)
data = someStringData
End Sub 'New
'The constructor parameter and property
'name are the same except for case.
Public ReadOnly Property SomeStringData() As String
Get
Return data
End Get
End Property
End Class
End Namespace
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 = 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 = someStringData;
}
//The constructor parameter and property
//name are the same except for case.
public string SomeStringData
{
get
{
return data;
}
}
}
}
Argumentos posicionales y con nombre
Descripción
Los argumentos posicionales y con nombre aclaran a los usuarios de la biblioteca qué argumentos son obligatorios para el atributo y cuáles son opcionales.
En el ejemplo siguiente se muestra la implementación de un atributo que tiene tanto argumentos posicionales como con nombre.
Código
using System;
namespace DesignLibrary
{
[AttributeUsage(AttributeTargets.All)]
public sealed class GoodCustomAttribute : Attribute
{
string mandatory;
string optional;
public GoodCustomAttribute(string mandatoryData)
{
mandatory = mandatoryData;
}
public string MandatoryData
{
get { return mandatory; }
}
public string OptionalData
{
get { return optional; }
set { optional = value; }
}
}
}
Comentarios
En el ejemplo siguiente se muestra cómo aplicar el atributo personalizado a dos propiedades.
Código
[GoodCustomAttribute("ThisIsSomeMandatoryData", OptionalData = "ThisIsSomeOptionalData")]
public string MyProperty
{
get { return myProperty; }
set { myProperty = value; }
}
[GoodCustomAttribute("ThisIsSomeMoreMandatoryData")]
public string MyOtherProperty
{
get { return myOtherProperty; }
set { myOtherProperty = value; }
}