.net 两成员枚举与布尔值

.net 两成员枚举与布尔值,.net,enums,boolean,.net,Enums,Boolean,这个问题在我脑海里已经有一段时间了,如果它显得主观的话,很抱歉。在数据对象的公共属性和构造函数中使用bool有一些缺点。考虑下面的代码作为一个例子。 使用bool: public class Room { public string Name { get; set; } public bool Bookable { get; set; } public Room(string name, bool bookable); } public enum BookingSta

这个问题在我脑海里已经有一段时间了,如果它显得主观的话,很抱歉。在数据对象的公共属性和构造函数中使用bool有一些缺点。考虑下面的代码作为一个例子。

使用bool:

public class Room
{
    public string Name { get; set; }
    public bool Bookable { get; set; }

    public Room(string name, bool bookable);
}
public enum BookingStatus
{
    Bookable,
    NotBookable
}

public class Room
{
    public string Name { get; set; }
    public BookingStatus Bookable { get; set; }

    public Room(string name, BookingStatus bookable);
}
以及这个类的使用

Room r = new Room ("101", true);
Room r = new Room ("101", BookingStatus.Bookable);
这是适当的功能,但是还有另一种实现方法:

使用枚举:

public class Room
{
    public string Name { get; set; }
    public bool Bookable { get; set; }

    public Room(string name, bool bookable);
}
public enum BookingStatus
{
    Bookable,
    NotBookable
}

public class Room
{
    public string Name { get; set; }
    public BookingStatus Bookable { get; set; }

    public Room(string name, BookingStatus bookable);
}
以及这个类的使用

Room r = new Room ("101", true);
Room r = new Room ("101", BookingStatus.Bookable);
在我看来,这两者在功能上是等效的,但它们都有一些优点和缺点:

  • 设置属性时,枚举方法更加详细(您可以仅从代码推断枚举的用法)
  • 枚举可以扩展以支持更多状态(对于API特别有用)
  • 枚举需要相当多的类型(尽管大大减少了这一点)
  • 枚举不能用于条件语句(即if(r.bookable)),尽管我知道这很难解决
我是不是漏掉了什么,完全不对劲?我不知道为什么这让我如此烦恼,也许我太强迫症了,对我自己来说太好了

在他的书中,Martin Fowler解释了为什么他认为枚举是一种代码气味,我只能同意。在您的示例中,更好的方法是创建一个抽象房间类:

public abstract class Room
{
     public string Name { get; set; }

     public abstract bool Bookable { get; }
}
然后可以生成派生的BookableRoom和NonBookableRoom类

public class BookableRoom : Room
{
    public override bool Bookable
    {
        get { return true; }
    }
}

public class NonBookableRoom : Room
{
    public override bool Bookable
    {
        get { return false; }
    }
}

Ih将来可能会有更多的选项,在枚举中添加第三个选项比将所有bool更改为enum要简单得多。

仅仅因为代码的可读性和理解性,我将选择enum而不是boolean

比较
BookingStatus.Bookable
true
,当然你会了解更多阅读
BookingStatus.Bookable


同样正如fforw所提到的,如果将来您可能需要添加更多选项,enum将更容易更改。

对于一个属性,我可能会同意。不过,在“干净代码”中,(正确地)指出bools在用作参数时隐藏意图。例如,格式化方法可能如下所示:

public void Format(bool pBold, bool pItalic, bool pUnderline)
{ ... }
Format(BOLD.BOLD, ITALIC.NOT_ITALIC, UNDERLINE.NOT_UNDERLINE);
调用时,它看起来像:

Format(true, false, true);
相反,它的可读性更高,因为:

public enum BOLD { BOLD, NOT_BOLD }
public enum ITALIC { ITALIC, NOT_ITALIC }
public enum UNDERLINE { UNDERLINE, NOT_UNDERLINE }

public void Format(BOLD pBold, ITALIC pItalic, UNDERLINE pUnderline)
{ ... }
这使得电话看起来像:

public void Format(bool pBold, bool pItalic, bool pUnderline)
{ ... }
Format(BOLD.BOLD, ITALIC.NOT_ITALIC, UNDERLINE.NOT_UNDERLINE);
(请记住,这只是bool参数如何隐藏意图的一个示例;可能有更好的方法来实现上述代码。)

在您的特定情况下,请注意两个构造函数调用之间的差异:

// enum; intent is clear
Room r = new Room ("101", BookingStatus.Bookable);

// bool; true what?
Room r = new Room("101", true);

优点,我在其他地方用过的方法。我想这对实体框架之类的东西不太管用吧?然而,它肯定会很好地映射到类似SharePoint列表的东西上。为什么您认为这是一种更好的方法?对我来说,它看起来正变得越来越复杂。我认为接吻原则在这里是合适的。这本书提供了一个全面的描述:)我同意@nightcoder的观点,对这个答案的选择感到困惑。OP是否担心枚举不会是一种复杂而冗长的方式,不足以翻转一个位?所以我们应该将每个对象类型的每个运行时状态烘焙到源代码中?Martin Fowler说了些什么来为这种做法辩护?那么当你有多个状态属性时你会怎么做?添加更多的类?添加提供每种可能的状态组合的类?这是他在回答中已经说过的(项目符号列表中的第二点)。除了“未来计划”方面。关于类型安全性呢?枚举可以防止任何旧的布尔值被丢弃到枚举参数中。这也是更好的维护方法。使用枚举时更改较小如果发明了一种新的BookingStatus,则在使用枚举时,不能将包含可能粗体值的变量放入“italic”参数槽中。:)键入safety.
//字符串;“101”什么?
再添加几个字符串,您将处于与布尔相同的位置。那你是做什么的?您可以查看方法定义。@Stijn同意。不阅读方法签名并不是不理解方法签名的借口。观点:这似乎不是最好的例子——如果这是一个真的是/否问题,那么bool是合适的。尽管你应该按照惯例正确命名你的房产(即“可预订”)——更好的例子是非是或非问题,比如性别或测量单位等——即使你只识别两种状态(英寸对厘米,或男性对女性),你也应该使用枚举,因为这些绝对不是“是或否”问题(即使你可以把它们变成是/否问题,但它们不是,并且可以扩展到支持更多的州)。