gpt4 book ai didi

c# - 用于解析的可扩展类型安全枚举类?

转载 作者:太空宇宙 更新时间:2023-11-03 13:39:16 26 4
gpt4 key购买 nike

我已经完全被这个问题困扰了大约 2 天,似乎我根本无法解决我所面临的问题。

目前,我正在编写一个 SDP 解析库,它也应该可用于根据其规范 (https://www.rfc-editor.org/rfc/rfc4566) 创建正确的 SDP 消息。但规范有时非常开放或不明确,因此我尝试实现必要的灵 active ,同时仍尽可能接近 RFC。

示例问题

SDP 消息可以包含媒体信息(“m”字段),因为此信息具有以下模式:

m=<media> <port> <proto> <fmt> ...

示例消息可能如下所示:

m=video 49170/2 RTP/AVP 31

看一下 proto 标志,它代表媒体传输协议(protocol)。根据规范,该字段可以有以下值:

  • RTP/AVP
  • RTP/SAVP
  • UDP

这是一个值列表,因此采用枚举显然是合适的。

public enum MediaTransportProtocolType {
RTP/AVP
RTP/SAVP
UDP
}

糟糕!但由于“/”字符,这不起作用。那么,我怎样才能使用它进行解析呢?我用 DescriptionAttribute

扩展了 Enumeration 字段
public enum MediaTransportProtocolType {
[Description("RTP/AVP")
RTP_AVP
[Description("RTP/SAVP")
RTP_SAVP
[Description("UDP")
UDP
}

现在我可以根据描述简单地查找适当的媒体传输协议(protocol)类型。但是现在,RFC 规范继续:

This memo registers three values [...] If other RTP profiles are 
defined in the future [...]

因此, future 的网络设备可能会向我发送我不知道的媒体传输协议(protocol)。由于各种原因 System.Enum 不可扩展,整个枚举在这里不再起作用。

解决方案

在寻找解决方案的过程中,我遇到了类型安全枚举模式(又名StringEnum),如下所述:how can i use switch statement on type-safe enum pattern。这个答案甚至描述了一种使它们可切换的解决方案,即使恕我直言,这是一个丑陋的解决方案。

但同样,这只适用于定义的范围。我用一个字典扩展了 Type Safe Enumeration 类来存储我可以在解析时查找的实例,但如果我现在不查找它们,也会添加新的实例。

但是所有其他字段呢?那么类型转换呢?

此处的答案描述了一种使用基类并通过显式运算符进行转换的方法:Casting string to type-safe-enum using user-defined conversion

我试过了,但它并没有像我希望的那样工作。 (无效的转换异常,脏的两次转换模式,不可扩展)。

如何正确、轻松地解析 SDP 信息,同时仍然提供允许创建正确 SDP 的库?

最佳答案

你可以这样做:

public sealed class MediaTransportProtocolType
{
public static readonly MediaTransportProtocolType RtpAvp =
new MediaTransportProtocolType("RTP/AVP");

public static readonly MediaTransportProtocolType RtpSavp =
new MediaTransportProtocolType("RTP/SAVP");

public static readonly MediaTransportProtocolType Udp =
new MediaTransportProtocolType("UDP");

public static readonly ReadOnlyCollection<MediaTransportProtocolType>
Values = new ReadOnlyCollection<MediaTransportProtocolType>(
new MediaTransportProtocolType[] { RtpAvp, RtpSavp, Udp });

private MediaTransportProtocolType(string name)
{
this.Name = name;
}

public string Name { get; private set; }

public static MediaTransportProtocolType Parse(string value)
{
if (string.IsNullOrEmpty(value))
{
throw new ArgumentNullException("value");
}

var comparer = StringComparer.OrdinalIgnoreCase;

if (comparer.Equals(value, RtpAvp.Name))
{
return RtpAvp;
}
else if (comparer.Equals(value, RtpSavp.Name))
{
return RtpSavp;
}
else if (comparer.Equals(value, Udp.Name))
{
return Udp;
}
else if (value.StartsWith("RTP/", StringComparison.OrdinalIgnoreCase))
{
// Normally we would throw an exception here, but future
// protocols are expected and we must be forward compatible.
return new MediaTransportProtocolType(name);
}

throw new FormatException(
"The value is not in an expected format. Value: " + value);
}
}

这允许您像这样将它用作枚举:

var type = MediaTransportProtocolType.Udp;

你可以解析它:

var type = MediaTransportProtocolType.Parse(value);

并遍历所有已知值:

foreach (var type in MediaTransportProtocolType.Values)
{
}

只要它们以“RTP/”开头(由规范定义),parse 就会返回一个未知/ future 的协议(protocol)类型。

当然,问题是,您的库能否处理“未知”协议(protocol)。如果不能,则不应允许解析它们。您应该抛出 NotSupportedException 并在添加新协议(protocol)时更新库。或者,如果您希望其他人扩展,您应该允许其他人定义处理特定协议(protocol)的实现。

关于c# - 用于解析的可扩展类型安全枚举类?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17718836/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com