gpt4 book ai didi

c# - 从数据库中填充函数字典

转载 作者:行者123 更新时间:2023-11-30 15:32:35 24 4
gpt4 key购买 nike

我正在研究 MUD,目前命令处理程序是一个元组,它采用字符串 readString 和 Player 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(' ');

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

最佳答案

您可以使用 GetMethod通过名称获取需要调用的方法

this.GetType().GetMethod("doSay")

然后你可以创建一个FuncDelegateInvoke 上命令 MethodInfo具有所需的参数和返回类型

var function = new Func<string, Player, Tuple<string, Player>>((arg1, arg2) => (Tuple<string, Player>)this.GetType().GetMethod("doSay").Invoke(this, new object[] { arg1, arg2 })));

将其包装起来使其可重用

public Func<string, Player, Tuple<string, Player>> CreateFunction(string methodName)
{
if (this.GetType().GetMethods().Any(x => x.Name == methodName))
{
return new Func<string, Player, Tuple<string, Player>>((arg1, arg2) => (Tuple<string, Player>)this.GetType().GetMethod(methodName).Invoke(this, new object[] { arg1, arg2 }));
}
return null;
}

然后您可以将这些添加到您的 Dictionary

  var functions = new Dictionary<string, Func<string, Player, Tuple<string, Player>>>();
functions.Add("Say",CreateFunction("doSay"));

或来自您Database

foreach (Command playerCommand in dbHandler.GetCommands())
{
if (!functions.ContainsKey(playerCommand.CommandName))
{
functions.Add(playerCommand.CommandName, CreateFunction(playerCommand.CommandTuple));
}
}

然后你可以随时调用他们

 var result = functions["Say"]("Hello", new Player());

注意事项:

我建议更换 Tuple<sting, Player>使用一个不错的类而不是像下面这样,因为在整个应用程序中处理它会不那么痛苦

public void Test()
{
Dictionary<string, Func<string, Player, MyResult>> functions = new Dictionary<string, Func<string, Player, MyResult>>();
functions.Add("Say",CreateFunction("doSay"));
var result = functions["Say"]("Hello", new Player());
}

public Func<string, Player, MyResult> CreateFunction(string methodName)
{
if (this.GetType().GetMethods().Any(x => x.Name == methodName))
{
return new Func<string, Player, MyResult>((arg1, arg2) => (MyResult)this.GetType().GetMethod(methodName).Invoke(this, new object[] { arg1, arg2 }));
}
return null;
}

public MyResult doSay(string value1, Player value2)
{
return new MyResult(value1, value2);
}

public class MyResult
{
public MyResult(string value1, Player value2)
{
Value1 = value1;
Value2 = value2;
}
public string Value1 { get; set; }
public Player Value2 { get; set; }
}

关于c# - 从数据库中填充函数字典,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18808308/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com