两个成员枚举与布尔值

时间:2009-11-06 10:04:21

标签: .net enums boolean

这个问题在我的脑海里已经有一段时间了,对不起,如果它看起来是主观的。在公共属性中使用bool和在数据对象中使用构造函数存在一些缺点。请考虑以下代码作为示例。

使用bool:

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

    public Room(string name, bool bookable);
}

和使用这个类

Room r = new Room ("101", true);

这是适当的功能,但有另一种方法来实现它:

使用枚举:

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", BookingStatus.Bookable);

对我来说,这两个看起来功能相同,但每个都有一些优点和缺点:

  • 设置属性时,Enum方法更详细(您可以从代码中推断枚举的用法)
  • 可以扩展枚举以支持更多状态(对API特别有用)
  • 枚举需要更多的输入(虽然大大减少了)
  • 枚举不能用于条件(即if(r.bookable)),虽然我知道这是微不足道的解决。

我错过了什么,完全不合适吗?我不知道为什么这会让我这么烦恼,也许我为了自己的利益而过于强迫症!

4 个答案:

答案 0 :(得分:8)

仅仅因为对代码的可读性和理解,我将使用枚举而不是布尔值。

比较BookingStatus.Bookabletrue,当然您会理解更多阅读BookingStatus.Bookable

也像fforw所提到的那样,如果将来你可能需要添加更多选项,枚举会更容易改变。

答案 1 :(得分:5)

是否有可能在将来可能有超过最初的两个选项,为枚举添加第三个选项然后将所有bool更改为枚举的工作要少得多。

答案 2 :(得分:4)

对于房产,我可能会同意。但是,在“清洁代码”中,(正确地)表示bool在用作参数时隐藏意图。例如,格式化方法可能如下所示:

public void Format(bool pBold, bool pItalic, bool pUnderline)
{ ... }

调用时看起来像:

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)
{ ... }

然后使调用看起来像:

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);

答案 3 :(得分:2)

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

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; }
    }
}