组织除开关以外的枚举项目的更好方法是什么?

时间:2014-10-07 20:24:37

标签: c# enums

所以我有一些工作正常的代码,但亲爱的上帝,很难看。我几乎肯定有一种更好的方式来写这一点。

所以基本上我在字节数组中有一些数据可能是也可能不是完整的数据包。前几个字节被读取为Int32,它是Packet的标题。它直接转换为我的数据包枚举。

所以现在我的数据包设置如下:

class SomePacket : Packet
{
  PacketType type = PacketType.SomePacket;

  public override Packet ReadPacket(ref buffer)
  {
    //Return if the buffer has all the data for this packet.
  }
  ...
}

但这实际上导致我不得不这样做:

    public abstract Byte[] CreateSendBuffer();

    /// <summary>
    /// Reads and removes from buffer to make a packet.
    /// </summary>
    /// <param name="buffer">Buffer used to try to create a packet.</param>
    /// <returns></returns>
    public static Packet ReadBuffer(ref List<Byte> buffer)
    {
        if (buffer != null)
        {
            if (buffer.Count > sizeof(Int32))
            {
                Byte[] backupBuffer = buffer.ToArray();
                try
                {
                    Packet returnPacket = null;
                    Int32 packetType = TakeInt32(ref buffer);

                    switch ((PacketType)packetType)
                    {
                        case (PacketType.VerifyInfo_s):
                            returnPacket = VerifyInfo_s.ReadPacket(ref buffer);
                            break;

                        case (PacketType.Ping_sp):
                            returnPacket = Ping_sp.ReadPacket(ref buffer);
                            break;

                        case (PacketType.GameInfo_p):
                            returnPacket = GameInfo_p.ReadPacket(ref buffer);
                            break;

                        case (PacketType.DayPhase_p):
                            returnPacket = DayPhase_p.ReadPacket(ref buffer);
                            break;

                        case (PacketType.AddPlayer_p):
                            returnPacket = AddPlayer_p.ReadPacket(ref buffer);
                            break;

                        case (PacketType.Player_Visible_p):
                            returnPacket = Player_Visible_p.ReadPacket(ref buffer);
                            break;

                        case (PacketType.Player_Movement_s):
                            returnPacket = Player_Movement_s.ReadPacket(ref buffer);
                            break;

                        case (PacketType.Player_Movement_p):
                            returnPacket = Player_Movement_p.ReadPacket(ref buffer);
                            break;

                        case (PacketType.Player_Health_p):
                            returnPacket = Player_Health_p.ReadPacket(ref buffer);
                            break;

                        default:
                            DebugLogger.GlobalDebug.LogNetworking("Invalid packet header!");
                            throw new InvalidPacketRead();
                    }

                    if (TakeByte(ref buffer) == END_PACKET)
                        return returnPacket;
                    else
                        throw new InvalidPacketRead();
                }
                catch (ArgumentOutOfRangeException e) //Not enough data yet to make a full packet.
                {
                    DebugLogger.GlobalDebug.LogNetworking("Packet not large enough yet." + e.ToString());
                    buffer = backupBuffer.ToList();
                    return null;
                }
            }
        }
        return null;
    }

如果没有开关的可怕混乱,我能以什么方式实现这一目标?

1 个答案:

答案 0 :(得分:2)

一旦达到这个级别,代码就会变得混乱。它就是这样;你必须学会​​忍受它。

话虽这么说,你可以定义一个Dictionary<PacketType, Func<byte[], Packet>>并像这样构建它:

var parseMethods = new Dictionary<PacketType, Func<byte[], Packet>>();
parseMethods.Add(PacketType.VerifyInfo_s, VerifyInfo_s.ReadPacket);
...

returnPacket = parseMethods[(PacketType)packetType](buffer);

真的更好吗?也许,也许不是,但如果你真的对switch有了反对的话。

相关问题