如何使用字符串数组来处理C#中switch语句中的case?

时间:2015-04-22 17:27:46

标签: c# arrays

我有一个数组

    public static string[] commands =
    {   
        "command1",
        "command2",
        "command3",
        "command4",
        "command5",
        "command6",
        "command7"
    };

我想在函数

中使用数组
    public static bool startCommand (string commandName) {
        //stuff
        if (commandName == commands[0]) {
            //stuff
            return true;
        }
        else {
            //stuff
            switch (commandName) {
                case commands [1]:
                    //stuff
                    break;
                case commands [2]:
                    //stuff
                    break;
                case commands [3]:
                    //stuff
                    break;
                case commands [4]:
                    //stuff
                    break;
                case commands [5]:
                    //stuff
                    break;
                case commands [6]:
                    //stuff
                    break;
                default:
                    return false;
            }
            //do stuff
            return true;
        }
    }

这给我的错误是“每个案例都有一个常数值”。

我可以使用if和else语句,但我认为switch语句看起来更好。

除非我错过了我的标记,否则我的数组是常量字符串,所以这应该有效。任何帮助,将不胜感激。很抱歉,如果这是一个新问题,我已经用C#编程了大约四天。

5 个答案:

答案 0 :(得分:7)

您正在寻找的是Dictionary<TKey, TValue>类型。 Dictionary基本上是键值对的集合,我们可以利用它来实现您想要实现的目标。

使用您给出的示例,实现方式如下:

Dictionary<string, Action> commandsDictionary = new Dictionary<string, Action>();
commandsDictionary.Add("Command1", () => Console.WriteLine("Command 1 invoked"));
commandsDictionary.Add("Command2", () => Console.WriteLine("Command 2 invoked"));

commandsDictionary["Command2"].Invoke();
// Command 2 invoked

正如您已经注意到的那样,我已经介绍了一个没有任何参数的Action委托。

要引入参数,只需将其指定为类型参数,如下所示:Action<int>

Dictionary<string, Action<int>> commandsDictionary = new Dictionary<string, Action<int>>();
commandsDictionary.Add("Command1", (i) => Console.WriteLine("Command {0} invoked", i));

commandsDictionary["Command1"].Invoke(1);
// Command 1 invoked

如果您想要从您要调用的代理中返回一个值,请使用Func代理,Func一个容易记住的规则就是最后 type参数始终是返回的类型,因此Func<int, string>等同于具有以下签名的方法public string Foo(int i)

Dictionary<string, Func<int, string>> commandsDictionary = new Dictionary<string, Func<int, string>>();
commandsDictionary.Add("Command1", (i) => { return string.Format("Let's get funky {0}", i); });

string result = commandsDictionary["Command1"].Invoke(56963);
Console.WriteLine (result);
// Let's get funky 56963

参考

我已经添加了这一部分,以帮助那些还不知道代表是什么的人...这一切都非常简单。

代表

DelegateType,表示方法参考。它们就像你声明引用对象的变量一样,除了代替对象,它们引用方法。

委托可以使用命名方法匿名函数进行实例化,例如lambda表达式(上面演示的类型I)。< / p>

行动代表

Action Delegate的返回类型为 void ,并使用类型参数定义其签名。

void Example()
{
    // Named method
    this.NamedActionDelegate = NamedMethod;
    this.NamedActionDelegate.Invoke("Hi", 5);
    // Output > Named said: Hi 5

    // Anonymous Function > Lambda
    this.AnonymousActionDelegate.Invoke("Foooo", 106);
    // Output > Anonymous said: Foooo 106
}

public Action<string, int> NamedActionDelegate { get; set; }
public Action<string, int> AnonymousActionDelegate = (text, digit) => Console.WriteLine ("Anonymous said: {0} {1}", text, digit);

public void NamedMethod(string text, int digit)
{
    Console.WriteLine ("Named said: {0} {1}", text, digit);
}

Func Delegate

Func Delegate与Action Delegate类似,区别在于Func永远不会返回 void ,因此总是 < em> require 至少 1类型参数 ,如前所述,最后指定的type参数指示委托的返回类型。

