.net 两成员枚举与布尔值
这个问题在我脑海里已经有一段时间了,如果它显得主观的话,很抱歉。在数据对象的公共属性和构造函数中使用bool有一些缺点。考虑下面的代码作为一个例子。 使用bool:.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
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)),尽管我知道这很难解决
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将更容易更改。对于一个属性,我可能会同意。不过,在“干净代码”中,(正确地)指出
bool
s在用作参数时隐藏意图。例如,格式化方法可能如下所示:
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是合适的。尽管你应该按照惯例正确命名你的房产(即“可预订”)——更好的例子是非是或非问题,比如性别或测量单位等——即使你只识别两种状态(英寸对厘米,或男性对女性),你也应该使用枚举,因为这些绝对不是“是或否”问题(即使你可以把它们变成是/否问题,但它们不是,并且可以扩展到支持更多的州)。