【问题标题】:Is there a typesafe enum conversion from int in c#?c# 中是否有从 int 的类型安全枚举转换?
【发布时间】:2013-11-13 17:45:29
【问题描述】:

我知道我可以使用强制转换将 int 转换为枚举

MyEnumType myEnum = (MyEnumType) myInteger;

这里的问题是,如果 myInteger 不是 int 类型,则运行时转换不会阻止我在构建时进行操作

void MyMethod(MyObject myObject)
{
    MyEnumType myEnum = (MyEnumType) myObject.someProperty;
    ....
}

上述代码模式并不少见,但如果对象的属性类型已更改,它不会在构建时保护我。

是否有一种内置方法来进行这种转换,这会给我一个构建时错误?当然,我可以很容易地编写一个通用方法,但我想知道是否内置。

【问题讨论】:

  • 即使这是可能的,当执行仅在运行时已知的值的强制转换时,您怎么能期望得到构建时错误?您希望从哪些其他“非 int”类型转换?您不能将任意对象强制转换为枚举。
  • @JeffMercado 我希望来执行演员阵容。类型化的方法会给我编译时反馈,因为我不依赖演员表。
  • 我认为“Enum.TryParse(myInteger.ToString())”应该可以工作。 (高清修复,这里没办法测试)。
  • @Servy 是的,这正是我的观点。我不希望我的代码编译。但如果 somePropertyobject 类型,那么它编译。
  • 鉴于枚举可以是任何整数类型(byte、sbyte、short、ushort、int、uint、long 或 ulong),因此无法在编译时检查溢出,那么为什么要检查类型呢?

标签: c# casting enums compiler-errors


【解决方案1】:

你可以使用

Enum.TryParse(myInteger.ToString(), out result)

获取 int 的 Enum 值。

希望这会有所帮助,

【讨论】:

  • 这不是你称呼TryParse的方式。此外,它用于获取表示枚举值之一的名称的字符串,而不是整数表示,因此即使您修复了如何调用它,这也不起作用。
  • @Servy 根据 MSDN,您也可以使用整数值调用 TryParse。我也不知道。 msdn.microsoft.com/en-us/library/dd783499(v=vs.110).aspx
  • 根据 MSDN 文档 msdn.microsoft.com/en-us/library/dd783499(v=vs.110).aspx 它确实采用名称或基础值
  • 无论如何,这根本不应用静态类型。目标是确保只有在知道转换将成功时才能编译代码,这样如果程序员在错误类型上调用方法,他们就会得到编译时错误,而不是运行时的错误。这种方法不这样做。您可以在任何事情上致电ToString。这并不比投射更好。
  • 它可能不会抛出编译时错误,但也不会抛出运行时错误......
【解决方案2】:

您可以轻松地为您的一个枚举创建一种方法来执行此操作:

public static MyEnumType CastFromInt<T>(int n)
{
    return (MyEnumType)n;
}

遗憾的是,由于无法应用泛型约束以使泛型类型参数成为枚举,因此没有好的 方法来泛化它。你可以这样写:

public static T CastFromInt<T>(int n)
{
    return (T)(object)n;
}

但假设调用者使用枚举作为T 的类型。如果他们不这样做,那就有问题了。这也不必要地将整数装箱。

【讨论】:

  • OP 要求“构建时错误”。这在编译时不会失败。这实际上将隐藏在编译时会发生的错误,例如MyEnumType = 3。 OP 想要做的事情根本不可能。
  • @P.Brian.Mackey 第一个正是 OP 正在寻找的,它只需要为每种类型的枚举编写。如果T 使用非枚举值,或者T 使用不受整数支持的枚举,则第二个将在运行时失败。在第一种方法的情况下,没有调用将编译的方法,也没有成功地将整数转换为给定的枚举。
  • MyEnumType e = 3 => 如果此值无效,则编译时错误。 MyEnumType e = CastFromInt&lt;MyEnumType&gt;(3) => 运行时错误。降级。
  • @P.Brian.Mackey 第二个 sn-p 不会 在运行时抛出错误。它将返回代表值3 的该枚举的实例。如果枚举是由 int 支持的。是什么让你认为这会失败?作为记录,MyEnumType e = 3 always 无法编译,没有“如果没有有效值”。它永远不会编译。
  • 噢,抱歉,我在测试中搞砸了。
猜你喜欢
  • 2020-01-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-11
相关资源
最近更新 更多