C#和VB.NET中枚举的差异

6
我们有一些遗留的字符编码,我们想要在新系统中将它们存储为数字。为了增加程序员在迁移过程中的代码阅读性和理解性,我想做出如下的枚举类型...
Public Enum Status As Short
    Open = AscW("O")
    Closed = AscW("C")
    Pending = AscW("P")
    EnRoute = AscW("E")
End Enum

使用这种设置,代码将变得可读(想象一下If Record.Status = Status.Open),但是值将存储在数据库中作为小数字,因此它将是高效的。然而...我是VB.NET的人,但每个人都想在C#中编码,所以我需要这种结构在C#中。

通过谷歌搜索,我发现AscW的.NET通用等效方式是Convert.ToInt32("C")。当我尝试在枚举中使用该语句时,我会得到编译器错误“需要常量表达式”。

我如何在C#中实现这一点?有更好的方法吗?

2个回答

11

方法调用不是常量表达式。尝试这样做:

public enum Status { 
   Open = 'O',
   Closed = 'C',
   Pending = 'P',
   EnRoute = 'E'
}
AscW在VB中能够工作的原因是它是VB编译器理解并在编译时计算的内部内容,并且被编译器视为常量表达式。即使在VB中,Convert.ToInt32也无法使用。
引用Visual Basic规范的说法:
11.2 常量表达式
常量表达式是一种可以在编译时完全评估其值的表达式。[...] 常量表达式允许使用以下结构:
[...]
下列运行时函数:
Microsoft.VisualBasic.Strings.ChrW
如果常量字符串不为空,则 Microsoft.VisualBasic.Strings.AscW
如果常量字符串不为空,则 Microsoft.VisualBasic.Strings.Asc

4
Nick说:“AscW 声明在 Microsoft.VisualBasic 中并不是很重要,关键是编译器已经内置了对 AscW 的理解,而且它并不会在运行时调用任何方法。编译器只是在编译时将表达式替换为其整数值。” - Mehrdad Afshari
2
+1,这比那稍微复杂一些。AscW既被编译器充分理解,也是VB运行时的一个特性。在常量和有效表达式的情况下,编译器将优化掉AscW调用。但在不是常量或无法理解的情况下,它将推迟到VB运行时。 - JaredPar
@JaredPar:是的,当参数是常量时,值无法在编译时被替换。关键是,正如你所说,运行时函数在这里是无关紧要的。顺便说一句,我认为这并不算是一种“优化”,因为规范明确要求这种行为。 - Mehrdad Afshari
我想补充一下,我觉得在VB中无法像这样使用字符串常量有点令人不安。我会收到错误消息“无法在常量表达式中将字符串转换为短整型”。然后我尝试了一个Char字面值,但也不起作用(类似的消息)。我猜编译器对于AscW函数比对字面值更容易插入。:D - Josh Stodola
1
@Josh:VB.NET(与C#不同)不支持从字符到整数的隐式强制转换。这个设计决策使得简单地编写"EnumMember = "A"c"无法工作。这并不是实现容易程度的问题。 - Mehrdad Afshari
显示剩余3条评论

3

试试这个:

public enum Status
{
    Open    = 'O',
    Closed  = 'C',
    Pending = 'P',
    EnRoute = 'E'
}

谢谢,是的,我也会点赞,因为你们的回答只相差几秒钟。你们真的很 - Josh Stodola

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接