Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/276.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 用于解析的可扩展类型安全枚举类?_C#_.net_Parsing_Protocols - Fatal编程技术网

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

C# 用于解析的可扩展类型安全枚举类?,c#,.net,parsing,protocols,C#,.net,Parsing,Protocols,我现在完全被这个问题困扰了大约两天,似乎我根本无法解决我所面临的问题 目前,我正在编写一个SDP解析库,该库还可以用于根据规范()创建正确的SDP消息。但规范有时非常开放或不明确,因此我尝试实现必要的灵活性,同时尽可能接近RFC 示例问题 SDP消息可以包含媒体信息(“m”字段),其中该信息具有以下模式: m=<media> <port> <proto> <fmt> ... 看看proto标志,它代表媒体传输协议。根据规范,此字段可以具有以下值:

我现在完全被这个问题困扰了大约两天,似乎我根本无法解决我所面临的问题

目前,我正在编写一个SDP解析库,该库还可以用于根据规范()创建正确的
SDP
消息。但规范有时非常开放或不明确,因此我尝试实现必要的灵活性,同时尽可能接近RFC

示例问题 SDP消息可以包含媒体信息(“
m
”字段),其中该信息具有以下模式:

m=<media> <port> <proto> <fmt> ...
看看proto标志,它代表媒体传输协议。根据规范,此字段可以具有以下值:

  • RTP/AVP
  • RTP/SAVP
  • UDP
这是一个值列表,因此显然适合使用枚举

public enum MediaTransportProtocolType {
    RTP/AVP
    RTP/SAVP
    UDP
}
哎呀!但由于“/”字符的存在,这不起作用。那么,我如何能够使用它进行解析呢?我使用
DescriptionAttribute

public enum MediaTransportProtocolType {
    [Description("RTP/AVP")
    RTP_AVP
    [Description("RTP/SAVP")
    RTP_SAVP
    [Description("UDP")
    UDP
}
现在,我可以通过描述简单地查找适当的媒体传输协议类型。但现在,RFC规范还在继续:

This memo registers three values [...] If other RTP profiles are 
defined in the future [...]
因此,未来的网络设备可能会向我发送我不知道的媒体传输协议。作为
系统,整个枚举在这里不再起作用。由于各种原因,Enum
不可扩展

解决方案 在寻找解决方案的过程中,我遇到了类型安全枚举模式(又称
StringEnum
),如下所述:。这个答案甚至描述了一个使它们可切换的解决方案,即使这是一个丑陋的解决方案

但同样,这只适用于定义的范围。我用一个字典扩展了
类型安全枚举
类,以存储我可以在解析时查找的实例,但如果现在没有实例,还可以添加新实例

但是其他领域呢?那铸造呢

这里的答案描述了一种使用基类并通过显式运算符强制转换的方法:

我试过了,但不是我想要的那样。(无效的强制转换异常,脏的两次强制转换模式,不可扩展)


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

您可以执行以下操作:

m=video 49170/2 RTP/AVP 31
公共密封类MediaTransportProtocolType
{
公共静态只读MediaTransportProtocolType RtpAvp=
新的MediaTransportProtocolType(“RTP/AVP”);
公共静态只读MediaTransportProtocolType RtpSavp=
新的MediaTransportProtocolType(“RTP/SAVP”);
公共静态只读MediaTransportProtocolType Udp=
新的MediaTransportProtocolType(“UDP”);
公共静态只读只读只读集合
值=新的只读集合(
新的MediaTransportProtocolType[]{RtpAvp、RtpSavp、Udp});
私有MediaTransportProtocolType(字符串名称)
{
this.Name=Name;
}
公共字符串名称{get;private set;}
公共静态MediaTransportProtocolType解析(字符串值)
{
if(string.IsNullOrEmpty(value))
{
抛出新的ArgumentNullException(“值”);
}
var comparer=StringComparer.OrdinalIgnoreCase;
if(comparer.Equals(value,RtpAvp.Name))
{
返回RtpAvp;
}
else if(comparer.Equals(value,RtpSavp.Name))
{
返回RtpSavp;
}
else if(comparer.Equals(value,Udp.Name))
{
返回Udp;
}
else if(value.StartsWith(“RTP/”,StringComparison.OrdinalIgnoreCase))
{
//通常我们会在这里抛出一个异常,但将来
//协议是预期的,我们必须是向前兼容的。
返回新的MediaTransportProtocolType(名称);
}
抛出新的格式化异常(
该值的格式不符合要求。值:“+value”);
}
}
允许您将其用作如下枚举:

m=video 49170/2 RTP/AVP 31
var type=MediaTransportProtocolType.Udp;
您可以解析它:

var type=MediaTransportProtocolType.Parse(值);
并迭代所有已知值:

foreach(MediaTransportProtocolType.Values中的变量类型)
{
}
和parse返回一个未知/未来的协议类型,只要它们以“RTP/(由规范定义)开头


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

如果我了解您的要求,您的库必须具有“可扩展行为”,这意味着:如果将来添加更多协议类型,如果找到其中一些协议类型,则必须发生不同的行为。因此,我会考虑一个可插拔的体系结构:尝试定义需要可扩展性的接口;然后,为接口的每个实现创建不同的程序集;在运行时,您将加载所有程序集,并通过配置文件将接口映射到实现所需行为的类。查看unity.codeplex。com@br1那完全是白费力气。其思想不是扩展行为,而是允许枚举中有新值。插件体系结构在这里太过分了。只有@Atrotygma可以确认这一点,但我想在他的代码中的某个地方,他将根据枚举变量的值“切换”他的库的行为。@br已确认。一个简单解析器的插件架构就像一只狗在挖一个10英尺的洞来隐藏他的骨头:他说