这绝对是主观的,但我想尽量避免它变成争论。我认为如果人们恰当地对待它,这将是一个有趣的问题。

这个问题的想法来自于我对“你最讨厌的语言的哪五件事?”问题的回答。我认为c#中的类在默认情况下应该是密封的——我不会把我的理由放在这个问题上,但我可能会写一个更完整的解释来回答这个问题。我对评论中的讨论热度感到惊讶(目前有25条评论)。

那么,你有什么有争议的观点?我宁愿避免那些基于相对较少的基础而导致相当宗教的事情(例如,大括号放置),但例如可能包括“单元测试实际上并没有多大帮助”或“公共字段确实是可以的”之类的事情。重要的是(至少对我来说)你的观点背后是有理由的。

请提出你的观点和理由——我鼓励人们投票给那些有充分论证和有趣的观点,不管你是否恰好同意这些观点。


当前回答

布尔变量只能用于布尔逻辑。在所有其他情况下,使用枚举。


布尔变量用于存储只能有两个可能值的数据。使用它们所产生的问题经常被忽视:

程序员通常不能正确地识别某些数据何时应该只有两个可能的值 指导程序员做什么的人,比如程序经理或编写程序员遵循的规范的人,通常也不能正确地识别这一点 即使一段数据被正确地识别为只有两种可能的状态,这种保证在将来也可能不成立。

在这些情况下,使用布尔变量会导致令人困惑的代码,这通常可以通过使用枚举来避免。

例子

假设一个程序员正在为一家只销售轿车和卡车的汽车经销商编写软件。程序员为他的软件开发一个全面的业务需求模型。由于知道所销售的车辆只有轿车和卡车两种类型,他正确地识别出可以在Vehicle类中使用一个布尔变量来指示车辆是轿车还是卡车。

class Vehicle {
 bool isTruck;
 ...
}

这个软件是这样写的,当isTruck为真时,车辆是一辆卡车,当isTruck为假时,车辆是一辆汽车。这是在整个代码中执行多次的简单检查。

一切都很顺利,直到有一天,汽车经销商收购了另一家同样销售摩托车的经销商。程序员必须更新软件,使其能够正确地考虑到经销商的业务发生了变化。现在它需要识别车辆是汽车、卡车还是摩托车,这是三种可能的状态。

程序员应该如何实现这一点?isTruck是一个布尔变量,所以它只能保存两种状态。他可以将其从布尔类型更改为允许多种状态的其他类型,但这将破坏现有的逻辑,并且可能无法向后兼容。从程序员的角度来看,最简单的解决方案是添加一个新变量来表示车辆是否是摩托车。

class Vehicle {
 bool isTruck;
 bool isMotorcycle;
 ...
}

代码更改后,当isTruck为真时,车辆为卡车,当isMotorcycle为真时,车辆为摩托车,当两者都为假时,车辆为汽车。

问题

这种解决方案存在两个大问题:

The programmer wants to express the type of the vehicle, which is one idea, but the solution uses two variables to do so. Someone unfamiliar with the code will have a harder time understanding the semantics of these variables than if the programmer had used just one variable that specifies the type entirely. Solving this motorcycle problem by adding a new boolean doesn't make it any easier for the programmer to deal with such situations that happen in the future. If the dealership starts selling buses, the programmer will have to repeat all these steps over again by adding yet another boolean.

软件的业务需求发生变化,要求他修改现有代码,这不是开发人员的错。但是首先使用布尔变量使得他的代码不那么灵活,也更难修改以满足未知的未来需求(不那么“适合未来”)。当他以最快的方式实现更改时,代码变得难以阅读。使用布尔变量最终是一个不成熟的优化。

解决方案

首先使用枚举就可以避免这些问题。

enum EVehicleType { Truck, Car }

class Vehicle {
 EVehicleType type;
 ...
}

为了在这种情况下容纳摩托车,程序员所要做的就是将Motorcycle添加到evhicletype中,并添加新的逻辑来处理摩托车的情况。不需要添加新的变量。现有的逻辑不应该被打乱。不熟悉代码的人也很容易理解车辆的类型是如何存储的。

悬崖笔记

不要使用只能存储两种不同状态的类型,除非您绝对确定两种状态总是足够的。如果将来可能需要两个以上的状态,则使用枚举,即使布尔值可以满足现有需求。

其他回答

匿名函数很糟糕。

我正在自学jQuery,虽然它是一种优雅且非常有用的技术,但大多数人似乎都将其视为最大化匿名函数用户的某种竞争。

函数和过程命名(以及变量命名)是我们在编程中所拥有的最强大的表达能力。将函数作为数据传递是一项伟大的技术,但使它们匿名并因此非自文档化是一个错误。这样就失去了表达代码含义的机会。

全局变量和/或单例变量本身并不邪恶

我来自更多的系统管理员,shell, Perl(和我的“真正的”编程),PHP类型的背景;去年我被派去做Java开发工作。

单身是邪恶的。全球人太邪恶了,他们甚至不被允许。然而,Java有像AOP这样的东西,现在还有各种“依赖注入”框架(我们使用谷歌Guice)。AOP就不是这样了,但是DI的东西肯定会给你什么?全局变量。啊,谢谢。

应该禁止调试器。这将迫使人们编写可通过单元测试测试的代码,最终将导致更好的代码质量。

从所有编程ide中删除复制和粘贴。复制和粘贴代码是非常糟糕的,这个选项应该完全删除。然后程序员可能会懒得重新输入所有的代码,所以他会创建一个函数并重用代码。

无论何时使用单例,都要给自己一个耳光。单例几乎从来没有必要,大多数时候只是全局变量的花哨名称。

通过断章取义地编写伟大的程序,以狂热者的热情和错误的假设,这些都是铁定的规则,这真的让我很恼火。例如,“过早的优化是万恶之源”。

在我看来,许多技术问题和解决方案都是非常上下文敏感的,全球最佳实践的概念是一个谬论。

我坚信非托管代码不值得这么麻烦。与查找内存泄漏相关的额外维护性开销(即使是最好的程序员偶尔也会引入这种开销)远远超过从c++这样的语言获得的性能。如果Java, c#等不能得到你需要的性能,买更多的机器。