Visual Basic 2012 Voorbeelden
   

visual basic 2012 broncode voorbeelden

Blijf op de hoogte van de recente aanpassingen op vbvoorbeelden!

Microsoft Visual Studio 2012Microsoft Developers Network - Visual BasicMicrosoft .NET Framework

25.2. Zelf Attributen Definiëren

Print Email Deel op Twitter Deel op Facebook

Dit artikel is gepubliceerd op maandag 15 oktober 2012 op vbvoorbeelden, bezoek de website voor een recente versie van dit artikel of andere artikels.

Attributen kunnen ook zelf gedefinieerd worden.  Dit is een vrij eenvoudig werkje, je maakt een eigen attribuutklasse die je doet overerven van de Attribute klasse.   Deze attribuutklasse kan dan gebruikt worden om metadata aan een definitie toe te voegen.

Het is voor de leesbaarheid aan te raden de "Attribute" suffix te gebruiken in de identifier van de attribuutklasse.

Bij de definitie van die klasse plaats je een AttributeUsage attribuut, daar geef je als argumentwaarde een AttributeTargets enumeratiewaarde aan de constructor door om op te geven op welke entiteit de attribuut slaat.
Mogelijkheden zijn : All, Assembly, Class, Constructor, Delegate, Enum, Event, Field, Interface, Method, Module, Parameter, Property, ReturnValue en Struct.  Het zou ook mogelijk zijn om AttributeTargets.Constructor Or AttributeTargets.Method Or AttributeTargets.Property in te stellen.  Dit zou dus bruikbaar zijn om aan te geven dat het attribuut van toepassing kan zijn op de entiteiten constructor, method en/of property.

Het AttributeUsage attribute is dus bruikbaar om bij het definiëren van een attribuutklasse aan te geven waarop het attribuut dat je aan het definiëren bent van toepassing zal zijn.

De volgende argumentwaarden die hier in de voorbeelden lijken doorgegeven te worden aan de constructor van de AttributeUsage klasse zijn eigenlijk geen argumentwaarden.  Ze zijn gewoon een verkorte taalconstructie (met een toekenning via de operator :=) om hier meteen na het instantiëren van dat attribuut de eigenschappen AllowMultiple en Inherited van de AttributeUsage klasse op een bepaalde waarde in te stellen.

Parameter AllowMultiple kan je op True instellen als het attribuut dat je aan het definiëren bent meerder keren kan gebruikt worden op de entiteit(en) die ervoor is/zijn opgegeven.  By default kan een attribuut maar één keer worden toegepast.

Parameter Inherited kan je op False instellen als je wenst dat het attribuut dat je aan het definiëren bent niet zal worden overgeërfd naar subklassen van de klasse waarbij dat attribuut zal gedefinieerd worden.  By default worden attributen overgeërfd.

Bij het definiëren van de constructor van een attribuutklasse ben je beperkt in de mogelijke datatypes voor de parameters van die constructor, namelijk : Byte, Short, Integer, Long, Single, Double, Char, String, Boolean, Type of eender welk enumeratietype.  Dit omdat enkele deze geserialiseerd kunnen worden in de metadata voor de assembly.

Via reflection kan de aan de klasse of aan de members toegevoegde metadata vervolgens weer worden opgespoord en vervolgens op de één of andere manier gebruik van worden gemaakt.
Het opsporen van attributen kan bijvoorbeeld via de classmembers GetCustomAttribute en GetCustomAttributes methods van de Attribute klasse.
Visual Basic 2012 Broncode - Codevoorbeeld 656
<AttributeUsage(AttributeTargets.Class, AllowMultiple:=True, Inherited:=False)> _
Public Class HistoryAttribute : Inherits Attribute : Implements IComparable
    Public Property [Date] As String
    Public Property Author As String
    Public Property Change As String
    Public Sub New(ByVal [date] As String, _
                   ByVal author As String, ByVal change As String)
        Me.Date = [date]
        Me.Author = author
        Me.Change = change
    End Sub
    Public Function CompareTo(ByVal obj As Object) As Integer _
                                         Implements System.IComparable.CompareTo
        If TypeOf obj Is HistoryAttribute Then
            Dim ha As HistoryAttribute = DirectCast(obj, HistoryAttribute)
            Return [Date].CompareTo(ha.Date)
        End If
    End Function
