"Enum : Type"和简单的"Enum"有什么区别?

8

我正在尝试理解 Enums 的一些基本概念,以及它们如何与 Chars 特定配合使用。以下是我正在使用的示例:

public enum AuditInteractionTypes
{
    Authorized = 'A',
    Created = 'C',
    Revised = 'R',
    Extracted = 'E',
    Deleted = 'D'
}

首先,声明它们时enum AuditInteractionTypesenum AuditInteractionTypes : char有什么区别?
其次,我看过许多关于尝试使用charEnums以及如何“制作”来回转换的帖子。这可能是一个愚蠢的问题,但为什么我不能简单地使用string进行来回转换?
例如:Authorized = "A"
我正在使用Linq To SQL作为我的DAL,如果这很重要,不过我希望问的是一个更广泛的问题,而不是特定于我的环境。

2
请注意,在C#语言中,使用char作为枚举的基础类型是非法的。 - vcsjones
2
char 派生是无效的,但使用 char 字面值来表示每个项的值是有效的:enum Fruit : int { Apple = 'A', Orange = 'O', Banana = 'B' } - Adam Houldsworth
@AdamHouldsworth:那么为什么要加上 :int 部分呢?不理解。 - Refracted Paladin
@RefractedPaladin 这只是枚举存储的基础数据类型。当枚举数据类型具有隐式转换为 char 时,可以使用 char - Adam Houldsworth
小问题:命名指南规定您的枚举应该被命名为 AuditInteractionType;只有当 FlagAttribute 应用于枚举时,才使用复数形式。 - casperOne
@casperOne 谢谢,错过了那个。 - Refracted Paladin
3个回答

13
它规定了枚举的基础类型,用于存储枚举值。
当你仅使用enum时,它使用int作为基础存储类型。
当你使用enum : <type>时,它使用该类型作为基础存储类型。
在你的情况下,你试图使类型的基础类型为char,但根据C#参考,这是无效的:

枚举的批准类型为byte、sbyte、short、ushort、int、uint、long或ulong。

如果你想存储char值,则有两个选项。
你可以使用ushort作为基础类型(它是一个像char一样的无符号16位整数),如下所示:
public enum AuditInteractionTypes : ushort
{
    Authorized = 'A',
    Created = 'C',
    Revised = 'R',
    Extracted = 'E',
    Deleted = 'D'
}

char有一个隐式转换到ushort的功能,所以上面的代码可以正常工作。此外,你可以轻松比较这两者。

如果你想使用字符串作为值,那么我建议使用类似于enum的类,如下所示:

public static class AuditInteractionTypes
{
    // You can make these static readonly if they are likely to change.
    public const string Authorized = "A";
    public const string Created = "C";
    public const string Revised = "R";
    public const string Extracted = "E";
    public const string Deleted = "D";
}

这个类看起来与enum相似,并且编码方式也相同。
需要注意的是,任何类型都可以采用同样的技巧,但通常这些类型应该是完全不可变的。 string很好地符合了这个准则,因为它是完全不可变的(大多数系统值类型和其他值类型也是如此,如果你正确设计了它们)。

真的吗,那么为什么所有这些文章(比如这里->http://www.codeproject.com/Articles/78600/C-Enum-with-Char-Valued-Items)都在说明枚举字符之间的相互转换方法?我错过了什么吗? - Refracted Paladin
@RefractedPaladin 在 C# 中,Char 在枚举类型中并不是一个有效的“基本类型”,所以你在那篇文章中看到的是一种解决方法。 - vcsjones
@RefractedPaladin - 如果你想从char枚举的_value_中获取一个字符串,你需要将数字值(也就是char)转换为字符串表示形式。 - Oded
我明白,也许这里只是纯粹的无知在说话,但使用值为“String”或“Char”的枚举是否更简单? - Refracted Paladin
从您发布的链接中可以看出:关键发现是将枚举转换为字符,您需要先将其强制转换为字符,然后才能获得字符值。因为.NET Framework认为它是一个整数,所以您必须将其转换为字符(这样它就会将该整数转换为ASCII表上等效的字符,就像旧方法chr()一样)。 - Joe
显示剩余7条评论

2
一个枚举的“基础类型”必须是整数值类型。字符串不符合要求,因为它是引用类型。
通常仅在与非托管代码进行交互时才需要使用非默认(int)类型。C和C++语言也允许使用相同的基本类型指定枚举的大小。当您有大量[Flags]枚举值时,长整型可能会有用,从而允许您区分多达64个标志值。
如果您真的想要挤压存储要求,则可以选择字节或短整型。这可以通过更好地利用cpu缓存来加快代码速度。但总体而言,由于类或结构中其他字段的对齐要求,这种方法并不太可行。当您操作这样的枚举值时,如测试其值或隔离标志时,您可能会失去缓存优势,32位处理器确实喜欢int,您将为转换付出代价。需要进行性能分析。

操作中使用的大小(通常为32位)不必与存储大小匹配。这就是你为其付费的原因。该段落的本质。 - Hans Passant

0

回答这个问题:

可能是一个愚蠢的问题,但为什么我不能只是将其作为字符串来回传递。

您可以使用以下实现:

using System.ComponentModel;

public enum AuditInteractionTypes
{
    [Description("A")] Authorized,
    [Description("C")] Created,
    [Description("R")] Revised,
    [Description("E")] Extracted,
    [Description("D")] Deleted
}

基本上每个元素都会接收一些字符串值。

或者您可以使用结构体:

struct AuditInteractionTypes
{
    static string Authorized = "A";
    static string Created = "C";
    static int Revised = 0;
    static char[] Extracted = "E".ToCharArray(); //Not sure if this one is usefull
}

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