枚举和匹配属性的C#命名约定

Ser*_*ier 90 .net c# enums naming-conventions

我经常发现自己实现了一个类来维护某种自己的状态属性作为枚举:我有状态类型的状态枚举和状态属性.我该如何解决这个名称冲突?

public class Car
{
  public enum Status
  {
    Off,
    Starting,
    Moving
  };

  Status status = Status.Off;

  public Status Status // <===== Won't compile =====
  {
    get { return status; }
    set { status = value; DoSomething(); }
  }
}
Run Code Online (Sandbox Code Playgroud)

如果Status enum对于不同的类型是通用的,我会把它放在课外,问题就会解决.但Status仅适用于Car,因此在类外声明枚举是没有意义的.

在这种情况下你使用什么命名约定?

注意:在回答这个问题的评论中,对这个问题进行了部分辩论.由于这不是主要问题,因此没有太多可见性.

编辑:Filip Ekberg建议IMO针对"状态"的具体案例提供出色的解决方法.然而,我很有兴趣阅读关于枚举/属性名称不同的解决方案,如Michael Prewecki的回答.

EDIT2(2010年5月):我最喜欢的解决方案是按照Chris S的建议复数枚举类型名称.根据MS指南,这应该仅用于标记枚举.但我越来越喜欢它了.我现在也将它用于常规枚举.

Fil*_*erg 34

"关闭","开始"和"移动"的定义就是我所说的"国家".当你暗示你正在使用"状态"时,它就是你的"状态".所以!

public class Car
{
  public enum State
  {
    Off,
    Starting,
    Moving
  };

  State state = State.Off;

  public State Status
  {
    get { return state ; }
    set { state= value; DoSomething(); }
  }
}
Run Code Online (Sandbox Code Playgroud)

如果我们从你所说的那个中使用"Type"这个词的另一个例子,在这种情况下:

public class DataReader
{
    public enum Type
    {
        Sql,
        Oracle,
        OleDb
    }

    public Type Type { get; set; } // <===== Won't compile =====

}
Run Code Online (Sandbox Code Playgroud)

你真的需要看到枚举和枚举之间有区别,对吧?但是在创建框架或谈论架构时,您需要关注相似性,确定可以找到它们:

当某些东西设置为某个状态时,它被定义为"事物"状态

示例:Car的状态处于Running State,Stopped State等状态.

你想在第二个例子中实现的是某种程度的:

myDataReader.Type = DataReader.Database.OleDb
Run Code Online (Sandbox Code Playgroud)

你可能会认为这反对我一直在向别人讲道,你需要遵循一个标准.但是,你遵循标准!Sql-case也是一个特定的案例,因此需要一些特定的解决方案.

然而,枚举可以在你的System.Data空间内重复使用,这就是模式的全部内容.

使用"Type"查看的另一个案例是"Animal",其中Type定义了Species.

public class Animal
    {
        public enum Type
        {
            Mammal,
            Reptile,
            JonSkeet
        }

        public Type Species{ get; set; }

    }
Run Code Online (Sandbox Code Playgroud)

这是一个模式,你没有特别需要"知道"对象,你没有指定"AnimalType"或"DataReaderType",你可以重新使用你选择的命名空间中的枚举.

  • 我相信“状态”名称只是一个例子。当您不能依赖 Status/State 时,其他情况呢?例如一个类型枚举... (2认同)
  • @Filip:动物类型样本完全指出了我在第一条评论中的含义,即这是枚举的"重写".我认为,使用枚举和属性名称的同义词会使代码有点混乱. (2认同)
  • 简单地重命名并不总是那么干净 - 想想一个扑克牌的类,例如enum Suit和属性套装 - 重命名到什么?两种方式都很笨拙. (2认同)

Chr*_*s S 31

我会在讨论中添加1欧元,但可能不会添加任何新内容.

显而易见的解决方案是将Status移出嵌套的Enum.大多数.NET枚举(除了可能是Windows.Forms命名空间中的一些)都没有嵌套,这使得使用API​​的开发人员很烦人,必须在类名前加上前缀.

有一点没有提到,根据MSDN指南的标志枚举应该你可能已经知道的复数名词(状态是一个简单的枚举,所以应该使用单数名词).

国家(enum称为州)是一种称呼,"状态"是一个名词的主格,英语就像我们的大多数语言从拉丁语中吸收.Vocative是你为其条件命名的名词,而主格是动词的主语.