End Class
Public Class ClassInfo
    Public Shared Function GetHistory(ByVal type As Type) As String
        Dim historyAttributes As HistoryAttribute() = _
          DirectCast(Attribute.GetCustomAttributes(type, GetType(HistoryAttribute)),  _
                     HistoryAttribute())
        GetHistory &= "fullname : " & type.FullName & _
                      Environment.NewLine() & Environment.NewLine() & _
                      "history  : " & Environment.NewLine()
        Array.Sort(historyAttributes)
        For Each historyAttribute As HistoryAttribute In historyAttributes
            GetHistory &= "  date   : " & historyAttribute.Date.ToString() & " - " & _
                          "author : " & historyAttribute.Author & _
                          Environment.NewLine() & _
                          "  change : " & historyAttribute.Change & _
                          Environment.NewLine() & Environment.NewLine()
        Next
    End Function
End Class
<History("2008-02-21", "John", "Created this class."), _
History("2008-02-22", "Jane", "Added Method1."), _
History("2008-02-23", "John", "Corrected Method1."), _
History("2008-02-24", "Paul", "Added Method2.")> _
Class Class1
    Public Sub Method1()
        Console.WriteLine("method1")
    End Sub
    Public Sub Method2()
        Console.WriteLine("method2")
    End Sub
End Class
Class Example1
    Public Shared Sub Main()
        Console.WriteLine(ClassInfo.GetHistory(GetType(Class1)))
        '
        Console.ReadLine()
    End Sub
End Class
Console Application Output
fullname : ContentConsoleApplication.Class1

history  :
  date   : 2008-02-21 - author : John
  change : Created this class.

  date   : 2008-02-22 - author : Jane
  change : Added Method1.

  date   : 2008-02-23 - author : John
  change : Corrected Method1.

  date   : 2008-02-24 - author : Paul
  change : Added Method2.
Een ander voorbeeld :
Visual Basic 2012 Broncode - Codevoorbeeld 657
Public Class ContractAttribute : Inherits Attribute
    Private ReadOnly _Text As String
    Public ReadOnly Property Text() As String
        Get
            Text = _Text
        End Get
    End Property
    Public Sub New(ByVal text As String)
        _Text = text
    End Sub
End Class
<AttributeUsage(AttributeTargets.All, AllowMultiple:=False, Inherited:=False)> _
Public Class SummaryAttribute : Inherits ContractAttribute
    Public Sub New(ByVal text As String)
        MyBase.New(text)
    End Sub
End Class
<AttributeUsage(AttributeTargets.Class, AllowMultiple:=True, Inherited:=True)> _
Public Class InvariantAttribute : Inherits ContractAttribute
    Public Sub New(ByVal text As String)
        MyBase.New(text)
    End Sub
End Class
<AttributeUsage(AttributeTargets.Constructor Or AttributeTargets.Method Or _
                AttributeTargets.Property, _
                AllowMultiple:=True, Inherited:=False)> _
Public Class PreConditionAttribute : Inherits ContractAttribute
    Public Sub New(ByVal text As String)
        MyBase.New(text)
    End Sub
End Class
<AttributeUsage(AttributeTargets.Constructor Or AttributeTargets.Method Or _
                AttributeTargets.Property, _
                AllowMultiple:=True, Inherited:=False)> _
Public Class PostConditionAttribute : Inherits ContractAttribute
    Public Sub New(ByVal text As String)
        MyBase.New(text)
    End Sub
