VB.NET-字符串和委托字典

VB.NET-字符串和委托字典,vb.net,command-line,dictionary,delegates,Vb.net,Command Line,Dictionary,Delegates,我试图创建一个程序,从用户那里输入一个命令,例如“add24”,然后根据该命令调用一个方法。因此,我输入命令字符串“add24”,然后解析器读取第一个单词“add”,并将其作为例程的名称输出,将该例程名称发送给另一个带有参数的子例程,然后调用相关子例程 从本质上讲,我试图避免这种情况: Select Case RoutineName.ToUpper Case "ADD" Add(Param1, Param2) Case "SUBTRACT" Sub

我试图创建一个程序,从用户那里输入一个命令,例如“add24”,然后根据该命令调用一个方法。因此,我输入命令字符串“add24”,然后解析器读取第一个单词“add”,并将其作为例程的名称输出,将该例程名称发送给另一个带有参数的子例程,然后调用相关子例程

从本质上讲,我试图避免这种情况:

Select Case RoutineName.ToUpper
    Case "ADD"
        Add(Param1, Param2)
    Case "SUBTRACT"
        Subtract(Param1, Param2)
    Case "MULTIPLY"
        Multiply(Param1, Param2)
    ...
因为我希望能够轻松地向新子对象添加引用,而无需不断更新选择语句

我看到其他人也有同样的问题:但我无法理解他的问题的任何答案,或者它们不在VB中。一个人建议使用一本代表字典,以字符串作为键。这听起来是个好主意,但代表们让我很困惑:有人能告诉我这个解决方案是如何实现的吗?

你必须看看。网上搜索VB.NET中也有很多例子。 我建议的策略是让一个类实现函数
Add-Subtract
等,并使用反射GetMethod()和Invoke()根据命令字符串调用它们

例如:

Type type = calcobject.GetType();
MethodInfo method = type.GetMethod(RoutineName);
if (method != null)
{
    method.Invoke(this, ...parameters...);
}

使用委托字典可能更好,但它不能满足自动绑定的要求:当您决定扩展解释器理解的函数时,需要在字典中手动添加新函数。你甚至可以自动填写字典;但是在本例中,反射再次出现。

我使用了数组,以防您希望向函数传递数量可变的参数。不过你不必这么做

Dim methods As New Dictionary(Of String, Func(Of Double(), Double))
Dim results as double

methods.Add("Add", Function(values() As Double) values(0) + values(1))
methods.Add("Sub", Function(values() As Double) values(0) - values(1))
methods.Add("Mul", Function(values() As Double) values(0) * values(1))
methods.Add("Div", Function(values() As Double) values(0) / values(1))

results = methods("Add")(New Double() {1, 2})
results = methods("Sub")(New Double() {5, 3})
results = methods("Mul")(New Double() {4, 8})
results = methods("Div")(New Double() {1, 2})
没有阵列

Dim methods As New Dictionary(Of String, Func(Of Double, Double, Double))

methods.Add("Add", Function(a As Double, b As Double)
                       Return a + b
                   End Function)

methods.Add("Sub", Function(a As Double, b As Double)
                       Return a - b
                   End Function)

methods.Add("Mul", Function(a As Double, b As Double)
                       Return a * b
                   End Function)

methods.Add("Div", Function(a As Double, b As Double)
                       Return a / b
                   End Function)

results = methods("Add")(1, 2)
results = methods("Sub")(5, 3)
results = methods("Mul")(4, 8)
results = methods("Div")(1, 2)

“或者它们不在VB中”:将它们转换为VB,这很容易,因为您实际上使用的是与c#相同的基础结构。另外,请看一下如何使用Func@FelicePollano我试着把其中一个答案翻译成C#,但是没有用,我也不明白原来的代码在做什么,所以我不知道如何使它起作用——然后我觉得打断别人的问题很粗鲁:呸,谢谢你,我没有想过使用Lambda表达式!我想我可以同样轻松地使用Sub,而不是调用单独例程的函数:3。谢谢,这看起来正是我需要的!嘿,谢谢你,我已经让你的例子开始工作了,但是有一个问题:Invoke的第二个参数需要引用类型,而不是值类型。所以,即使这个方法使用整数,我仍然必须使用其他东西来存储参数,显然要使用的是对象。。。但这似乎不是一个非常优雅的解决方案。有没有办法在这个方法中使用引用类型?第二个参数是一个对象数组。数组的每一项都是一个参数OK。还有一个问题——这在一个类内有效,但我无法在一个类外解决如何做到这一点。我只想有一个泛型子函数或函数,并使用reflectionMaybe引用它@Ceres答案在这种情况下对您来说更有趣。除此之外,反射也适用于静态类。我喜欢他的答案,并且我成功地实现了该实现,但是尽管dictionary方法很简洁,我想知道如何使用反射,以便扩展功能所需做的就是添加新的子例程和函数,而不是为每个例程向字典中添加新成员。