Reputation: 1153
I'm currently writing a simple parser for streaming information delivered using the Session Description Protocol (SDP; see: https://www.rfc-editor.org/rfc/rfc4566).
For various fields, such as originator or media, there are flags which can have different values. For example, the media transport protocol on media field (see: https://www.rfc-editor.org/rfc/rfc4566#section-8.2.2)
m=audio 49170 RTP/AVP 0
The proto flag (media transport protocol) can either be "RTP/AVP", "RTP/SAVP" or "UDP" according to the specification.
Because there are numerous values this flag can have, it's appropriate to use an enum
:
public enum MediaTransportProtocol {
UDP,
RTP_AVP
RTP_SAVP
}
But now here's the problem: There's no such thing as a string enum, so I can't use this one for parsing (e.g. because of the "/
" char in RTP/AVP..) So I have to define additional constants just to switch over the media transport protocol flag when parsing the media field.
I've considered using the "DESCRIPTION
" attribute over each enum
field, but then I have to write an additional method/extension method just to receive the enum flag description
(gathering enum description attribute isn't a trivial task IMHO)
What's considered best practice to parse such data? Or is there something like a string enum and I'm just not aware of it?
public enum MyStringEnum {
ENUMVAL1 = "EnumVal-01",
ENUMVAL2 = "EnumVal-02"
...
}
Upvotes: 0
Views: 150
Reputation: 18474
Actually the Name
property of DisplayAttribute
is probably the best way to go. You will find numerous examples of using this, quite often to populate dropdown combos.
I utility library I keep that has functions like this stored in it, meaning I only had to write the function once.
If you are desperate not to use an attribute then your best bet is to create a dictionary for your lookups.
public static readonly Dictionary<string,MediaTransportProtocol> MediaTransportProtocols =
new Dictionary<string,MediaTransportProtocol> {
{"UDP", MediaTransportProtocol.UDP},
{"RTP/AVP", MediaTransportProtocol.RTP_AVP},
{"RTP_SAVP", MediaTransportProtocol.RTP_SAVP},
};
Then you can just perform the lookups and keep the advantages of using an enum
in your code.
The ideal solution, which is what my library does, is to create a static generic class EnumHelper<T>
that creates this dictionary in its static constructor by reflecting the enum to extract from the Display attribute, falling back on the member name. This means that reflection only happens once for each enum type.
Upvotes: 1
Reputation: 28302
Artur Udod has an interesting idea (#1). Another way to do do this would be to replace the '/' character with an underscore '_'. Then use the enum parse function.
tokenStr = tokenStr.replace('/', '_');
enumVal = Enum.Parse(typeof(MediaTransportProtocol), tokenStr);
I'm making an implicit assumption that your token character set is limited to letters, possibly digits and slashes. Obviously if there are two tokens of the form A_B and A/B that are to be considered differently, this would be a problem.
Upvotes: 1
Reputation: 4743
No. Enums are essentially ints.
let me give you few propositions:
1) use attributes on your enums
public enum MyStringEnum {
[ProtoFlagName("RTP/AVP")]
ENUMVAL1 = 1,
[ProtoFlagName("RTP/SAVP")]
ENUMVAL2 = 2
...
}
2) Chose a different data structure, for instance List<string>
or Dictionary<MyStringEnum, string>
3) (don't like this one honestly). Use '_' symbol instead of '/'. Then just post-process your string values after you get them:
var stringValue = Enum.GetName(typeof(MyStringEnum ), MyStringEnum.ENUMVAL1);
var correctedStringValue = stringValue.Replace('_', '/');
Upvotes: 2