if((attributes & FileAttributes.Hidden) == FileAttributes.Hidden) { } 是如何工作的?
How does if((attributes & FileAttributes.Hidden) == FileAttributes.Hidden) { } work?
在 this 页面上,我看到以下代码:
if ((attributes & FileAttributes.Hidden) == FileAttributes.Hidden)
但是我不明白为什么会这样。
为什么attributes & FileAttributes.Hidden)
? attributes
上的单数检查实际上做了什么?它是否检查它是否不为空?我有一种感觉,我知道,但它看起来很奇怪。随机和奇怪。
这是简单的布尔逻辑。如果双方具有完全相同的值,则 ==
运算符仅 returns true
。因此,您必须 mask attributes
值与您要比较的标志。考虑这两个例子(值是组成的):
正确:
0010001 // attributes
& 0000001 // FileAttributes.Hidden
-------
= 0000001 // FileAttributes.Hidden
错误:
0011000 // attributes
& 0000001 // FileAttributes.Hidden
-------
= 0000000 // FileAttributes.None
& 是按位与运算符。
此运算符仅对 2 组位执行按位与运算。
0 & 0 === 0
1 & 0 === 0
0 & 1 === 0
1 & 1 === 1
在 and 运算符旁边,还有一个 OR (|) 和 XOR(异或)(^) 运算符。
attributes
是 FileAttributes
类型。此类型是 enum
,一种值类型。它不是 FileAttributes?
(Nullable<FileAttributes>
),所以它 不能为 null。
每个 enum
都包含一个命名值列表,但每个值都是 mappable/convertible 一些整数 (int) 值。在许多地方,C# 允许您 "exploit" 该转换并(在某种程度上)将枚举值视为整数,但它们仍然不是。
例如,& 运算符执行您所期望的 - 它执行二进制 AND。这样,如果转换为整数的枚举值设置了相关位,您将得到一些非零结果。
在检查 flags/bits 是否存在于某些状态值的 "good old way" 中。您可能经常看到像 foo & FLAG != 0
这样的表达式,它检查标志是否已设置,或 foo & (FLAG|BLAG) != 0
检查这两个中的任何一个是否被设置。这有点 flawed/dangerous 因为如果有人将 FLAG 更改为不止一位,那么这样的表达式将检查是否设置了任何位,而不是检查整个 "multi-bit flag" 是否已设置。这就是为什么您可能还经常看到 foo & FLAG == FLAG
应用位掩码并检查结果是否是位掩码,因此它检查是否设置了掩码的所有位。
在这里,你的情况就是这样。由于在该表达式中您使用相同的掩码进行 ANDing 和 COMPARING,因此您实际上是在检查是否设置了掩码的所有位。但这是多余的,因为 FileAttributes 明确标记为 [Flags],Hidden
值只有一位,所以 != 0 就足够了。
然而,在这种情况下(检查标志,而不是花哨的按位掩码)你可以尝试使用 Enum.HasFlag 方法,大多数人会建议你使用它,因为它是为这种情况设计的;)
但这并不总是最佳选择。请看:
- http://www.codeproject.com/Tips/441086/NETs-Enum-HasFlag-and-performance-costs
- http://www.dotnetbitsandpieces.com/?p=11
..但如果性能成本对您来说是个问题,我会感到惊讶。很少需要优化到这一点。
在 this 页面上,我看到以下代码:
if ((attributes & FileAttributes.Hidden) == FileAttributes.Hidden)
但是我不明白为什么会这样。
为什么attributes & FileAttributes.Hidden)
? attributes
上的单数检查实际上做了什么?它是否检查它是否不为空?我有一种感觉,我知道,但它看起来很奇怪。随机和奇怪。
这是简单的布尔逻辑。如果双方具有完全相同的值,则 ==
运算符仅 returns true
。因此,您必须 mask attributes
值与您要比较的标志。考虑这两个例子(值是组成的):
正确:
0010001 // attributes
& 0000001 // FileAttributes.Hidden
-------
= 0000001 // FileAttributes.Hidden
错误:
0011000 // attributes
& 0000001 // FileAttributes.Hidden
-------
= 0000000 // FileAttributes.None
& 是按位与运算符。
此运算符仅对 2 组位执行按位与运算。
0 & 0 === 0
1 & 0 === 0
0 & 1 === 0
1 & 1 === 1
在 and 运算符旁边,还有一个 OR (|) 和 XOR(异或)(^) 运算符。
attributes
是 FileAttributes
类型。此类型是 enum
,一种值类型。它不是 FileAttributes?
(Nullable<FileAttributes>
),所以它 不能为 null。
每个 enum
都包含一个命名值列表,但每个值都是 mappable/convertible 一些整数 (int) 值。在许多地方,C# 允许您 "exploit" 该转换并(在某种程度上)将枚举值视为整数,但它们仍然不是。
例如,& 运算符执行您所期望的 - 它执行二进制 AND。这样,如果转换为整数的枚举值设置了相关位,您将得到一些非零结果。
在检查 flags/bits 是否存在于某些状态值的 "good old way" 中。您可能经常看到像 foo & FLAG != 0
这样的表达式,它检查标志是否已设置,或 foo & (FLAG|BLAG) != 0
检查这两个中的任何一个是否被设置。这有点 flawed/dangerous 因为如果有人将 FLAG 更改为不止一位,那么这样的表达式将检查是否设置了任何位,而不是检查整个 "multi-bit flag" 是否已设置。这就是为什么您可能还经常看到 foo & FLAG == FLAG
应用位掩码并检查结果是否是位掩码,因此它检查是否设置了掩码的所有位。
在这里,你的情况就是这样。由于在该表达式中您使用相同的掩码进行 ANDing 和 COMPARING,因此您实际上是在检查是否设置了掩码的所有位。但这是多余的,因为 FileAttributes 明确标记为 [Flags],Hidden
值只有一位,所以 != 0 就足够了。
然而,在这种情况下(检查标志,而不是花哨的按位掩码)你可以尝试使用 Enum.HasFlag 方法,大多数人会建议你使用它,因为它是为这种情况设计的;)
但这并不总是最佳选择。请看:
- http://www.codeproject.com/Tips/441086/NETs-Enum-HasFlag-and-performance-costs
- http://www.dotnetbitsandpieces.com/?p=11
..但如果性能成本对您来说是个问题,我会感到惊讶。很少需要优化到这一点。