VB.NET Advanced Topics: Attributes

Leveraging metadata in Visual Basic for enhanced code functionality.

Attributes provide a powerful mechanism for adding declarative metadata to your code elements in Visual Basic .NET. This metadata can be accessed at runtime through reflection, enabling various frameworks and tools to modify or enhance the behavior of your code without directly altering its core logic.

What are Attributes?

Attributes are classes that derive from the System.Attribute base class. They are applied to code elements like classes, methods, properties, assemblies, and more, using square brackets [ ]. Attributes are essentially custom data that can be associated with your code.

Commonly Used Attributes

The .NET Framework provides a rich set of built-in attributes, and you can also create your own custom attributes.

Built-in Attributes

Creating Custom Attributes

To create a custom attribute, you simply define a class that inherits from System.Attribute. It's a convention to end the class name with "Attribute", although you can omit this suffix when applying the attribute.

Example: A Simple Custom Attribute

Code:

Imports System

' Define the custom attribute
<AttributeUsage(AttributeTargets.Class Or AttributeTargets.Method)>
Public Class DeveloperInfoAttribute
    Inherits Attribute

    Public ReadOnly Property Name As String
    Public Property Version As String

    Public Sub New(ByVal name As String)
        Me.Name = name
        Me.Version = "1.0" ' Default version
    End Sub
End Class

' Apply the custom attribute
<DeveloperInfo("Alice", Version:="2.0")>
Public Class MyClass
    <DeveloperInfo("Bob")>
    Public Sub MyMethod()
        Console.WriteLine("This is MyMethod.")
    End Sub
End Class

Applying Attributes

Attributes are applied using square brackets before the declaration of the element they are decorating.

Syntax:

Syntax[AttributeName(positional_arguments, named_arguments: = value)]
Public Class MyClass
    ' ...
End Class

You can specify the target element for the attribute using the AttributeUsage attribute. This controls where your custom attribute can be applied (e.g., classes, methods, properties).

Accessing Attributes with Reflection

The true power of attributes lies in accessing them at runtime using reflection. You can inspect code elements to retrieve associated attributes and their values.

Example: Reading Attribute Data

Code:

CodeImports System
Imports System.Reflection

Module MainModule
    Sub Main()
        Dim type As Type = GetType(MyClass)

        ' Get attributes applied to the class
        Dim classAttributes = type.GetCustomAttributes(GetType(DeveloperInfoAttribute), False)
        If classAttributes.Length > 0 Then
            Dim developerInfo = DirectCast(classAttributes(0), DeveloperInfoAttribute)
            Console.WriteLine($"Class '{type.Name}' developed by: {developerInfo.Name}, Version: {developerInfo.Version}")
        End If

        ' Get attributes applied to a method
        Dim methodInfo As MethodInfo = type.GetMethod("MyMethod")
        Dim methodAttributes = methodInfo.GetCustomAttributes(GetType(DeveloperInfoAttribute), False)
        If methodAttributes.Length > 0 Then
            Dim developerInfo = DirectCast(methodAttributes(0), DeveloperInfoAttribute)
            Console.WriteLine($"Method '{methodInfo.Name}' developed by: {developerInfo.Name}, Version: {developerInfo.Version}")
        End If
    End Sub
End Module

Use Cases for Attributes

Attribute Targets

The AttributeUsage attribute allows you to specify which code elements your custom attribute can be applied to. Common targets include:

Target Description
AttributeTargets.Class Classes, structures, interfaces, enumerations, delegates.
AttributeTargets.Method Methods.
AttributeTargets.Property Properties.
AttributeTargets.Field Fields.
AttributeTargets.Assembly Assemblies.
AttributeTargets.All All applicable targets.

You can combine multiple targets using the bitwise OR operator (Or).

Learn More