可空布尔作为 C# 中的三态变量
Posted
技术标签:
【中文标题】可空布尔作为 C# 中的三态变量【英文标题】:Nullable bool as tri-state variable in C# 【发布时间】:2011-07-16 11:36:10 【问题描述】:使用可为空的布尔值存储三态值有什么好处吗?例如,null == 1st state, false == 2nd state, true == 3rd state
?
开销可能比使用字节枚举要高,但我很好奇。
【问题讨论】:
在看到false == 1
的那一刻,我有点死了(没关系,问题已被编辑)
我觉得这样使用可以为空的 bool 是完全不舒服的,想想一段代码负责检查它的值并将它与枚举或常规整数进行比较
这三个状态分别代表什么? bool?
对 enum
有什么影响?
@BoltClock,经过编辑以延长全世界程序员的预期寿命:)
@k3b:可以为空的布尔类型bool?
是Nullable<bool>
的别名。
【参考方案1】:
您应该得到一份Framework Design Guidelines 的副本。
第 177 页有一章在枚举和布尔参数之间选择。
其中一个要点是:
请勿使用布尔值,除非您绝对确定永远不需要两个以上的值。【讨论】:
【参考方案2】:这是一个有点主观的问题,但我会拒绝,因为它会影响可读性。
【讨论】:
没错。它掩盖了价值背后的实际概念。【参考方案3】:在 bool 类型的末尾使用 ?
标记,这是一个包含可为空的 bool 的结构。
bool? mytristatebool = null;
【讨论】:
C# 指南:docs.microsoft.com/en-us/dotnet/csharp/language-reference/… 这非常适合我正在做的事情。感谢您的建议,我完全忘记了这一点。 gist.github.com/instance-id/ab406a366238a7088978368daf0c87d6【参考方案4】:否
我建议您选择 Enum,因为您现在已经掌握了 3 个状态,并且随着范围蔓延,它可能会进一步增加。因此,Enum 将是一个安全的赌注,并且更准确/更易读,用于描述三种状态,最重要的是第三种状态,它既不是真也不是假。
最后,它更像是为眼睛编码,他们会稍后查看此代码并使其对他们有意义和可读
【讨论】:
【参考方案5】:我认为这样做是错误的。
布尔值是一种“双态”类型。这是它的定义。
在 C#、C++、Java 或其他语言中。
如果你想模拟三种状态,只需要实现一个枚举,而不是重新发明一个方轮!
【讨论】:
SQL有什么实现?如果有点,可以是0或1。 @Matías:在 SQL 中,表达式a < b
的计算结果为 TRUE
、FALSE
或 NULL
。
“NULL”是什么情况?
@Matías:我不确定你的意思。如果a
是1
并且b
是NULL
,则表达式的计算结果为NULL
。无论如何,由于这是一个 C# 问题,我主要是在开玩笑。
好的,这就是重点。 NULL 不是布尔值。布尔值是“真”或“假”,即使如果你想做“a NULL AND a > b”。【参考方案6】:
如果它是一个 WinForms 程序,那么一种可能性是使用 System.Windows.Forms.CheckState。它具有 Checked、Indeterminate 和 Unchecked 的值 - 这可能适合也可能不适合您的目的。
【讨论】:
【参考方案7】:更简单的解决方法是使用两个布尔变量。 一个人会保持 null/not-null 另一个将保持真/假
一个应用:
当您在布尔属性中缓存计算时,您需要知道它是否已经设置。
例如
// actual variable having true/false
private bool isX = false;
// variable holding wither above is set/not-set i.e. null/not-null
private bool isXSet = false;
public bool IsX
get
if (isXSet)
return isX;
else
isX = GetX(); // this could be time consuming.
isXSet = true;
return isX;
当上面的 GetX() 耗时且 IsX 被多次访问时,这在性能调整中非常有用。
【讨论】:
【参考方案8】:对于未知或尚未确定,我会坚持 null。您也失去了对值进行数学运算的可能性。总而言之,我认为不是一个好主意
【讨论】:
【参考方案9】:这取决于。非常适合像“Has Dog”这样的属性:真假,或者我们只是不知道。
【讨论】:
经验告诉我宁愿有一个枚举:HasDog、NoDog、未指定。 NULL 始终是一个问号。我们是否缺少数据,或者他们是否填写了未指定?并且不可避免地需要Has2Dogs
或HasCat
。
是的,但 OP 的问题是关于三态,而不是四态等。
你是 OP :-)【参考方案10】:
我明白为什么人们建议不要使用它来表示选项 A、B 和 C。我也会为此使用枚举。
但是布尔值?非常适合表示可能尚未获取或生成的实际布尔值。不,有一个单独的 bool 来获取并不简单,它更混乱。恕我直言
现在如果只有 C# 允许使用局部静态变量,那么我们就可以让它完全自包含,就像这样:
bool isSomething
get
static bool? _isSomething = null;
if (null == _isSomething)
_isSomething = goFetchIsSomething();
return _isSomething == true;
但是由于纯粹主义者讨厌可读的代码,你能做的最好的就是这个
private bool? _isSomething = null; //Pretty please don't try to use me outside of isSomething
bool isSomething
get
if (null == this._isSomething)
this._isSomething = goFetchIsSomething();
return this._isSomething == true;
【讨论】:
以上是关于可空布尔作为 C# 中的三态变量的主要内容,如果未能解决你的问题,请参考以下文章