End Class
Partial Class ClassInfo
    Public Shared Function GetContract(ByVal type As Type) As String
        Dim summaryAttribute As SummaryAttribute = _
          DirectCast(Attribute.GetCustomAttribute(type, GetType(SummaryAttribute)),  _
                     SummaryAttribute)
        Dim invariantAttributes As InvariantAttribute() = _
          DirectCast(Attribute.GetCustomAttributes(type, GetType(InvariantAttribute)),  _
                     InvariantAttribute())
        GetContract &= "fullname : " & type.FullName & Environment.NewLine() & _
                       "   invariants : " & Environment.NewLine()
        For Each invariantAttribute As InvariantAttribute In invariantAttributes
            GetContract &= "      - " & invariantAttribute.Text & Environment.NewLine()
        Next
        Dim membersInfo As Reflection.MemberInfo() = type.GetMembers()
        For Each memberInfo As Reflection.MemberInfo In membersInfo
            If (memberInfo.MemberType = Reflection.MemberTypes.Method OrElse _
                memberInfo.MemberType = Reflection.MemberTypes.Property OrElse _
                memberInfo.MemberType = Reflection.MemberTypes.Constructor) AndAlso _
                memberInfo.DeclaringType Is type Then
                GetContract &= GetContract(memberInfo)
            End If
        Next
    End Function
    Public Shared Function GetContract(ByVal member As Reflection.MemberInfo) As String
        GetContract &= "   " & member.Name & " : " & Environment.NewLine()
        Dim summary As SummaryAttribute() = _
          DirectCast(member.GetCustomAttributes(GetType(SummaryAttribute), False),  _
                     SummaryAttribute())
        GetContract &= "      summary        : "
        Dim summaryText As String = "-"
        If summary.Length > 0 Then
            summaryText = summary(0).Text
        End If
        GetContract &= summaryText & Environment.NewLine()
        Dim preConditions As PreConditionAttribute() = _
          DirectCast(member.GetCustomAttributes(GetType(PreConditionAttribute), False),  _
                    PreConditionAttribute())
        GetContract &= "      pre-condities  : "
        Dim preConditionText As String
        For Each preCondition As PreConditionAttribute In preConditions
            preConditionText &= Environment.NewLine() & _
                                "                       - " & preCondition.Text
        Next
        If preConditionText = "" Then
            GetContract &= "-" & Environment.NewLine()
        Else
            GetContract &= preConditionText & Environment.NewLine()
        End If
        Dim postConditions As PostConditionAttribute() = _
          DirectCast(member.GetCustomAttributes(GetType(PostConditionAttribute), False),  _
                    PostConditionAttribute())
        GetContract &= "      post-condities : "
        Dim postConditionText As String
        For Each postCondition As PostConditionAttribute In postConditions
            postConditionText &= Environment.NewLine() & _
                                "                       - " & postCondition.Text
        Next
        If postConditionText = "" Then
            GetContract &= "-" & Environment.NewLine()
        Else
            GetContract &= postConditionText & Environment.NewLine()
        End If
    End Function
End Class
Class Assertion
    Public Shared Sub Require(ByVal condition As Boolean)
        If Not condition Then Throw New PreConditionException
    End Sub
    Public Shared Sub Ensure(ByVal condition As Boolean)
        If Not condition Then Throw New PostConditionException
    End Sub
    Public Class PreConditionException : Inherits ApplicationException
    End Class
    Public Class PostConditionException : Inherits ApplicationException
    End Class
End Class
<Summary("Bounded LIFO collection."), _
Invariant("GetCount() >= 0"), _
Invariant("GetSize() >= 2")> _
Class BoundedStack
    Private _Stack As Object()
    Private _Size As Integer
    Private _Count As Integer
    <Summary("Constructor expects capacity (size)."), _
     PreCondition("size > 1"), _
     PostCondition("GetSize() = size")> _
    Public Sub New(ByVal size As Integer)
        Assertion.Require(size > 1)
        _Size = size
        ReDim _Stack(_Size - 1)
        Assertion.Ensure(getSizeQuery() = size AndAlso getCountQuery() = 0)
        Assertion.Ensure(invariant())
    End Sub
    <Summary("GetSize() gets the capacity."), _
     PostCondition("GetSize() > 1")> _
    Public Function GetSize() As Integer
        GetSize = getSizeQuery()
        Assertion.Ensure(GetSize > 1)
        Assertion.Ensure(invariant())
    End Function
    Private Function getSizeQuery() As Integer
        getSizeQuery = _Size
    End Function
    <Summary("GetCount() gets the count."), _
     PostCondition("GetCount() >= 0"), _
     PostCondition("GetCount() <= GetSize()")> _
    Public Function GetCount() As Integer
        GetCount = getCountQuery()
        Assertion.Ensure(GetCount >= 0 AndAlso GetCount <= getSizeQuery())
        Assertion.Ensure(invariant())
    End Function
    Private Function getCountQuery() As Integer
        getCountQuery = _Count
    End Function
    '
    Private Function invariant() As Boolean
        Return getCountQuery() >= 0 AndAlso getSizeQuery() >= 2
    End Function
    ' ...
End Class
Public Class Example2
    Public Shared Sub Main()
        Console.WriteLine(ClassInfo.GetContract(GetType(BoundedStack)))
        '
        Console.ReadLine()
    End Sub
End Class
Console Application Output
fullname : ContentConsoleApplication.BoundedStack
invariants :
   - GetCount() >= 0
   - GetSize() >= 2
GetSize :
   summary        : GetSize() gets the capacity.
   pre-condities  : -
   post-condities :
                    - GetSize() > 1
GetCount :
   summary        : GetCount() gets the count.
   pre-condities  : -
   post-condities :
                    - GetCount() >= 0
                    - GetCount() <= GetSize()
.ctor :
   summary        : Constructor expects capacity (size).
   pre-condities  :
                    - size > 1
   post-condities :
                    - GetSize() = size

Dit artikel is gepubliceerd op maandag 15 oktober 2012 op vbvoorbeelden, bezoek de website voor een recente versie van dit artikel of andere artikels.