此 C# 运算符在此代码段中如何工作?
Posted
技术标签:
【中文标题】此 C# 运算符在此代码段中如何工作?【英文标题】:How does this C# operator work in this code snippet? 【发布时间】:2011-06-12 02:20:37 【问题描述】:我在 SO 上找到了这个代码 sn-p(抱歉,我没有问题/答案组合的链接)
bool isDir = (File.GetAttributes(source) & FileAttributes.Directory) == FileAttributes.Directory;
这让我很困惑,因为FileAttributes.Directory
在==
的两侧。
&
在这种情况下会做什么?我不确定如何阅读这行代码。我正在尝试评估路径字符串是文件还是目录。
【问题讨论】:
【参考方案1】:它使用位掩码来测试是否设置了单个位(FileAttributes.Directory)。
枚举的值是 2 的幂,对应于各个位。
ReadOnly = 1,
Hidden = 2,
System = 4,
Directory = 16,
Archive = 32,
Device = 64,
如果设置了 ReadOnly 和 Directory,则 FileAttributes 等于 17。二进制计算如下所示:
File.GetAttributes(source) = 00001001
FileAttributes.Directory = 00001000 &
-------------------------------------
00001000
如果目录位没有设置你会得到零:
File.GetAttributes(source) = 00000001
FileAttributes.Directory = 00001000 &
-------------------------------------
00000000
编写给出相同效果的表达式的更简洁的方法是针对零进行测试:
bool isDir = (File.GetAttributes(source) & FileAttributes.Directory) != 0;
【讨论】:
我不确定 C++ 如何处理布尔值,但 ANSI C 也允许稍短一些:bool isDir = (File.GetAttributes(source) & FileAttributes.Directory);【参考方案2】:它执行按位与运算。属性存储为位标志,因此将这些标志与 AttributeFlags.Directory 一起使用以查看属性之一是否为 .Directory。
这里是位标志的好例子: http://weblogs.asp.net/wim/archive/2004/04/07/109095.aspx
[Flags]
public enum FileAttributes
Archive, // 0000
Compressed, // 0001
Device, // 0010
Directory, // 0100
Encrypted, // 1000
...
然后:
File.GetAttributes(source): 1101
FileAttributes.Directory: 0100
(Logical AND): 0100
0100 与目录标志相同,因此我们现在知道该标志在枚举的选定标志中。
【讨论】:
【参考方案3】:它是logical & operator。在这个特定示例中,它检查 FileAttributes 枚举是否具有 Directory 值,验证 source
变量指向的字符串是否是目录。
【讨论】:
【参考方案4】:单个 & 是位运算符。 http://msdn.microsoft.com/en-us/library/sbf85k1c(v=VS.100).aspx
它对两个值的各个位执行按位与。它在位掩码中被大量使用。
【讨论】:
【参考方案5】:&
在这种情况下是按位的and
运算符。
【讨论】:
【参考方案6】:它正在执行按位标志测试 - File.GetAttributes(source)
可以返回一个 个标志(在不同位中),指示不同的属性。 &
将1
s 限制为只是存在于FileAttributes.Directory
中的那些(我希望这是一个位)。碰巧,这是16
,即(二进制)..0001000
如果source
有ReadOnly
(=1)、Hidden
(=2) 和Directory
(=16),它将是:
...0001011
我们和 16 人
...0001000
离开
...0001000
因此目录测试通过。
如果源具有 System
(=4) 和 ReadOnly
(=1)(而不是目录),它将是:
...0000101
我们和 16 人
...0001000
离开
...0000000
因此目录测试失败。
作为旁注;在这样的测试中,==
验证是否设置了 all 所需的标志(如果第二个操作数中有多个位)。另一个常见的测试是!= 0
,它测试是否存在任何位。
【讨论】:
【参考方案7】:是位运算符 AND。http://en.wikipedia.org/wiki/Bitwise_operation
codesn-p 在两个变量之间执行按位与,然后将值与另一个变量进行比较,将结果放入 bool。
【讨论】:
【参考方案8】:它是按位AND
操作。 FileAttributes
是标志枚举。这意味着这个枚举的数值中的每一位都描述了这个文件的一些布尔属性,它们可以组合起来。
【讨论】:
【参考方案9】:它正在测试FileAttributes.Directory
标志是否设置在File.GetAttributes
返回的枚举中。您可以在this entry on MSDN 中阅读有关如何使用标志枚举的更多信息。
我正在尝试评估路径字符串是文件还是目录。
我宁愿使用 System.IO 中的一种方法,比如Directory.Exists
:
if (Directory.Exists(path))
// it's a directory
else if (File.Exists(path))
// it's a file
else
// doesn't exist
【讨论】:
【参考方案10】:GetAttributes 返回一个标志值,其中每个位代表不同的布尔状态。除了 GetAttributes 返回的任何其他标志之外,此代码使用按位 & 运算符打开 Directory 标志。
这似乎过于复杂了。这相当于写:
bool isDir = File.GetAttributes(source).HasFlag(FileAttributes.Directory);
或者,专门测试目录属性:
bool isDir = File.GetAttributes(source) == FileAttributes.Directory;
HasFlag() 方法目前有点慢,所以按位替代更快并且使用更少的资源。 HasFlag 非常适合快速轻松地响应标志中所需的位是打开还是关闭,而无需了解位值或一般二进制。
【讨论】:
以上是关于此 C# 运算符在此代码段中如何工作?的主要内容,如果未能解决你的问题,请参考以下文章
GNU 内置函数 `__builtin_unreachable ` 如何在此代码段中工作?