选择任一功能

时间:2012-09-14 08:53:18

标签: c# .net

让我举一个例子,试着解释一下我想问的问题:

假设我有一个名为Func1Func2Fucn3的函数......等等。所有这些功能都有相同的签名。然后,还有另一个函数Call(String str)。现在基于传递给Call的参数,我想调用三个函数中的一个。即如果str == "Func1"调用Func1,如果str == "Func2"调用Func2,如果str == "Func3"调用Func3 ......依此类推。有没有办法在不使用条件语句的情况下执行此操作?

5 个答案:

答案 0 :(得分:2)

你可以使用多态性。

如果有几个类实现相同的接口,则可以将具有所需行为的对象传递给函数并直接调用它,因为行为将封装在传入的对象中。

有关示例和详细信息,请参阅strategy pattern

答案 1 :(得分:2)

实现这一目标的一种方法是进行某种表查找:

//assuming your functions receive string and return int

Dictionary<string, Func<string, int>> methods = {
    {"Func1", Func1},
    {"Func2", Func2},
    {"Func3", Func3}
}

void call(String input){
    if (methods.HasKey(input)){
       int result = methods[input]("I'm a parameter");
    }
}

另一种方法是使用反射:

void call(String input){
    var func = yourobject.GetType().GetMethod(input);
    if (func!=null){
        int result = func.Invoke(object, "I'm a parameter");
    }
}

第一种方法有点冗长,但您可以完全控制哪些函数映射到哪些字符串。后一种方法需要较少的代码,但应谨慎使用。

答案 2 :(得分:1)

在这些情况下if-else的常用替代方法是switch。例如:

switch (str) {
    case "Func1": Func1(); break;
    case "Func2": Func2(); break;
    default:
        throw new ArgumentException("Unrecognised function name", "str");
        break;
}

这可能会也可能不会产生比ifelse if系列更有效的代码,具体取决于编译器的智能程度(我从未研究过它,尽管我&#39;我现在很感兴趣。)

另一种方法是从Perl借用一个想法:创建一个Dictionary<string, Func<Whatever>>并为其添加不同键值的条目,然后在需要时可以在其中查找所需的函数对象。

答案 3 :(得分:1)

你也可以使用代表。示例代码

   delegate int Arithm(int x, int y);

public class CSharpApp
{
    static void Main()
    {
        DoOperation(10, 2, Multiply);
        DoOperation(10, 2, Divide);
    }

    static void DoOperation(int x, int y, Arithm del)
    {
        int z = del(x, y);
        Console.WriteLine(z);
    }

    static int Multiply(int x, int y)
    {
        return x * y;
    }

    static int Divide(int x, int y)
    {
        return x / y;
    }
} 

答案 4 :(得分:0)

你可以使用switch或select语句,  如下所示

Between the button Sub and End Sub code add the folowing

Dim creamcake As String
 Dim DietState As String

creamcake = TextBox1.Text

Select Case creamcake

Case "Eaten"
DietState = "Diet Ruined"
Case "Not Eaten"
DietState = "Diet Not Ruined"
Case Else
DietState = "Didn't check"


End Select

MsgBox DietState