上传没有任何添加的数据字段

时间:2010-03-15 22:29:23

标签: c# class casting types

在我的项目中,我有一个通用的Packet类。我希望能够转发到其他课程(例如LoginPacketMovePacket)。

基类包含一个命令和参数(大大简化):

public class Packet
{
    public String Command;
    public String[] Arguments;
}

我希望能够根据Packet.Command == "LOGIN"检查从Packet转换为LoginPacket(或任何其他)。登录数据包不包含任何新数据成员,而只包含访问特定参数的方法。例如:

public class LoginPacket : Packet
{
    public String Username
    {
        get { return Arguments[0]; }
        set { Arguments[0] == value; }
    }
    public String Password
    {
        get { return Arguments[1]; }
        set { Arguments[1] == value; }
    }
}

如果我可以运行一个简单的代码,从Packet转换为LoginPacket并使用类似LoginPacket _Login = (LoginPacket)_Packet;的内容,但会抛出System.InvalidCastException,那就太棒了。

似乎这是一项简单的任务,因为没有包含新数据,但除了将Packet类中的所有内容复制到新的LoginPacket类之外,我无法想出任何其他方法

2 个答案:

答案 0 :(得分:3)

更好的方法是将Packet实例封装为LoginPacket

这样你就可以:

LoginPacket _Login = new LoginPacket(_packet);

还考虑创建一个PacketFactory,其中创建各种Packet所需的所有逻辑都会进入。

public class Packet
{
    public String Command;
    public String[] Arguments;
}

public abstract class AbstractPacket
{
    private Packet _packet;

    public AbstractPacket(Packet packet)
    {
        _packet = packet;
    }

    public string this[int index]
    {
        get { return _packet.Arguments[index]; }
        set { _packet.Arguments[index] = value; }
    }
}

public class LoginPacket : AbstractPacket
{
    public LoginPacket(Packet packet): base(packet)
    {            
    }

    public string Username
    {
        get { return base[0]; }
        set { base[0] = value; }
    }
    public string Password
    {
        get { return base[1]; }
        set { base[1] = value; }
    }

}

答案 1 :(得分:0)

如果不同类型的数据包只有可用的数据成员不同,那么您可以执行以下操作:

使用PacketGenerator生成数据包:

Packet packet = PacketGenerator.GetInstance(packetdata);

访问属性:

Console.WriteLine("User Name: {0}", packet["UserName"]);

代码..

public enum PacketType { Undefined, LoginPacket, MovePacket }

public class PacketData
{
    public String Command;
    public String[] Arguments;
}

public class Packet
{
    public readonly PacketType TypeOfPacket;
    private Dictionary<string, string> _argumentMap;

    public Packet(PacketType _packetType,
                  Dictionary<string, string> argumentMap)
    {
        TypeOfPacket = _packetType;
        _argumentMap = argumentMap;
    }

    public string this[string index]
    {
        get { return _argumentMap[index]; }
        set { _argumentMap[index] = value; }
    }
}

public static class PacketFactory
{
    Packet GetInstance(PacketData packetData)
    {
        Dictionary<string, string> argumentMap
                            = new Dictionary<string, string>();
        PacketType typeOfPacket = PacketType.Undefined;

        // Replace inline strings/int with static/int string definitions
        switch (packetData.Command.ToUpper())
        {
            case "LOGIN":
                typeOfPacket = PacketType.LoginPacket;

                argumentMap["UserName"] = packetData.Arguments[0];
                argumentMap["PassWord"] = packetData.Arguments[1];
                break;

            case "MOVE":
                typeOfPacket = PacketType.MovePacket;
                //..
                break;
            default:
                throw new ArgumentException("Not a valid packet type");
        }

        return new Packet(typeOfPacket, argumentMap);
    }
}