我发现通常有一个单一类型或命名空间将任何特定枚举作为参数,因此我总是在那里定义这些枚举。不过最近,我让一位同事大谈特谈这是一件多么愚蠢的事情,并且您应该始终在项目的根目录中有一个枚举命名空间,您可以在其中定义每个枚举类型。
查找枚举类型的最佳位置在哪里?
我发现通常有一个单一类型或命名空间将任何特定枚举作为参数,因此我总是在那里定义这些枚举。不过最近,我让一位同事大谈特谈这是一件多么愚蠢的事情,并且您应该始终在项目的根目录中有一个枚举命名空间,您可以在其中定义每个枚举类型。
查找枚举类型的最佳位置在哪里?
为什么将枚举与其他类型区别对待?将它们保存在可能被使用的相同命名空间中 - 并假设它们将被其他类使用,在它们自己的文件中使它们成为顶级类型。
我通常聚集在一起的唯一类型是委托 - 我有时有一个 Delegates.cs 文件,其中包含一堆委托。请注意,.NET 3.5 和 Func/Action 就不那么重要了。
此外,名称空间用于分离逻辑上属于一起的事物。并非所有类都属于同一个命名空间,只是因为它们是类。同样,并非所有枚举都属于同一个命名空间,因为它们是枚举。将它们与逻辑上属于它们的代码放在一起。
我通常会尝试将所有不同的类型(类、接口和枚举)放在它们自己的文件中,不管它们有多小。它只是使查找和管理它们所在的文件变得更加容易,尤其是如果您碰巧不在 Visual Studio 中并且没有可用的“转到定义”功能。我发现几乎每次我在另一个类中放置一个这样的“简单”类型时,我最终要么稍后添加它,要么以一种不再有意义的方式重用它有自己的文件。
至于哪个命名空间,它真的取决于你正在开发的任何东西的设计。通常,我尝试模仿 .NET 框架的约定。
我尝试将与类相关的所有内容都放在类中。这不仅包括枚举,还包括常量。我不想去别处搜索包含枚举的文件或类。在具有大量类和文件夹的大型应用程序中,将枚举文件放在哪里并不总是很明显,因此很容易找到。
如果枚举在几个密切相关的类中使用,您可以创建一个基类,以便在那里共享枚举等常见类型。
当然,如果枚举真的是通用的并且被广泛使用,您可能希望为它们创建一个单独的类,以及其他通用实用程序。
我认为您将枚举和常量放在使用它们或使用它们来控制代码决策最多的类中,并且您使用代码完成来找到它们。这样你就不必记住它们在哪里,它们与类相关联。因此,例如,如果我有一个 ColoredBox 类,那么我不必考虑它们在哪里。它们将成为 ColoredBox 的一部分。ColoredBox.Colors.Red、ColoredBox.Colors.Blue 等。我认为枚举和常量是该类的属性或描述。如果它被多个类使用,并且没有一个类是至高无上的,那么有一个枚举类或常量类是合适的。这遵循封装规则。从不同的类中隔离属性。如果您决定更改 Cirle 对象中红色的 RGB 但您不这样做怎么办?不想更改 ColoredBox 对象的红色?封装它们的属性可以实现这一点。
我为此使用嵌套的命名空间。我更喜欢它们而不是将枚举放在一个类中,因为在类之外,您必须使用完整的 MyClass::MyEnum 用法,即使 MyEnum 不会与范围内的任何其他内容发生冲突。
通过使用嵌套命名空间,您可以使用“使用”语法。此外,我会将与给定子系统相关的枚举放在它们自己的文件中,这样你就不会遇到必须包含世界才能使用它们的依赖问题。
所以在枚举头文件中你得到:
// MyEnumHeader.h
// Consolidated enum header file for this dll,lib,subsystem whatever.
namespace MyApp
{
namespace MyEnums
{
enum SomeEnum { EnumVal0, EnumVal1, EnumVal2 };
};
};
然后在类头文件中你得到:
// MyInterfaceHeader.h
// Class interfaces for the subsystem with all the expected dependencies.
#include "MyEnumHeader.h"
namespace MyApp
{
class MyInterface
{
public:
virtual void DoSomethingWithEnumParam (MyEnums::SomeEnum enumParam) = 0;
};
};
或者使用尽可能多的枚举头文件。我喜欢将它们与类头分开,这样枚举就可以是系统中其他地方的参数,而不需要类头。然后,如果您想在其他地方使用它们,则不必像在类中声明枚举那样具有封装类定义。
如前所述,在外部代码中,您可以使用以下内容:
using namespace MyApp::MyEnums;
什么环境?
在 .NET 中,我通常创建一个空的类文件,将其重命名为 MyEnum 或其他任何内容以表明它包含我的枚举,然后在其中声明它。
如果我的枚举有任何机会在我打算使用它的类之外使用,我会为枚举创建一个单独的源文件。否则,我会将它放在我打算使用它的类中。
通常我发现枚举以单个类为中心——作为 MyClassOptions 类型的东西。
在这种情况下,我将枚举放在与 MyClass 相同的文件中,但在命名空间内但在类外。
namespace mynamespace
{
public partial class MyClass
{
}
enum MyClassOptions
{
}
}
我倾向于定义它们,它们的用途是显而易见的。如果我有一个结构的 typedef 出于某种原因使用它...
typedef enum {
HI,
GOODBYE
} msg_type;
typdef struct {
msg_type type;
union {
int hivar;
float goodbyevar;
}
} msg;