【发布时间】:2013-09-19 10:32:59
【问题描述】:
我正在开发一个 MUD,目前命令处理程序是一个元组,它接受一个字符串 readString 和带有 switch 语句的 Player PlayerObj 来确定返回元组
public Tuple<string, Player> handleCMD(string readString, Player PlayerObj)
{
Tuple<string, Player> returnTuple = new Tuple<string, Player>(readString, PlayerObj);
string[] arguments = readString.Split(' ');
switch (arguments[0].ToLower())
{
case "addchange":
returnTuple = doAddChange(readString, PlayerObj);
break;
case "changes":
returnTuple = doChanges(readString, PlayerObj);
break;
case "score":
returnTuple = doScore(readString, PlayerObj);
break;
case "look":
returnTuple = doLook(readString, PlayerObj);
break;
case "north":
returnTuple = doWalk(arguments[0], PlayerObj);
break;
case "east":
returnTuple = doWalk(arguments[0], PlayerObj);
break;
case "south":
returnTuple = doWalk(arguments[0], PlayerObj);
break;
case "west":
returnTuple = doWalk(arguments[0], PlayerObj);
break;
case "quit":
returnTuple = doQuit(readString, PlayerObj);
break;
case "chat":
returnTuple = doChat(readString, PlayerObj);
break;
case "say":
returnTuple = doSay(readString, PlayerObj);
break;
case "who":
returnTuple = doWho(readString, PlayerObj);
break;
case "tell":
returnTuple = doTell(readString, PlayerObj);
break;
default:
returnTuple = doHuh(readString, PlayerObj);
break;
}
return returnTuple;
}
public Tuple<string, Player> doSay(string readString, Player PlayerObj)
{
DBHandler dbHandler = new DBHandler();
PlayerObj = dbHandler.GetPlayer(PlayerObj.PlayerName);
string returnString;
string[] arguments = readString.Split(' ');
if (arguments.Count() > 1 && arguments[1] != string.Empty && arguments[1] != null && arguments[1] != "" && arguments[1] != " ")
{
readString = readString.Trim().Replace("say ", "");
Message message = new Message(0, readString, PlayerObj.PlayerID, 0, 1, 1);
returnString = string.Format("You say \"{0}\"", readString);
foreach (int i in dbHandler.GetPlayersInRoom(PlayerObj.RoomID, PlayerObj.PlayerName))
dbHandler.AddMessage(new Message(0, message.MessageText, message.SenderPlayerID, i, message.MessageType, message.Ticked));
}
else
returnString = "[Syntax] : Say <Message>";
return new Tuple<string, Player>(returnString, PlayerObj);
}
我想将 switch 语句替换为由数据库中的表填充的字典,这样我就可以在数据库表中添加和禁用命令/别名,而无需编辑代码
我试过这样做:
public Tuple<string, Player> handleCMD(string readString, Player PlayerObj)
{
Tuple<string, Player> returnTuple = new Tuple<string, Player>(readString, PlayerObj);
string[] arguments = readString.Split(' ');
DBHandler dbHandler = new DBHandler();
Dictionary<string, Delegate> cmdDictionary = new Dictionary<string, Delegate>();
foreach (Command playerCommand in dbHandler.GetCommands())
cmdDictionary.Add(playerCommand.CommandName, new Func<string, Player, Tuple<string, Player>>(playerCommand.CommandTuple));
if (cmdDictionary[arguments[0]] != null)
returnTuple = (Tuple<string, Player>)cmdDictionary[arguments[0]].DynamicInvoke(readString, PlayerObj);
else
returnTuple = doHuh(readString, PlayerObj);
return returnTuple;
}
问题是我收到错误消息:
cmdDictionary.Add(playerCommand.CommandName, new Func<string, Player, Tuple<string, Player>>(playerCommand.CommandTuple));
'GWOService.Command.CommandTuple' is a 'property' but is used like a 'method'
playerCommand.CommandName 是一个字符串,它 = "doSay" 或 "doHuh" 或任何元组的名称,但以下方法有效:
cmdDictionary.Add(playerCommand.CommandName, new Func<string, Player, Tuple<string, Player>>(doSay/*playerCommand.CommandTuple*/));
更新
所以我再次尝试了以下方法:
public Tuple<string, Player> handleCMD(string readString, Player PlayerObj)
{
Tuple<string, Player> returnTuple = new Tuple<string, Player>(readString, PlayerObj);
string[] arguments = readString.Split(' ');
DBHandler dbHandler = new DBHandler();
Dictionary<string, Delegate> cmdDictionary = new Dictionary<string, Delegate>();
foreach (Command playerCommand in dbHandler.GetCommands())
{
try
{
MethodInfo method = GetType().GetMethod(playerCommand.CommandTuple);
//Func<string, Player, Tuple<string, Player>> func = ( ) => { return (Tuple<string, Player>)(this.GetType().GetMethod(playerCommand.CommandTuple).Invoke(this, new object[0])); }
Func<string, Player, Tuple<string, Player>> func = (Func<string, Player, Tuple<string, Player>>)Delegate.CreateDelegate(typeof(Func<string, Player, Tuple<string, Player>>), method);
cmdDictionary.Add(playerCommand.CommandName, new Func<string, Player, Tuple<string, Player>>(func));
}
catch (Exception e)
{
dbHandler.LogEntry(PlayerObj, e.ToString());
}
}
if (cmdDictionary[arguments[0]] != null)
returnTuple = (Tuple<string, Player>)cmdDictionary[arguments[0]].DynamicInvoke(readString, PlayerObj);
else
returnTuple = doHuh(readString, PlayerObj);
//switch (arguments[0].ToLower())
//{
// case "addchange":
// returnTuple = doAddChange(readString, PlayerObj);
// break;
// case "changes":
// returnTuple = doChanges(readString, PlayerObj);
// break;
// case "score":
// returnTuple = doScore(readString, PlayerObj);
// break;
// case "look":
// returnTuple = doLook(readString, PlayerObj);
// break;
// case "north":
// returnTuple = doWalk(arguments[0], PlayerObj);
// break;
// case "east":
// returnTuple = doWalk(arguments[0], PlayerObj);
// break;
// case "south":
// returnTuple = doWalk(arguments[0], PlayerObj);
// break;
// case "west":
// returnTuple = doWalk(arguments[0], PlayerObj);
// break;
// case "quit":
// returnTuple = doQuit(readString, PlayerObj);
// break;
// case "chat":
// returnTuple = doChat(readString, PlayerObj);
// break;
// case "say":
// returnTuple = doSay(readString, PlayerObj);
// break;
// case "who":
// returnTuple = doWho(readString, PlayerObj);
// break;
// case "tell":
// returnTuple = doTell(readString, PlayerObj);
// break;
// default:
// returnTuple = doHuh(readString, PlayerObj);
// break;
//}
return returnTuple;
}
但我得到了错误:
第 25 行
Func<string, Player, Tuple<string, Player>> func = (Func<string, Player, Tuple<string, Player>>)Delegate.CreateDelegate(typeof(Func<string, Player, Tuple<string, Player>>), method);
System.ArgumentException: Cannot bind to the target method because its signature or security transparency is not compatible with that of the delegate type.
at System.Delegate.CreateDelegate(Type type, MethodInfo method, Boolean throwOnBindFailure)
at System.Delegate.CreateDelegate(Type type, MethodInfo method)
at GWOService.CmdHandler.handleCMD(String readString, Player PlayerObj) in \Projects\GodWarsOxide\GWOService\CmdHandler.cs:line 25
【问题讨论】:
标签: c# .net dictionary tuples