因此,换句话说,当汽车正在移动,这就是动词-移动是其状态.但是汽车没有发动,它的引擎确实如此.也没有启动,引擎确实(你可能在这里选了一个例子,所以这可能是无关紧要的).

public class Car
{
  VehicleState _vehicleState= VehicleState.Stationary;

  public VehicleState VehicleState 
  {
    get { return _vehicleState; }
    set { _vehicleState = value; DoSomething(); }
  }
}

public enum VehicleState
{
    Stationary, Idle, Moving
}
Run Code Online (Sandbox Code Playgroud)

国家是这样一个广义名词,描述它所指的是什么状态不是更好吗?就像我上面做的那样

我的视图中的类型示例不是指读者类型,而是指其数据库.如果您描述读者的数据库产品并不一定与读者类型相关(例如,读者的类型可能只是前向,缓存等),我更愿意这样做.所以

reader.Database = Databases.Oracle;
Run Code Online (Sandbox Code Playgroud)

实际上,这不会发生,因为它们被实现为驱动程序和继承链而不是使用枚举,这就是为什么上面的行看起来不自然.

  • 我的理解是标志应该是多元化的,而不是简单的枚举. (24认同)
  • 关于将枚举移出课堂,我还没有理解为什么CarState比Car.State更方便.但是,当这个枚举仅描述此类的行为时,我不理解从类中获取枚举的积极方面. (8认同)

Jon*_*jap 9

我认为这里真正的问题是enum Status被封装在你的类中,Car.Status这对于属性Status和枚举都是不明确的Status

更好的是,把你的枚举放在课堂之外:

public enum Status
{
    Off,
    Starting,
    Moving
}

public class Car
{
    public Status Status
    { ... }
}
Run Code Online (Sandbox Code Playgroud)

UPDATE

由于下面的评论,我将在上面解释我的设计.

我是一个不相信枚举或类或任何其他对象应该驻留的人 另一个类中的人,除非它在该类中完全是私有的.以上面的例子为例:

public class Car
{
    public enum Status
    {...}
    ...
    public Status CarStatus { get; set;}
}
Run Code Online (Sandbox Code Playgroud)

虽然有些评论者认为Status在Car类的范围之外没有任何意义,但是你设置公共属性的事实意味着该程序的其他部分使用该枚举:

public Car myCar = new Car();
myCar.CarStatus = Car.Status.Off;
Run Code Online (Sandbox Code Playgroud)

对我来说是一个代码味道.如果我要去看看那个状态之外Car,我还不如把它定义之外也是如此.

因此,我可能会将其重命名为:

public enum CarStatus
{...}

public class Car
{
    ...
    public CarStatus Status { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

但是,如果该枚举将汽车类内部使用,那么我可以在那里声明枚举.


nat*_*ere 6

那些讨厌匈牙利记数法及其变体的人都该死。我使用枚举后缀的约定 - 等等 - Enum。因此,我从来没有遇到过你所描述的问题,浪费时间担心如何称呼它们,并且代码是可读的并且是自描述的。

public class Car
{
  public enum StatusEnum
  {
    Off,
    Starting,
    Moving
  };

  public StatusEnum Status { get; set; }

}
Run Code Online (Sandbox Code Playgroud)

  • 请注意,Microsoft 的[命名枚举](http://msdn.microsoft.com/en-us/library/ms229040%28v=vs.110%29.aspx) 约定表示:***X 不* ** *在枚举类型名称中使用“Enum”后缀。* (11认同)
  • 因为微软的惯例已被证明经得起时间的考验。 (2认同)

小智 5

我知道我的建议违反了 .NET 命名约定,但我个人用“E”和枚举标志前缀“F”(类似于我们如何用“I”前缀接口)。我真的不明白为什么这不是约定。枚举/标志是一种特殊情况,如接口永远不会改变它们的类型。它不仅清楚地表明它是什么,而且很容易输入智能感知,因为前缀将过滤大多数其他类型/变量/等,并且您不会有这些命名冲突。

这也将解决另一个问题,对于 WPF 中的示例,它们使用静态类,如具有预定义类型实例的枚举(例如 FontWeights),但如果您不搜索它,您将不知道。如果他们只是用“E”作为前缀,您所要做的就是输入字符以找到这些特殊的静态类。