void Example()
{
    // Named method
    this.NamedFuncDelegate = NamedMethod;
    string namedResult = this.NamedFuncDelegate.Invoke(5);
    Console.WriteLine (namedResult);
    // Output > Named said: 5

    // Anonymous Function > Lambda
    string anonyResult = this.AnonymousFuncDelegate.Invoke(106);
    Console.WriteLine (anonyResult);
    // Output > Anonymous said: 106
}

public Func<int, string> NamedFuncDelegate { get; set; }
public Func<int, string> AnonymousFuncDelegate = (digit) => { return string.Format("Anonymous said: {0}", digit); };

public string NamedMethod(int digit)
{
    return string.Format ("Named said: {0}", digit);
}

答案 1 :(得分:2)

如果要将开关与数组命令一起使用,而是使用与命令项比较,请使用索引语句,如下所示:

public static string[] commands =
{   
    "command1",
    "command2",
    "command3",
    "command4",
    "command5",
    "command6",
    "command7"
};

public static bool startCommand(string commandName)
{
    var index = Array.IndexOf(commands, commandName);

    //stuff
    if (index == 0)  // commands[0]
    {
        //stuff
        return true;
    }
    else
    {
        //stuff
        switch (index)
        {
            case 1:  // commands[0]
                //stuff
                break;
            case 2:  // commands[2]
                //stuff
                break;
            case 3:  // commands[3]
                //stuff
                break;
            case 4:  // commands[4]
                //stuff
                break;
            case 5:  // commands[5]
                //stuff
                break;
            case 6:  // commands[6]
                //stuff
                break;
            default:
                return false;
        }
        //do stuff
        return true;
    }
}

答案 2 :(得分:1)

总结为答案,将其改为:

        Dictionary<string, Action> commands = new Dictionary<string,Action>();
        commands.Add("command1", () => {});
        commands.Add("command2", () => { });
        commands.Add("command3", () => { });

        Action action = null;
        commands.TryGetValue(commandName, out action);
        if (action != null) 
            action();

如果需要,您可以使字典静态或可能只读:

    static void Command1() { }
    static void Command2() { }

    static readonly Dictionary<string, Action> commands = new Dictionary<string, Action>(){
        { "command1", Command1 },
        { "command2", Command2 }
    };

答案 3 :(得分:1)

假设你对常量字符串没问题,那么定义一个静态类:

public static class COMMANDS 
{
    public const string COMMAND1 = "command1";
    public const string COMMAND2 = "command2";
    public const string COMMAND3 = "command3";
    public const string COMMAND4 = "command4";
    public const string COMMAND5 = "command5";
    public const string COMMAND6 = "command6";
    public const string COMMAND7 = "command7";
}

然后将其与switch语句一起使用:

//stuff
if (commandName == COMMANDS.COMMAND1)
{
    //stuff
    return true;
}
else
{
    //stuff
    switch (commandName)
    {
        case COMMANDS.COMMAND2:
            //stuff
            break;
        case COMMANDS.COMMAND3:
            //stuff
            break;
        case COMMANDS.COMMAND4:
            //stuff
            break;
        case COMMANDS.COMMAND5:
            //stuff
            break;
        case COMMANDS.COMMAND6:
            //stuff
            break;
        case COMMANDS.COMMAND7:
            //stuff
            break;
        default:
            return false;
    }
    //do stuff
    return true;
}

答案 4 :(得分:0)

using System;
using System.Reflection;

namespace CommandExample
{
    class Program
    {
        static void Main()
        {
            var cmdName = "Command1";

            // Create an instance of the command class using reflection
            Type type = Assembly.GetExecutingAssembly().GetType("CommandExample." + cmdName);
            if (type == null) { /* Cannot find command. Handle error */ }
            var cmd = Activator.CreateInstance(type) as ICommand;

            cmd.Exec();
        }
    }

    interface ICommand
    {
        void Exec();
    }

    class Command1 : ICommand
    {
        public void Exec()
        {
            Console.WriteLine("Executing Command1");
        }
    }
}