此 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) 可以返回一个 个标志(在不同位中),指示不同的属性。 &1s 限制为只是存在于FileAttributes.Directory 中的那些(我希望这是一个位)。碰巧,这是16,即(二进制)..0001000

如果sourceReadOnly (=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# 运算符在此代码段中如何工作?的主要内容,如果未能解决你的问题,请参考以下文章

如何自动对齐不同代码段中的注释?

BigQuery 代码段中的错误

如何使用mock对象替换内部代码段中的原始对象?

GNU 内置函数 `__builtin_unreachable ` 如何在此代码段中工作?

无法将 jinja2 变量传递到 javascript 代码段中

这段代码是如何工作的? (GDI,C#)