Notatka
Dostęp do tej strony wymaga autoryzacji. Może spróbować zalogować się lub zmienić katalogi.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Język Visual Basic umożliwia programistom określanie modyfikatorów deklaracji, które reprezentują informacje o zadeklarowanych jednostkach. Na przykład umieszczenie metody klasy z modyfikatorami Public, Protected, Friend, Protected Friendlub Private określa jej dostępność.
Oprócz modyfikatorów zdefiniowanych przez język język Visual Basic umożliwia również programistom tworzenie nowych modyfikatorów, nazywanych atrybutami i używanie ich podczas deklarowania nowych jednostek. Te nowe modyfikatory zdefiniowane za pomocą deklaracji klas atrybutów są następnie przypisywane do jednostek za pomocą bloków atrybutów.
Uwaga. Atrybuty mogą być pobierane w czasie wykonywania za pośrednictwem interfejsów API odbicia programu .NET Framework. Te interfejsy API wykraczają poza zakres tej specyfikacji.
Na przykład struktura może definiować Help atrybut, który można umieścić w elementach programu, takich jak klasy i metody, aby zapewnić mapowanie z elementów programu do dokumentacji, jak pokazano w poniższym przykładzie:
<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
W przykładzie zdefiniowano klasę atrybutów o nazwie HelpAttributelub Help na krótko, która ma jeden parametr pozycyjny (UrlValue) i jeden nazwany argument (Topic).
W następnym przykładzie pokazano kilka zastosowań atrybutu:
<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
Następny przykład sprawdza, czy Class1 ma Help atrybut, i zapisuje skojarzone wartości Topic i Url jeśli atrybut jest obecny.
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
Klasy atrybutów
Klasa atrybutów jest klasą niegeneryjną, która pochodzi z System.Attribute klasy i nie MustInheritjest . Klasa atrybutów może mieć System.AttributeUsage atrybut, który deklaruje, co atrybut jest prawidłowy, czy może być używany wiele razy w deklaracji i czy jest dziedziczony. W poniższym przykładzie zdefiniowano klasę atrybutów o nazwie SimpleAttribute , którą można umieścić w deklaracjach klas i deklaracjach interfejsu:
<AttributeUsage(AttributeTargets.Class Or AttributeTargets.Interface)> _
Public Class SimpleAttribute
Inherits System.Attribute
End Class
W następnym przykładzie pokazano kilka zastosowań atrybutu Simple . Mimo że klasa atrybutów ma nazwę SimpleAttribute, użycie tego atrybutu może pominąć Attribute sufiks, skracając w ten sposób nazwę na Simple:
<Simple> Class Class1
End Class
<Simple> Interface Interface1
End Interface
Jeśli atrybut nie ma atrybutu System.AttributeUsage, atrybut można umieścić na dowolnym obiekcie docelowym (odpowiednik AttributeTargets.All). Atrybut System.AttributeUsage ma inicjator zmiennej , który określa, AllowMultipleczy wskazany atrybut można określić więcej niż raz dla danej deklaracji. Jeśli AllowMultiple dla atrybutu jest True, jest to klasa atrybutów wielokrotnego użycia i może być określona więcej niż raz w deklaracji. Jeśli AllowMultiple atrybut jest False lub nieokreślony dla atrybutu, jest to klasa atrybutów pojedynczego użycia i może być określona co najwyżej raz w deklaracji.
W poniższym przykładzie zdefiniowano klasę atrybutów wielokrotnego użycia o nazwie 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
W przykładzie pokazano deklarację klasy z dwoma zastosowaniami atrybutu Author :
<Author("Maria Hammond"), Author("Ramesh Meyyappan")> _
Class Class1
End Class
Atrybut System.AttributeUsage ma publiczną zmienną wystąpienia , Inheritedktóra określa, czy atrybut, po określeniu w typie podstawowym, jest również dziedziczony przez typy pochodzące z tego typu podstawowego. Jeśli publiczna zmienna Inherited wystąpienia nie jest inicjowana, zostanie użyta wartość domyślna False . Właściwości i zdarzenia nie dziedziczą atrybutów, chociaż metody zdefiniowane przez właściwości i zdarzenia działają. Interfejsy nie dziedziczą atrybutów.
Jeśli atrybut pojedynczego użycia jest dziedziczony i określony w typie pochodnym, atrybut określony w typie pochodnym zastępuje dziedziczony atrybut. Jeśli atrybut wielokrotnego użycia jest dziedziczony i określony w typie pochodnym, oba atrybuty są określone w typie pochodnym. Przykład:
<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
Parametry pozycyjne atrybutu są definiowane przez parametry publicznych konstruktorów klasy atrybutów. Parametry pozycyjne muszą być ByVal i mogą nie określać ByRef. Zmienne i właściwości wystąpienia publicznego są definiowane przez publiczne właściwości odczytu i zapisu lub zmienne wystąpienia klasy atrybutu. Typy, które mogą być używane w parametrach pozycyjnych i publicznych zmiennych wystąpień i właściwości, są ograniczone do typów atrybutów. Typ jest typem atrybutu, jeśli jest to jeden z następujących elementów:
Dowolny typ pierwotny z wyjątkiem i
DateDecimal.Typ
Object.Typ
System.Type.Typ wyliczony, pod warunkiem, że jest on i typy, w których jest zagnieżdżona (jeśli istnieje) mają
Publicułatwienia dostępu.Jednowymiarowa tablica jednego z poprzednich typów na tej liście.
Bloki atrybutów
Atrybuty są określane w blokach atrybutów. Każdy blok atrybutów jest rozdzielany nawiasami kątowymi ("<>"), a wiele atrybutów można określić na liście rozdzielanej przecinkami w bloku atrybutu lub w wielu blokach atrybutów. Kolejność, w której określono atrybuty, nie jest znacząca. Na przykład atrybut bloki <A, B>, <B, A><A> <B> i <B> <A> są równoważne.
Attributes
: AttributeBlock+
;
AttributeBlock
: LineTerminator? '<' AttributeList LineTerminator? '>' LineTerminator?
;
AttributeList
: Attribute ( Comma Attribute )*
;
Attribute
: ( AttributeModifier ':' )? SimpleTypeName
( OpenParenthesis AttributeArguments? CloseParenthesis )?
;
AttributeModifier
: 'Assembly' | 'Module'
;
Atrybut może nie być określony w rodzaju deklaracji, który nie obsługuje, a atrybuty pojedynczego użycia mogą nie być określone więcej niż raz w bloku atrybutów. Poniższy przykład powoduje błędy zarówno dlatego, że próbuje użyć HelpString w interfejsie Interface1 , jak i więcej niż raz w deklaracji 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
Atrybut składa się z opcjonalnego modyfikatora atrybutów, nazwy atrybutu, opcjonalnej listy argumentów pozycyjnych i inicjatorów zmiennych/właściwości. Jeśli nie ma parametrów ani inicjatorów, nawiasy mogą zostać pominięte. Jeśli atrybut ma modyfikator, musi znajdować się w bloku atrybutów w górnej części pliku źródłowego.
Jeśli plik źródłowy zawiera blok atrybutów w górnej części pliku, który określa atrybuty zestawu lub modułu, który będzie zawierać plik źródłowy, każdy atrybut w bloku atrybutów musi być poprzedzony zarówno Assembly modyfikatorem, Module jak i dwukropkiem.
Nazwy atrybutów
Nazwa atrybutu określa klasę atrybutów. Zgodnie z konwencją klasy atrybutów mają nazwę z sufiksem Attribute. Użycie atrybutu może zawierać lub pomijać ten sufiks. W związku z tym nazwa klasy atrybutu, która odpowiada identyfikatorowi atrybutu, jest samym identyfikatorem lub łączeniem kwalifikowanego identyfikatora i Attribute. Gdy kompilator rozpozna nazwę atrybutu, dołącza Attribute ją do nazwy i próbuje wyszukać. Jeśli wyszukiwanie zakończy się niepowodzeniem, kompilator spróbuje wyszukać bez sufiksu. Na przykład użycie klasy SimpleAttribute atrybutów może pominąć Attribute sufiks, skracając w ten sposób nazwę na Simple:
<Simple> Class Class1
End Class
<Simple> Interface Interface1
End Interface
Powyższy przykład jest semantycznie równoważny z następującymi elementami:
<SimpleAttribute> Class Class1
End Class
<SimpleAttribute> Interface Interface1
End Interface
Ogólnie rzecz biorąc, preferowane są atrybuty o nazwie z sufiksem Attribute . W poniższym przykładzie przedstawiono dwie klasy atrybutów o nazwach T i 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
Blok atrybutów <T> i blok <TAttribute> atrybutów odwołują się do klasy atrybutów o nazwie TAttribute. Nie można użyć T jako atrybutu, dopóki nie usuniesz deklaracji klasy TAttribute.
Argumenty atrybutów
Argumenty atrybutu mogą mieć dwie formy: argumenty pozycyjne i inicjatory zmiennej wystąpienia/właściwości. Wszelkie argumenty pozycyjne atrybutu muszą poprzedzać inicjatory zmiennej wystąpienia/właściwości. Argument pozycyjny składa się z wyrażenia stałego, jednowymiarowego wyrażenia tworzenia tablicy lub GetType wyrażenia. Inicjator zmiennej wystąpienia/właściwości składa się z identyfikatora, który może być zgodny ze słowami kluczowymi, a następnie dwukropkiem i znakiem GetType równości, a następnie zakończonym przez wyrażenie stałe lub wyrażenie.
Biorąc pod uwagę atrybut z klasą Tatrybutów , listą Pargumentów pozycyjnych i listą Ninicjatora zmiennej wystąpienia/właściwości , te kroki określają, czy argumenty są prawidłowe:
Wykonaj kroki przetwarzania w czasie kompilacji, aby skompilować wyrażenie formularza
New T(P). Powoduje to błąd w czasie kompilacji lub określa konstruktor,Tktóry ma największe zastosowanie do listy argumentów.Jeśli konstruktor określony w kroku 1 ma parametry, które nie są typami atrybutów lub są niedostępne w lokacji deklaracji, wystąpi błąd czasu kompilacji.
Dla każdego inicjatora
Argzmiennej wystąpienia/właściwości wNprogramie należy posłużyćNamesię identyfikatorem inicjatoraArgzmiennej wystąpienia/właściwości .Namemusi identyfikowaćSharedwłaściwość nie-, zapisywalną,Publiczmienną wystąpienia lub bez parametrów, naTktórej typ jest typem atrybutu. JeśliTnie ma takiej zmiennej lub właściwości wystąpienia, wystąpi błąd czasu kompilacji.
Przykład:
<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
Parametrów typu nie można używać nigdzie w argumentach atrybutów. Jednak mogą być używane typy skonstruowane:
<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