Enums 哪里是查找枚举类型的最佳位置?

Enums 哪里是查找枚举类型的最佳位置?,enums,Enums,我发现通常有一个单一类型或名称空间,它接受任何特定的枚举作为参数,因此我总是在那里定义这些枚举。不过,最近我有一位同事大肆宣扬这是一件多么愚蠢的事情,而且您应该在项目的根目录中始终有一个枚举名称空间,在那里定义所有枚举类型 哪里是查找枚举类型的最佳位置?什么环境 在.NET中,我通常创建一个空类文件,将其重命名为MyEnum或其他任何名称,以表明它保存了我的枚举,并在其中声明它。如果我的枚举有可能在我打算使用的类之外使用,我会为枚举创建一个单独的源文件。否则,我将把它放在我打算使用它的类中。此外

我发现通常有一个单一类型或名称空间,它接受任何特定的枚举作为参数,因此我总是在那里定义这些枚举。不过,最近我有一位同事大肆宣扬这是一件多么愚蠢的事情,而且您应该在项目的根目录中始终有一个枚举名称空间,在那里定义所有枚举类型

哪里是查找枚举类型的最佳位置?

什么环境


在.NET中,我通常创建一个空类文件,将其重命名为MyEnum或其他任何名称,以表明它保存了我的枚举,并在其中声明它。

如果我的枚举有可能在我打算使用的类之外使用,我会为枚举创建一个单独的源文件。否则,我将把它放在我打算使用它的类中。

此外,名称空间用于分离逻辑上属于一起的事物。并非所有类都属于同一名称空间,仅仅因为它们是类。同样,并非所有枚举都属于同一名称空间,因为它们是枚举。把它们和逻辑上属于它们的代码放在一起。

我倾向于定义它们,它们的用法在明显的例子中是显而易见的。如果我有一个结构的typedef,出于某种原因使用它

typedef enum {
  HI,
  GOODBYE
} msg_type;

typdef struct {
 msg_type type;
 union {
   int hivar;
   float goodbyevar;
  }
} msg;

通常,我发现枚举以单个类为中心——作为MyClassOptions类型

在这种情况下,我将枚举与MyClass放在同一个文件中,但在名称空间内,但在类之外

namespace mynamespace
{
  public partial class MyClass
  {
  }
  enum MyClassOptions
  {
  }
}

我通常尝试将所有不同类型(类、接口和枚举)放在它们自己的文件中,而不管它们有多小。它只会使查找和管理它们所在的文件变得更加容易,特别是如果您不在Visual Studio中并且“转到定义”功能可用的话。我发现,几乎每次我在另一个类中放入这样的“简单”类型时,我都会在以后添加它,或者以一种不再需要它自己的文件的方式重用它


至于哪个名称空间,它实际上取决于您正在开发的任何东西的设计。一般来说,我尝试模仿.NET framework的惯例。

为什么要将枚举与其他类型区别对待?将它们保持在可能被使用的相同名称空间中——并且假设它们将被其他类使用,则在它们自己的文件中使它们成为顶级类型


唯一一种我经常聚集在一起的类型是委托-我有时有一个delegates.cs文件,其中有一堆委托。请注意,对于.NET3.5和Func/Action,情况就不是这样了。

我尝试将与类相关的所有内容都放在类中。这不仅包括枚举,还包括常量。我不想在别处搜索包含枚举的文件或类。在一个有很多类和文件夹的大型应用程序中,通常不会很明显地将enum文件放在哪里,这样就很容易找到它

如果枚举用于几个密切相关的类,则可以创建一个基类,以便共享诸如枚举之类的常见类型


当然,如果一个枚举是真正的泛型且被广泛使用,那么您可能需要为它们创建一个单独的类,以及其他泛型实用程序。

我认为您将枚举和常量放在使用它们的类中,或者将它们用于控制代码决策的类中,然后使用代码完成来查找它们。这样,您就不必记住它们在哪里,它们与类相关联。例如,如果我有一个ColoredBox类,那么我不必考虑它们在哪里。它们将是彩盒的一部分。ColoredBox.Colors.Red、ColoredBox.Colors.Blue等I 我认为枚举和常量是该类的属性或描述。 如果它被多个类使用,并且没有一个类占主导地位,那么使用enum类或constants类是合适的。 这遵循封装规则。从不同的类中隔离属性。如果您决定更改Cirle对象中红色的RGB,但是
您不想更改ColoredBox对象的红色吗?封装它们的属性可以实现这一点。

我为此使用嵌套的名称空间。与将枚举放在类中相比,我更喜欢它们,因为在类之外,您必须使用完整的MyClass::MyEnum用法,即使MyEnum不会与范围中的任何其他内容发生冲突

通过使用嵌套的名称空间,可以使用“using”语法。此外,我还将把与给定子系统相关的枚举放在它们自己的文件中,这样您就不会遇到必须包含世界才能使用它们的依赖性问题

因此,在枚举头文件中,您可以得到:

// 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;
  };
};
然后在类头文件中,您会得到:

// 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;
  };
};
或者使用尽可能多的枚举头文件。我喜欢将它们与类头分开,以便枚举可以是系统中其他地方的参数,而不需要类头。然后,如果您想在其他地方使用它们,您不必像在类中声明枚举那样拥有封装类def

如前所述,在外部代码中,您可以使用以下内容:

using namespace MyApp::MyEnums;

任何与“最佳实践”相关的东西都是主观的,但我认为你的同事错了。NET framework不包含枚举命名空间,这是有充分理由的。将枚举放在它们逻辑上最属于的命名空间中。(如果合适的话,是的,把他们放在一个班里。)在你的同事解释她/他的问题之前,“愚蠢”并不是你可以采取行动的标准。这样说,同事是错的。如果解决方案有很多项目,枚举被用于多个项目,在一个地方.NET中有它们是有意义的,但是我认为在C++中同样如此。