您可以使用反射为Module 中的方法创建一个委托。我会将创建的委托加载到Dictionary(Of String, Action(Of Int32))。
Action(Of Int32) 被选中是因为它与您指定的带有整数参数的子例程的签名相匹配。
假设你有一个这样定义的Module:
Module SomeModule
Public Sub Sub1(arg As Int32)
Console.WriteLine("Sub1: {0}", arg)
End Sub
Public Sub Sub2(arg As Int32)
Console.WriteLine("Sub2: {0}", arg)
End Sub
End Module
现在创建代理并将其存储在字典中。
Private methods As New Dictionary(Of String, Action(Of Int32))
Sub LoadMethods()
Dim modType As Type = GetType(SomeModule)
Dim mi As Reflection.MethodInfo
mi = modType.GetMethod("Sub1", BindingFlags.Static Or BindingFlags.Public)
methods.Add(mi.Name, CType(mi.CreateDelegate(GetType(Action(Of Int32))), Action(Of Int32)))
mi = modType.GetMethod("Sub2", BindingFlags.Static Or BindingFlags.Public)
methods.Add(mi.Name, CType(mi.CreateDelegate(GetType(Action(Of Int32))), Action(Of Int32)))
End Sub
您可以像这样检索和调用委托:
methods("Sub1")(123)
methods("Sub2")(456)
编辑:我有时会让事情变得复杂。 LoadMethods 方法可以在没有反射的情况下完成,如下所示:
Sub LoadMethods()
methods.Add("Sub1", New Action(Of Int32)(AddressOf SomeModule.Sub1))
methods.Add("Sub2", New Action(Of Int32)(AddressOf SomeModule.Sub1))
End Sub
编辑 2:基于对下面问题和评论的编辑。
编辑:为了让它变得非常简单,我需要相当于 VBA 的:
Application.Run module_name.sub_name 参数
您需要首先根据输入的名称从其包含的程序集中提取Module 类型。然后您可以检索MethodInfo,如上所示。以下示例假定模块包含在执行程序集中,并且实施了最少的检查。它将要求您提供模块名称、方法名称和正确键入的方法参数的数组。在现实世界的场景中,它可能需要获取参数字符串并执行某种类型的动态类型转换,以基于调用 MethodInfo.GetParameters 构建 typedArgs 数组。
Private Shared Sub Exec(moduleName As String, methodName As String, typedArgs As Object())
Dim asm As Reflection.Assembly = Assembly.GetExecutingAssembly
Dim modType As Type = asm.GetType(String.Format("{0}.{1}", asm.GetName.Name, moduleName))
If modType IsNot Nothing Then
Dim mi As Reflection.MethodInfo
mi = modType.GetMethod(methodName, BindingFlags.Static Or BindingFlags.Public)
If mi IsNot Nothing Then
mi.Invoke(Nothing, typedArgs)
End If
End If
End Sub
用法示例:Exec("SomeModule", "Sub1", New Object() {123})