【问题标题】:Why does accessing an Enum member not present in the enum definition (via casting an integer) not give an error为什么访问枚举定义中不存在的枚举成员(通过转换整数)不会给出错误
【发布时间】:2018-10-24 19:45:39
【问题描述】:

要修复我的应用程序中的错误,我必须像这样设置 System.Net 程序集中的 ServicePointManager 类的 SecurityProtocolType:

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;

在 .Net 4.5+ 中,SecurityProtocolType 枚举有四个成员:

public enum SecurityProtocolType
{
    Ssl3 48,    
    Tls 192,    
    Tls11 768,  
    Tls12 3072
}

但是,在 .Net 4.0 中,SecurityProtocolType 枚举只有两个成员:

public enum SecurityProtocolType
{
    Ssl3 48,    
    Tls 192
}

因为,我的代码中的另一个项目也需要相同的修复,但该项目位于 .Net 4.0 上,它没有 Tls12 作为枚举成员,this 答案建议以下解决方法(前提是我有 .Net 4.5安装在同一个盒子上):

ServicePointManager.SecurityProtocol = (SecurityProtocolType)3072;

可能是我缺少明显的东西,但我的问题是,当 3072 不是 .Net 4.0 中枚举的有效值时,(SecurityProtocolType)3072 如何解析为 Tls12。我想了解使这项工作在幕后发生了什么魔力。

【问题讨论】:

  • 枚举只是以整数形式存储。我不记得我在哪里看到的,但枚举类本质上只是一个静态类,每个枚举值都有一堆公共 const int 成员。这就是为什么当你编写一个 switch 块时,即使你涵盖了枚举中的每个选项,你仍然需要一个默认情况。 ServicePointManager 可能只是将枚举值作为 int 传递给底层系统调用,它会识别值 3072,即使它没有在枚举中定义
  • stackoverflow.com/questions/6488884/… 这可能会有所帮助,在后台它只是存储为 int,因此调用本质上是无操作
  • @ReeseDeWind 你能详细说明一下“基本上没有操作”吗?如果 no-op 是对 Win32 编程的引用,我对 Win32 编程不熟悉
  • 无操作只是一个什么都不做的指令。在您的情况下,编译器基本上发出类似int SecurityProtocol = (int)3072;
  • @AdamG 谢谢,我现在明白了。尽管 .Net 4.0 如何能够理解如何处理 3072 以及它如何赋予它特殊含义,但这仍然没有解释。

标签: c# .net enums


【解决方案1】:

来自 C# 中枚举的文档 (MSDN)

Day 类型的变量可以被赋值为基础类型范围内的任何值;值不限于命名常量。

所以代码编译肯定没有问题。另外:

与任何常量一样,对枚举的各个值的所有引用都会在编译时转换为数字文字。这可能会产生潜在的版本控制问题,如常量中所述。

为新版本的枚举分配额外的值,或在新版本中更改枚举成员的值,可能会导致依赖源代码出现问题。

您实际上是在利用这一点。在 .NET 4.0 上运行的框架不知道如何处理 3072 值,但 .NET 4.5 框架可以。您只是没有方便的快捷方式(枚举)来获取该值。

【讨论】:

  • 谢谢。我得到的第一部分是可以为 int 枚举分配任何有效的 int 值。但我还是不明白 4.0 和 4.5 之间的相互作用。 .Net 4.0 如何“理解” 3072 表示 TLS 1.2 并开始使用 Http 调用的设置。是否存在对 Tls 1.2 的支持但未通过 API 公开的事实?所以,3072 可能是一个可赋值的值,因为枚举基类型是 int,但是框架 4.0 是如何知道如何处理该值的呢?希望这是有道理的
  • @PunitVora 您对问题的评论可能是正确的,该值只是直接传递给 Win32 调用,只要该调用可以识别它就可以了。或者,我相信 4.5 将运行 4.0 应用程序,它可能只是使用该版本的框架
  • 这是不正确的。此解决方法仅在您安装 .Net 4.5 时有效。如果没有安装 .Net4.5,此解决方法不起作用,因此该框架不是简单地将值传递给 Win32,
猜你喜欢
  • 1970-01-01
  • 2018-05-02
  • 1970-01-01
  • 2018-11-05
  • 2013-01-17
  • 2018-07-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多