【问题标题】:How does this C# operator work in this code snippet?此 C# 运算符在此代码段中如何工作?
【发布时间】:2011-06-12 02:20:37
【问题描述】:

我在 SO 上找到了这个代码 sn-p(抱歉,我没有问题/答案组合的链接)

 bool isDir = (File.GetAttributes(source) & FileAttributes.Directory) == FileAttributes.Directory;

这让我很困惑,因为FileAttributes.Directory== 的两侧。

& 在这种情况下会做什么?我不确定如何阅读这行代码。我正在尝试评估路径字符串是文件还是目录。

【问题讨论】:

    标签: c# syntax operators bit-manipulation bitwise-operators


    【解决方案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 非常适合快速轻松地响应标志中所需的位是打开还是关闭,而无需了解位值或一般二进制。

                    【讨论】:

                      猜你喜欢
                      • 1970-01-01
                      • 2021-11-29
                      • 1970-01-01
                      • 2020-12-18
                      • 1970-01-01
                      • 1970-01-01
                      • 2019-11-11
                      • 1970-01-01
                      • 2019-01-24
                      相关资源
                      最近更新 更多