Switch-Case数据包处理的替代方案

Fus*_*ght 1 c# sockets json packet switch-statement

我一直在玩网络套接字,我的大多数问题都来自Windows Forms,但是我已经研究了很多程序,比如私有服务器模拟器,我对我的数据包处理感到不满意.

每个消息都以JSON格式化,如下所示:

{
"id":201,
"Message":"Hello, World.",
"User":"System",
"Color":"LawnGreen"
}
Run Code Online (Sandbox Code Playgroud)

"id"是所有数据包中的常量,它将识别数据包的功能.具有相同ID的数据包(以下称为标题)将始终具有相同的键,但不一定具有相同的值(duh,有人说).

我将JSON反序列化为动态并在数据包的标题上执行切换案例,如下所示:

switch((int)jsonPacket.id)
{
    case 201:
    ...
}
Run Code Online (Sandbox Code Playgroud)

鉴于这是一个非常小规模的聊天应用程序,甚至几乎没有开始尝试和实现所有IRC的功能,我是否仍然应该关注并不满意我的实现?小型游戏/测试台服务器使用相同的方法,但我不想在功能和性能方面限制自己,或者如果它变得令人讨厌.

任何想法都会有帮助.

das*_*ght 7

使用开关可以生成相当高效的代码,因此您不会限制自己的性能.它也是一个相当简洁的代码,从某种意义上说,大多数对该语言有基本了解的读者都能够弄清楚发生了什么.

switch的另一个常见替代方法是委托的关联容器.你可以这样做:

private static readonly IDictionary<int,Action<object>> processor =
    new Dictionary<int,Action<object>>
{
    { 201, Process201 }
,   { 205, Process205 }
};
...
static void Process201(object message) {
    // Do something
}
static void Process205(object message) {
    // Do something else
}
Run Code Online (Sandbox Code Playgroud)

现在你可以像这样使用这个数组:

processor[jsonPacket.id](jsonPacket);
Run Code Online (Sandbox Code Playgroud)

这将根据数据包中的ID调用适当的方法.Action<T>如果您决定在分派到操作处理程序之前从数据包中获取更多数据,则可以使更具体的类型而不是对象,或者完全传递一组不同的参数.