Reflection, Attributes and Late Binding
32.1 Reflection
Imports System.Reflection
Dim t As Type = GetType(Customer)
Console.WriteLine(t.FullName)
For Each prop In t.GetProperties()
Console.WriteLine($"{prop.Name}: {prop.PropertyType.Name}")
Next
For Each m In t.GetMethods(BindingFlags.Public Or BindingFlags.Instance Or BindingFlags.DeclaredOnly)
Console.WriteLine(m.Name)
Next
Dim obj = Activator.CreateInstance(t) ' create an instance dynamically
t.GetProperty("Name").SetValue(obj, "Ana")
Console.WriteLine(t.GetProperty("Name").GetValue(obj))
Dim result = t.GetMethod("ToString").Invoke(obj, Nothing)
Dim asm = Assembly.LoadFrom("Plugins\MyPlugin.dll") ' plugin loading
Dim plugins = asm.GetTypes().Where(Function(x) GetType(IPlugin).IsAssignableFrom(x) AndAlso Not x.IsAbstract)32.2 Attributes
Common attributes: <Obsolete>, <Serializable>, <Flags>, <DebuggerDisplay>, <DllImport>, <Conditional("DEBUG")>, <JsonPropertyName>, <Required> / <Range> / <StringLength> (DataAnnotations), <TestMethod>, <STAThread>.
<Obsolete("Use NewMethod instead", False)>
Public Sub OldMethod()
End Sub
<Serializable>
Public Class Data
End Class
' Custom attribute
<AttributeUsage(AttributeTargets.Property, AllowMultiple:=False)>
Public Class ColumnAttribute
Inherits Attribute
Public ReadOnly Property Name As String
Public Property Required As Boolean
Public Sub New(name As String)
Me.Name = name
End Sub
End Class
Public Class Employee
<Column("emp_name", Required:=True)>
Public Property Name As String
End Class
Dim attr = GetType(Employee).GetProperty("Name").GetCustomAttribute(Of ColumnAttribute)()
Console.WriteLine($"{attr.Name}, required={attr.Required}")32.3 Late Binding (Option Strict Off)
VB's late binding is simpler than C#'s dynamic. It's useful for COM/Office interop without interop assemblies, but you lose compile-time safety. Isolate late-bound code in a separate file with Option Strict Off at its top.
CallByName(obj, "MethodName", CallType.Method, args) invokes a member by its string name.
Option Strict Off
Dim excel As Object = CreateObject("Excel.Application") ' COM late binding
excel.Visible = True
Dim wb = excel.Workbooks.Add()
wb.Sheets(1).Range("A1").Value = "Hello"
' Members are resolved at runtime: no IntelliSense, runtime errors on typos