Nota:
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
El lenguaje Visual Basic permite al programador especificar modificadores en declaraciones, que representan información sobre las entidades que se declaran. Por ejemplo, al colocar un método de clase con los modificadores Public, , FriendProtected, Protected Friendo Private se especifica su accesibilidad.
Además de los modificadores definidos por el lenguaje, Visual Basic también permite a los programadores crear nuevos modificadores, denominados atributos, y usarlos al declarar nuevas entidades. Estos nuevos modificadores, que se definen a través de la declaración de clases de atributo, se asignan a las entidades a través de bloques de atributos.
Nota. Los atributos se pueden recuperar en tiempo de ejecución a través de las API de reflexión de .NET Framework. Estas API están fuera del ámbito de esta especificación.
Por ejemplo, un marco podría definir un Help atributo que se puede colocar en elementos de programa como clases y métodos para proporcionar una asignación de elementos de programa a documentación, como se muestra en el ejemplo siguiente:
<AttributeUsage(AttributeTargets.All)> _
Public Class HelpAttribute
Inherits Attribute
Public Sub New(urlValue As String)
Me.UrlValue = urlValue
End Sub
Public Topic As String
Private UrlValue As String
Public ReadOnly Property Url() As String
Get
Return UrlValue
End Get
End Property
End Class
En el ejemplo se define una clase de atributo denominada HelpAttribute, o Help para short, que tiene un parámetro posicional (UrlValue) y un argumento con nombre (Topic).
En el ejemplo siguiente se muestran varios usos del atributo :
<Help("http://www.example.com/.../Class1.htm")> _
Public Class Class1
<Help("http://www.example.com/.../Class1.htm", Topic:="F")> _
Public Sub F()
End Sub
End Class
En el ejemplo siguiente se comprueba si Class1 tiene un Help atributo y se escriben los valores y Url asociados Topic si el atributo está presente.
Module Test
Sub Main()
Dim type As Type = GetType(Class1)
Dim arr() As Object = _
type.GetCustomAttributes(GetType(HelpAttribute), True)
If arr.Length = 0 Then
Console.WriteLine("Class1 has no Help attribute.")
Else
Dim ha As HelpAttribute = CType(arr(0), HelpAttribute)
Console.WriteLine("Url = " & ha.Url & ", Topic = " & ha.Topic)
End If
End Sub
End Module
Clases de atributos
Una clase de atributo es una clase no genérica que deriva de System.Attribute y no MustInherites . La clase de atributo puede tener un System.AttributeUsage atributo que declara en qué es válido el atributo, si se puede usar varias veces en una declaración y si se hereda. En el ejemplo siguiente se define una clase de atributo denominada SimpleAttribute que se puede colocar en declaraciones de clase y declaraciones de interfaz:
<AttributeUsage(AttributeTargets.Class Or AttributeTargets.Interface)> _
Public Class SimpleAttribute
Inherits System.Attribute
End Class
En el ejemplo siguiente se muestran algunos usos del Simple atributo . Aunque la clase de atributo se denomina SimpleAttribute, los usos de este atributo pueden omitir el Attribute sufijo, lo que reduce el nombre a Simple:
<Simple> Class Class1
End Class
<Simple> Interface Interface1
End Interface
Si el atributo carece de , System.AttributeUsageel atributo se puede colocar en cualquier destino (equivalente a AttributeTargets.All). El System.AttributeUsage atributo tiene un inicializador de variable, , AllowMultipleque especifica si el atributo indicado se puede especificar más de una vez para una declaración determinada. Si AllowMultiple para un atributo es True, es una clase de atributo de varios usos y se puede especificar más de una vez en una declaración. Si AllowMultiple para un atributo es o no se False especifica para un atributo, es una clase de atributo de uso único y se puede especificar como máximo una vez en una declaración.
En el ejemplo siguiente se define una clase de atributo de varios usos denominada AuthorAttribute:
<AttributeUsage(AttributeTargets.Class, AllowMultiple:=True)> _
Public Class AuthorAttribute
Inherits System.Attribute
Private _Value As String
Public Sub New(value As String)
Me._Value = value
End Sub
Public ReadOnly Property Value() As String
Get
Return _Value
End Get
End Property
End Class
En el ejemplo se muestra una declaración de clase con dos usos del Author atributo :
<Author("Maria Hammond"), Author("Ramesh Meyyappan")> _
Class Class1
End Class
El System.AttributeUsage atributo tiene una variable de instancia pública, Inherited, que especifica si el atributo, cuando se especifica en un tipo base, también se hereda por tipos que derivan de este tipo base. Si la Inherited variable de instancia pública no se inicializa, se usa un valor predeterminado de False . Las propiedades y los eventos no heredan atributos, aunque los métodos definidos por propiedades y eventos sí lo hacen. Las interfaces no heredan atributos.
Si un atributo de uso único se hereda y se especifica en un tipo derivado, el atributo especificado en el tipo derivado invalida el atributo heredado. Si un atributo de varios usos se hereda y se especifica en un tipo derivado, ambos atributos se especifican en el tipo derivado. Por ejemplo:
<AttributeUsage(AttributeTargets.Class, AllowMultiple:=True, _
Inherited:=True) > _
Class MultiUseAttribute
Inherits System.Attribute
Public Sub New(value As Boolean)
End Sub
End Class
<AttributeUsage(AttributeTargets.Class, Inherited:=True)> _
Class SingleUseAttribute
Inherits Attribute
Public Sub New(value As Boolean)
End Sub
End Class
<SingleUse(True), MultiUse(True)> Class Base
End Class
' Derived has three attributes defined on it: SingleUse(False),
' MultiUse(True) and MultiUse(False)
<SingleUse(False), MultiUse(False)> _
Class Derived
Inherits Base
End Class
Los parámetros posicionales del atributo se definen mediante los parámetros de los constructores públicos de la clase de atributo. Los parámetros posicionales deben ser ByVal y no especificar ByRef. Las variables y propiedades de instancia pública se definen mediante propiedades de lectura y escritura públicas o variables de instancia de la clase de atributo. Los tipos que se pueden usar en parámetros posicionales y variables y propiedades de instancia pública están restringidos a los tipos de atributo. Un tipo es un tipo de atributo si es uno de los siguientes:
Cualquier tipo primitivo excepto para
DateyDecimal.El tipo
Object.El tipo
System.Type.Tipo enumerado, siempre que y los tipos en los que esté anidado (si existe) tienen
Publicaccesibilidad.Matriz unidimensional de uno de los tipos anteriores de esta lista.
Bloques de atributos
Los atributos se especifican en bloques de atributos. Cada bloque de atributo se delimita por corchetes angulares ("<>") y se pueden especificar varios atributos en una lista separada por comas dentro de un bloque de atributos o en varios bloques de atributos. El orden en el que se especifican los atributos no es significativo. Por ejemplo, los bloques <A, B>de atributos , <A> <B><B, A>y <B> <A> son todos equivalentes.
Attributes
: AttributeBlock+
;
AttributeBlock
: LineTerminator? '<' AttributeList LineTerminator? '>' LineTerminator?
;
AttributeList
: Attribute ( Comma Attribute )*
;
Attribute
: ( AttributeModifier ':' )? SimpleTypeName
( OpenParenthesis AttributeArguments? CloseParenthesis )?
;
AttributeModifier
: 'Assembly' | 'Module'
;
Es posible que no se especifique un atributo en un tipo de declaración que no admita y es posible que no se especifiquen atributos de uso único más de una vez en un bloque de atributos. En el ejemplo siguiente se producen errores porque intenta usar HelpString en la interfaz Interface1 y más de una vez en la declaración de Class1.
<AttributeUsage(AttributeTargets.Class)> _
Public Class HelpStringAttribute
Inherits System.Attribute
Private InternalValue As String
Public Sub New(value As String)
Me.InternalValue = value
End Sub
Public ReadOnly Property Value() As String
Get
Return InternalValue
End Get
End Property
End Class
' Error: HelpString only applies to classes.
<HelpString("Description of Interface1")> _
Interface Interface1
Sub Sub1()
End Interface
' Error: HelpString is single-use.
<HelpString("Description of Class1"), _
HelpString("Another description of Class1")> _
Public Class Class1
End Class
Un atributo consta de un modificador de atributo opcional, un nombre de atributo, una lista opcional de argumentos posicionales y inicializadores de variable/propiedad. Si no hay parámetros ni inicializadores, se pueden omitir los paréntesis. Si un atributo tiene un modificador, debe estar en un bloque de atributos en la parte superior de un archivo de origen.
Si un archivo de origen contiene un bloque de atributos en la parte superior del archivo que especifica atributos para el ensamblado o módulo que contendrá el archivo de origen, cada atributo del bloque de atributos debe tener como prefijo tanto el Assembly modificador o Module como dos puntos.
Nombres de atributo
El nombre de un atributo especifica una clase de atributo. Por convención, las clases de atributo se denominan con el sufijo Attribute. En el uso de un atributo se puede incluir u omitir este sufijo. Por consiguiente, el nombre de una clase de atributo que corresponde a un identificador de atributo es el propio identificador o la concatenación del identificador calificado y Attribute. Cuando el compilador resuelve un nombre de atributo, se anexa Attribute al nombre e intenta la búsqueda. Si se produce un error en esa búsqueda, el compilador intenta la búsqueda sin el sufijo. Por ejemplo, los usos de una clase SimpleAttribute de atributo pueden omitir el Attribute sufijo, lo que reduce el nombre a Simple:
<Simple> Class Class1
End Class
<Simple> Interface Interface1
End Interface
El ejemplo anterior es semánticamente equivalente a lo siguiente:
<SimpleAttribute> Class Class1
End Class
<SimpleAttribute> Interface Interface1
End Interface
En general, se prefieren los atributos denominados con el sufijo Attribute . En el ejemplo siguiente se muestran dos clases de atributo denominadas T y T``Attribute.
<AttributeUsage(AttributeTargets.All)> _
Public Class T
Inherits System.Attribute
End Class
<AttributeUsage(AttributeTargets.All)> _
Public Class TAttribute
Inherits System.Attribute
End Class
' Refers to TAttribute.
<T> Class Class1
End Class
' Refers to TAttribute.
<TAttribute> Class Class2
End Class
Tanto el bloque <T> de atributos como el bloque <TAttribute> de atributos hacen referencia a la clase de atributo denominada TAttribute. No es posible usar T como atributo hasta que quite la declaración de la clase TAttribute.
Argumentos de atributo
Los argumentos de un atributo pueden tener dos formas: argumentos posicionales e inicializadores de variable o propiedad de instancia. Los argumentos posicionales al atributo deben preceder a los inicializadores de propiedad o variable de instancia. Un argumento posicional consta de una expresión constante, una expresión unidimensional de creación de matrices o una GetType expresión. Un inicializador de propiedad o variable de instancia consta de un identificador, que puede coincidir con palabras clave, seguidos de dos puntos y un signo igual, y terminados por una expresión constante o una GetType expresión.
Dado un atributo con la clase Tde atributo , la lista de argumentos posicionales y la lista PNde inicializadores de variables o propiedades de instancia, estos pasos determinan si los argumentos son válidos:
Siga los pasos de procesamiento en tiempo de compilación para compilar una expresión del formulario
New T(P). Esto da como resultado un error en tiempo de compilación o determina un constructor enTque es más aplicable a la lista de argumentos.Si el constructor determinado en el paso 1 tiene parámetros que no son tipos de atributo o no es accesible en el sitio de declaración, se produce un error en tiempo de compilación.
Para cada inicializador
Argde propiedad o variable de instancia enN, vamosNamea ser el identificador del inicializadorArgde propiedad o variable de instancia .Namedebe identificar una propiedad sin parámetros oPublicuna variable de instancia que noSharedsea grabable o sin parámetros enTcuyo tipo sea un tipo de atributo. SiTno tiene ninguna variable o propiedad de instancia, se produce un error en tiempo de compilación.
Por ejemplo:
<AttributeUsage(AttributeTargets.All)> _
Public Class GeneralAttribute
Inherits Attribute
Public Sub New(x As Integer)
End Sub
Public Sub New(x As Double)
End Sub
Public y As Type
Public Property z As Integer
Get
End Get
Set
End Set
End Property
End Class
' Calls the first constructor.
<General(10, z:=30, y:=GetType(Integer))> _
Class C1
End Class
' Calls the second constructor.
<General(10.5, z:=10)> _
Class C2
End Class
Los parámetros de tipo no se pueden usar en ningún lugar de los argumentos de atributo. Sin embargo, se pueden usar tipos construidos:
<AttributeUsage(AttributeTargets.All)> _
Class A
Inherits System.Attribute
Public Sub New(t As Type)
End Sub
End Class
Class List(Of T)
' Error: attribute argument cannot use type parameter
<A(GetType(T))> Dim t1 As T
' OK: closed type
<A(GetType(List(Of Integer)))> Dim y As Integer
End Class
AttributeArguments
: AttributePositionalArgumentList
| AttributePositionalArgumentList Comma VariablePropertyInitializerList
| VariablePropertyInitializerList
;
AttributePositionalArgumentList
: AttributeArgumentExpression? ( Comma AttributeArgumentExpression? )*
;
VariablePropertyInitializerList
: VariablePropertyInitializer ( Comma VariablePropertyInitializer )*
;
VariablePropertyInitializer
: IdentifierOrKeyword ColonEquals AttributeArgumentExpression
;
AttributeArgumentExpression
: ConstantExpression
| GetTypeExpression
| ArrayExpression
;
Visual Basic language spec