将变量声明为接口并访问特定实现的属性

问题描述 投票:0回答:1

在我正在开发的应用程序中,我正在解码 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 并基于此继续。我很感激任何帮助或指点。

c# inheritance interface netty
1个回答
0
投票

你的变量

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;

}
© www.soinside.com 2019 - 2024. All rights reserved.