Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can a statement have both = and ==?

I found this other stack overflow question about files and directories, and the answer included this statement:

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

His question was about .net, and I was coding in C# .net in Visual Studio. Is the ability to have both an assignment operator and an equals operator in the same statement work for all .net languages or is it specific to certain ones? Also, can I get an explanation for how the above code works? Assuming that path refers to a directory, I'd expect isDir to be true, but can anyone explain why?

like image 557
Bradley Oesch Avatar asked May 18 '12 20:05

Bradley Oesch


People also ask

What does == mean in C++?

== is an Equal To Operator in C and C++ only, It is Binary Operator which operates on two operands. == compares value of left and side expressions, return 1 if they are equal other will it will return 0.

What is ==?

== is for value equality. It's used to know if two objects have the same value.


3 Answers

The equality test performed by the == operator takes precedence over the assignment performed by the = operator. Therefore, the isDir variable will be set equal to true if the two sides of the == operator are equal, otherwise it will be set to false. In other words, it's the equivalent of saying:

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

This is possible in VB.NET. I cannot answer for other languages. In VB.NET, the equivalent would be:

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

Since VB uses the same character (=) for both it's assignment and equality-test operators, it determines which operation you are performing based on context. The VB compiler is smart enough to know that the first = operator is an assignment and the second one is an equality test. However, this is obviously confusing, so it is often discouraged, for readability sake. It's particularly confusing to people with backgrounds in other languages. For instance, in C#, you could do the following to set two variables to the same value:

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

The reason that happens in C# is because = is always an assignment operator, and the assignment expression always evaluates to (returns) the value that was assigned. Therefore, in this case, the expression y = 5 not only assigns the value 5 to the variable y, but it also evaluates to the value of 5 as well. So, when you set x to the value of that expression, it gets set to 5 as well. In VB, however, the result is very different:

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

In VB, the compiler will assume that the expression y = 5 is an equality test, so it will evaluate to False. Therefore, it will attempt to set x = False which may or may not work depending on the value of Option Strict.

like image 92
Steven Doggart Avatar answered Oct 16 '22 06:10

Steven Doggart


Here's how the above code works. The right hand side evaluates simply to true or false, hence the equivalence (==) operator. That value is then set using the assignment (=) operator.

Another example where both operators are used (although differently) is in file IO:

while((line = streamReader.ReadLine()) != null)
{
   //do file IO
}
like image 6
kmarks2 Avatar answered Oct 16 '22 07:10

kmarks2


The rvalue is evaluated before the assignment takes place. The rvalue is an equality comparison. The result of a comparison is a boolean true or false, which can of course be assigned to a bool.

It's the same as saying

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

But is more concise.

It's not some special-case of assignment and equality in the same statement. You could do something like

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

foo becomes true if any of the flags bar, baz, or qux is true. You can evaluate any expression in an rvalue.

like image 5
sorpigal Avatar answered Oct 16 '22 07:10

sorpigal