6

我发现了关于文件和目录的另一个堆栈溢出问题,答案包括以下语句:

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

他的问题是关于 .net 的,而我在 Visual Studio 中使用 C# .net 进行编码。在同一语句中同时使用赋值运算符和等于运算符的能力是否适用于所有 .net 语言,还是特定于某些语言?另外,我能解释一下上面的代码是如何工作的吗?假设它path指的是一个目录,我希望isDir这是真的,但谁能解释为什么?

4

6 回答 6

13

运算符执行的相等性测试==优先于运算符执行的赋值=。因此,如果运算符的两侧相等,则将isDir变量设置为等于,否则将设置为。换句话说,这相当于说:true==false

if ((File.GetAttributes(path) & FileAttributes.Directory) == FileAttributes.Directory)
    isDir = true;
else
    isDir = false;

这在 VB.NET 中是可能的。我无法回答其他语言。在 VB.NET 中,等价于:

Dim isDir As Boolean = ((File.GetAttributes(path) And FileAttributes.Directory) = FileAttributes.Directory)

由于 VB=对其赋值和相等测试运算符使用相同的字符 ( ),因此它会根据上下文确定您正在执行的操作。VB 编译器足够聪明,知道第一个=运算符是赋值,第二个是相等测试。然而,这显然是令人困惑的,因此为了便于阅读,通常不鼓励这样做。对于具有其他语言背景的人来说,这尤其令人困惑。例如,在 C# 中,您可以执行以下操作将两个变量设置为相同的值:

int y;
int x = y = 5;  // Both x and y will be set to 5

在 C# 中发生的原因是因为=始终是赋值运算符,并且赋值表达式总是计算(返回)分配的值。因此,在这种情况下,表达式y = 5不仅将值 5 赋给变量y,而且它的计算结果也为 5。因此,当您设置x为该表达式的值时,它也会设置为 5。然而,在 VB 中,结果却大不相同:

Dim y As Integer
Dim x As Integer = y = 5

在 VB 中,编译器将假定表达式y = 5是一个相等测试,因此它的计算结果为False. 因此,它将尝试x = False根据Option Strict.

于 2012-05-18T20:37:10.510 回答
6

以下是上述代码的工作原理。右手边只计算真或假,因此是等价 (==) 运算符。然后使用赋值 (=) 运算符设置该值。

另一个同时使用两个运算符(虽然不同)的例子是在文件 IO 中:

while((line = streamReader.ReadLine()) != null)
{
   //do file IO
}
于 2012-05-18T20:37:11.767 回答
5

在赋值发生之前评估右值。右值是一个相等比较。比较的结果是布尔值 true 或 false,当然可以将其分配给布尔值。

这和说的一样

if((File.GetAttributes(path) & FileAttributes.Directory)
             == FileAttributes.Directory)
{
    isDir = true;
}
else
{
    isDir = false;
}

但是更简洁。

这不是同一语句中赋值和相等的一些特殊情况。你可以做类似的事情

bool bar, baz, qux;
bar = qux = false;
baz = true;
bool foo = (bar || baz || qux); // foo is true

foo如果任何标志barbazqux为真,则变为真。您可以评估右值中的任何表达式。

于 2012-05-18T20:37:59.143 回答
3

=是一个赋值运算符,它设置 isDir 的值

==是一个比较运算符,正在检查两边的值是否相等

于 2012-05-18T20:37:17.760 回答
2

==是在 C# 中返回布尔值的运算符。isDir正在分配该运算符的结果。这不仅限于 C#,但不一定适用于所有 .net 语言(例如,据我所知,VB .net 仍然使用单等号进行相等测试)。

于 2012-05-18T20:37:06.400 回答
1

此语句正在获取文件路径的属性(其中是标志枚举)与目录的枚举值相结合(这实际上将枚举的所有位擦除为 0,除了表示的位FileAttributes.Directory。然后比较结果该操作以查看它是否实际上等于表示 的枚举值FileAttributes.Directory。然后将该操作的结果存储在 isDir 变量中。

这段代码相当于:

FileAttributes pathAttributes = File.GetAttributes(path);
FileAttributes checkForDirectory = pathAttributes & File.GetAttributes(path);
bool isDir = checkForDirectory == FileAttributes.Directory;

有关标志枚举如何工作(即 FileAttributes 是什么)的更多信息,请参阅: 枚举

于 2012-05-18T20:41:19.080 回答