在我正在开发的应用程序中,我正在解码 TCP 消息。这些消息都具有相同的标头,但实际的消息内容可以具有不同的字段和不同的总长度。所以我想到了以下实现,我认为这是不正确的。
我为仅包含标题的消息定义了一个接口:
internal interface IMesTelegram
{
public MesTelegramHeader Header { get; set; }
}
internal class MesTelegramHeader
{
public ushort Id { get; set; }
public ushort SenderId { get; set; }
public ushort ReceiverId { get; set; }
public byte MessageType { get; set; }
public ushort DataLength { get; set; }
}
然后我实现了一个 Telegram 类,它实现了标头:
internal class MesTelegram : IMesTelegram
{
public MesTelegramHeader Header { get; set; }
}
然后我有特定的电报类,它们基于 MesTelegram 类:
internal class MesAckTelegram : MesTelegram
{
public byte AckReject { get;set; }
public ushort MessageId { get; set; }
public ushort ResponseId { get; set; }
public uint ResponseTimeOut { get; set; }
}
internal class MesVersionInfoTelegram : MesTelegram
{
public ushort InterfaceVersionMajor { get; set; }
public ushort InterfaceVersionMinor { get; set; }
public ushort StringLength { get; set; }
public string SoftwareVersion { get; set; }
}
这是电报被解码的地方。我认为声明一个 IMesTelegram 变量然后为其分配特定的实现是可以的,但这不起作用。
protected override void Decode(IChannelHandlerContext context, IByteBuffer input, List<object> output)
{
MesTelegramHeader header = new();
header.Id = input.ReadUnsignedShortLE();
header.SenderId = input.ReadUnsignedShortLE();
header.ReceiverId = input.ReadUnsignedShortLE();
header.MessageType = input.ReadByte();
header.DataLength = input.ReadUnsignedShortLE();
IMesTelegram mesTelegram = null;
switch (header.Id)
{
case 123:
mesTelegram = new MesVersionInfoTelegram();
// i thought i could access the properties here, but i can't
break;
case 456:
mesTelegram = new MesAckTelegram();
// i thought i could access the properties here, but i can't
break;
default:
break;
}
mesTelegram.Header = header;
}
我认为我在这里选择了正确的方法,并且我不确定继续下去的最佳方法是什么。我认为通过使用接口我可以保持代码简短。下一步是将电报转换为不同系统的消息,具体取决于原始电报类型。我想我可以将 IMesTelegram 传递给该方法,检查 header.Id 并基于此继续。我很感激任何帮助或指点。
你的变量
mesTelegram
是接口类型,没有具体的概念。因此,只需创建一个特定类型的变量并将其分配给您的 mesTelegram
变量:
protected override void Decode(IChannelHandlerContext context, IByteBuffer input, List<object> output)
{
MesTelegramHeader header = new();
header.Id = input.ReadUnsignedShortLE();
header.SenderId = input.ReadUnsignedShortLE();
header.ReceiverId = input.ReadUnsignedShortLE();
header.MessageType = input.ReadByte();
header.DataLength = input.ReadUnsignedShortLE();
IMesTelegram mesTelegram = null;
switch (header.Id)
{
case 123:
var m1 = new MesVersionInfoTelegram();
// ... set the specific props here
mesTelegram = m1;
break;
case 456:
var m2 = new MesAckTelegram();
mesTelegram = m2;
break;
default:
break;
}
if(mesTelegram != null)
mesTelegram.Header = header;
}