何时使用枚举(Enum)和结构体(Struct)

4
在我们的数据库中,有一个名为ObjectType的表。该表只是包含了一系列带有Id和ObjectName的行。在我们的后端代码中,我们以不同的方式处理不同的对象,因此经常需要引用对象的ID进行比较。这些ID始终相同,并且它们始终映射到相同的对象。
如果我的方法期望传递一个整数值,那么哪种结构体对于处理这些对象更好?
何时使用结构体?何时使用枚举?

我脑海中浮现的第一个是一个类。 - Tim Schmelter
4个回答

10

枚举类型不能与结构体互换使用,它们拥有完全不同的用途。 结构体可以有成员和方法,而枚举只能有标签和标签的值。

你可以使用枚举类型来指定系统的不同行为。

假设你有一个名为Person的类,并且出于某种原因人可以有情绪状态。

一个好的实现方式是使用以下枚举类型:

enum EmotionalState
{
     Happy = 3,
     Sad,
     Shy    
}

你可以像这样将枚举项用作整数:

int b = (int)EmotionalState.Sad // <---4

而且也可以在反向方向进行

int v = 3;
EmotionalState s = (EmotionalState)v; // Happy
请注意,枚举成员没有类型。它们也可以被指定一个起始值。例如,如果您在第一项上分配3,则下一项将被标记为4。
一个很好的结构体示例是一个点(Point)。
struct Point {
   int a;
   int b;
}

结构体应该尽可能小,因为它们是值类型并且存储在堆栈上,而引用类型存储在堆上。


我唯一真正的需求是能够看到每个对象中存储的Id/Value。这样,如果我说var someVar = ObjectType.Role,我就可以将一个整数值分配给someVar。这也会使我的代码更易读,因为我不会说if (objectType == 15) { }。我只需要确保分配给变量的值在我使用数字Id进行多次插入/查询时仍然容易访问。过去,我曾使用具有静态定义值或常量的结构体。 - JD Davis
@Jdsfighter 如果这在概念上是有意义的话,你可以将它们归为一个枚举中(例如情感状态的示例)。在枚举中分配的值很容易访问,例如EmotionalState b = (EmotionalState)15; - Christo S. Christov
“枚举可以只有标签和标签对应的值。”这是错误的,枚举也可以包括其他成员。 - Marcos Pereira

4

struct并不是enum的替代品,它是class的替代品。在结构体和类中,只有内存布局不同。

如果您不需要让代码跟随并支持添加到数据库中的新条目,则可以选择使用枚举类型。

否则,如果您需要支持新的数据库条目,则应考虑使用Dictionary<int, string>


基本上,我想做的是能够使用对象中包含的整数值来确定选择了哪个对象,然后使用ID来操作其他记录。例如,说“ObjectType.User”将返回9,因此在我的代码中,我可以将此值分配给另一个记录/变量,但我也可以将其用于比较。这些值不需要从数据库中获取,因为它们几乎不可能改变。 - JD Davis
枚举类型确实很好用,但缺点是你需要将它们与数据库保持同步。 - Fabio Salvalai

1

枚举是一组可供选择的不同选项列表,结构体用于存储变量(它类似于类,但主要用于仅存储数据)。

enum Sports {
        Soccer, Tennis, Football, Baseball
}

输出结果为:体育。 | 足球 | | 网球 | | 足球 | | 棒球 |


在我的情况下,我只是想在每个变量/选项中存储一个整数值。这样我就可以轻松提取该值并在必要时执行查询,但它还可以防止我在比较中使用魔数。 - JD Davis

0
你可以将整个 ObjectType 表读入到一个 Dictionary<string, int> 中。将 idObjectName 进行映射。对于那些期望 int 类型的方法,你可以传递 objectTypeMapping["objectName"]

幸运的是,ObjectType表相当小且完全静态。一旦在代码中定义,我只想调用类似于 ObjectType.User 的东西并返回一个整数值。 - JD Davis
@Jdsfighter:对于这种情况,枚举和字典都可以。即使 ObjectType 表是静态的,你能保证你的 ID 始终以 1 递增吗?如果不能,那就使用字典,因为在读取表后,让应用程序每次启动时自动准备字典比手动修改硬编码的枚举更容易,尤其是当你的表发生变化时。 - displayName
表格数据是静态的,过去开发人员在每行代码中硬编码了ID。有数百(如果不是数千)个存储过程仅通过它们的ID引用对象。在我们的后端代码中也是如此。 - JD Davis
@Jdsfighter:好的,所以你正在尝试通过重构硬编码ID来提高代码的可读性。你只需要寻找枚举类型。准备好你的枚举类,然后在你的解决方案中查找所有应该替换为“ObjectType.User”之类的行的魔法数字。 - displayName

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