Structures with conditional members

2019-07-27 11:13发布

问题:

I'm trying to build a structure in VB to allow me to both store and parse an IP/UDP based message that I'm receiving as ASCII encoded HEX.

The trick is that after I get past the IP header and the UDP header the data that follows after is of a variable structure type. By that I mean that there is a basic initial message structure that has data in specific fields... two thirds of which are optional... but then the actual data, the real meat of the transmission, is in one of 15 different message structures.

So is there a way to conditionally define one of the members of the structure based on the data I'm putting in it?

My plan was to create a New() function that you could simply pass the message string to and it would parse out all of the data and populate the members of the structures as needed. But how can I make the declaration type of one of the structure members dependent on the data that will be parsed out in the New() function? Or is there no way to really do this?

Basically something (albeit crudely) like this:

Private Structure DevMsg
    ReadOnly IPHeader As IP_HDR
    ReadOnly UDPHeader As UDP_HDR
    ReadOnly MsgType As DevMsgType
    Select Case MsgType
        Case Msg0
            ReadOnly Data as MsgType0
        Case Msg1
            ReadOnly Data as MsgType1
        ...
    End Select

    Public Sub New(ByVal msg as String)

        ... String parser ...

        MsgType = blah

        ... More parsing ...

        Data.property0 = blah2
        Data.property1 = blah3
        ...

    End Sub
End Structure

回答1:

I think what you should be doing is having a base/abstract class and concrete classes for each type of message that inherit from the base.

Something like this:

Public MustInherit Class MessageBase
    Public ReadOnly Header As String
    Public ReadOnly MsgType As Integer
    Public Function CreateMessage(message As String) As MessageBase
        If message = "type1" Then Return New Type1Message
        If message = "type1" Then Return New Type2Message
        'etc.
    End Function
End Class

Public Class Type1Message
    Inherits MessageBase
End Class

Public Class Type2Message
    Inherits MessageBase
End Class

This way you can share common properties in the base class and add additional properties for each message where they differ.

note you need a constructor in each concrete class to parse the data according to its own rules, but I have left this out for clarity



回答2:

Based on what you've said, it sounds like a class would be better suited to your needs than a structure (see MSDN). You should start with an abstract base class, and define all your "flavors" in classes that derive from it.

Furthermore, I wouldn't do all the building in constructors; rather, I'd define a separate "builder" class that can build the various types of instances based on your needs.

You might also find that an abstract factory scenario suits your needs better than a builder since you're dealing dealing with a "family" of objects.

Here's a good starting point to learn about a variety of creational design patterns, including "builder" and "abstract factory": https://en.wikipedia.org/wiki/Creational_pattern