我有一个数组
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#编程了大约四天。
答案 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
我已经添加了这一部分,以帮助那些还不知道代表是什么的人...这一切都非常简单。
Delegate
是Type
,表示方法的参考。它们就像你声明引用对象的变量一样,除了代替对象,它们引用方法。
委托可以使用命名方法或匿名函数进行实例化,例如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
与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");
}
}
}