声明如何同时具有=和==?

Bra*_*sch 6 .net c# operators visual-studio-2010

我发现这个关于文件和目录的其他堆栈溢出问题,答案包括这个声明:

bool isDir = (File.GetAttributes(path) & FileAttributes.Directory)
             == FileAttributes.Directory;
Run Code Online (Sandbox Code Playgroud)

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

Ste*_*art 13

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

if ((File.GetAttributes(path) & FileAttributes.Directory) == FileAttributes.Directory)
    isDir = true;
else
    isDir = false;
Run Code Online (Sandbox Code Playgroud)

这在VB.NET中是可行的.我无法回答其他语言.在VB.NET中,等效的是:

Dim isDir As Boolean = ((File.GetAttributes(path) And FileAttributes.Directory) = FileAttributes.Directory)
Run Code Online (Sandbox Code Playgroud)

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

int y;
int x = y = 5;  // Both x and y will be set to 5
Run Code Online (Sandbox Code Playgroud)

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

Dim y As Integer
Dim x As Integer = y = 5
Run Code Online (Sandbox Code Playgroud)

在VB中,编译器将假定表达式y = 5是一个相等测试,因此它将评估为False.因此,它将尝试x = False根据值来设置哪些可能有效或无效Option Strict.


kma*_*ks2 6

以下是上述代码的工作原理.右侧简单地评估为true或false,因此等价(=​​=)运算符.然后使用赋值(=)运算符设置该值.

使用两个运算符的另一个示例(尽管不同)在文件IO中:

while((line = streamReader.ReadLine()) != null)
{
   //do file IO
}
Run Code Online (Sandbox Code Playgroud)


Sor*_*gal 5

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

这跟说的一样

if((File.GetAttributes(path) & FileAttributes.Directory)
             == FileAttributes.Directory)
{
    isDir = true;
}
else
{
    isDir = false;
}
Run Code Online (Sandbox Code Playgroud)

但更简洁.

在同一语句中,并不是一些特殊情况下的赋值和相等.你可以做点什么

bool bar, baz, qux;
bar = qux = false;
baz = true;
bool foo = (bar || baz || qux); // foo is true
Run Code Online (Sandbox Code Playgroud)

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