Reflection in VB.NET
Reflection is a powerful feature of the .NET Framework that allows you to inspect the metadata of assemblies, modules, and types at runtime. It enables you to dynamically discover information about types, such as their properties, methods, events, and fields, and to invoke methods or access fields at runtime. This is particularly useful for building generic applications, such as serializers, object browsers, and data-binding frameworks.
Core Concepts
Reflection primarily involves the use of types from the System.Reflection
namespace. Key types include:
Assembly
: Represents an assembly. You can load assemblies dynamically and then examine their contents.Type
: Represents type declarations, such as classes, interfaces, arrays, value types, enums, and type parameters.MethodInfo
: Provides information about methods and allows their invocation.PropertyInfo
: Provides information about properties and allows their get/set operations.FieldInfo
: Provides information about fields and allows their get/set operations.ConstructorInfo
: Provides information about constructors and allows object instantiation.
Getting a Type
There are several ways to obtain a Type
object:
- Using the
GetType()
method on an object instance. - Using the
GetType(String)
method on theType
class, passing the fully qualified name of the type. - Using the
TypeOf...Is
operator (for type checking).
Example of getting a type:
Imports System
Imports System.Reflection
Module ReflectionDemo
Sub Main()
' Get Type from an object instance
Dim myString As String = "Hello Reflection"
Dim stringType As Type = myString.GetType()
Console.WriteLine($"Type of myString: {stringType.FullName}")
' Get Type by name
Dim dateTimeType As Type = Type.GetType("System.DateTime")
If dateTimeType IsNot Nothing Then
Console.WriteLine($"Type of DateTime: {dateTimeType.FullName}")
Else
Console.WriteLine("System.DateTime type not found.")
End If
' Get Type from the current assembly
Dim currentAssemblyType As Type = GetType(ReflectionDemo)
Console.WriteLine($"Type of current module: {currentAssemblyType.FullName}")
End Sub
End Module
Discovering Members
Once you have a Type
object, you can discover its members:
GetMembers()
: Retrieves all public members of the current Type.GetMethods()
: Retrieves all public methods.GetProperties()
: Retrieves all public properties.GetFields()
: Retrieves all public fields.GetConstructors()
: Retrieves all public constructors.
You can also specify binding flags to retrieve non-public members or members declared on base types.
Invoking Methods
The MethodInfo
object allows you to invoke methods on an instance of a type.
Example: Invoking a Method
This example shows how to get a method by name and invoke it.
Imports System
Imports System.Reflection
Public Class MyCalculator
Public Function Add(a As Integer, b As Integer) As Integer
Return a + b
End Function
End Class
Module ReflectionInvokeDemo
Sub Main()
Dim calc As New MyCalculator()
Dim calcType As Type = calc.GetType()
' Get the Add method
Dim addMethod As MethodInfo = calcType.GetMethod("Add", New Type() {GetType(Integer), GetType(Integer)})
If addMethod IsNot Nothing Then
' Invoke the method
Dim result As Object = addMethod.Invoke(calc, New Object() {5, 10})
Console.WriteLine($"Result of Add(5, 10): {result}") ' Output: 15
Else
Console.WriteLine("Add method not found.")
End If
End Sub
End Module
Accessing Properties and Fields
Similar to methods, PropertyInfo
and FieldInfo
objects are used to get and set property/field values.
Example: Accessing Properties
This example demonstrates getting and setting a public property.
Imports System
Imports System.Reflection
Public Class Person
Public Property Name As String
Public Property Age As Integer
End Class
Module ReflectionPropertyDemo
Sub Main()
Dim person As New Person()
Dim personType As Type = person.GetType()
' Get the Name property
Dim nameProperty As PropertyInfo = personType.GetProperty("Name")
If nameProperty IsNot Nothing Then
nameProperty.SetValue(person, "Alice")
Dim retrievedName As Object = nameProperty.GetValue(person)
Console.WriteLine($"Person's Name: {retrievedName}") ' Output: Alice
End If
' Get the Age property
Dim ageProperty As PropertyInfo = personType.GetProperty("Age")
If ageProperty IsNot Nothing Then
ageProperty.SetValue(person, 30)
Dim retrievedAge As Object = ageProperty.GetValue(person)
Console.WriteLine($"Person's Age: {retrievedAge}") ' Output: 30
End If
End Sub
End Module
Use Cases for Reflection
- Serialization: Inspecting object state to save and load it.
- Object Browsers and Designers: Dynamically displaying type information.
- Data Binding: Connecting UI elements to object properties.
- Testing Frameworks: Discovering and invoking test methods.
- Plugin Architectures: Loading and interacting with external assemblies.
Performance Considerations
While powerful, reflection can be slower than direct member access. This is due to the overhead of dynamically looking up types and members at runtime. For performance-critical sections of code, consider caching reflection information or using direct access where possible. For typical application scenarios, the performance impact is often negligible.
Security Considerations
Reflection can bypass traditional access control. If you grant a user permission to use reflection, they might be able to access or invoke members that would normally be restricted. Therefore, use reflection cautiously, especially in security-sensitive applications.