Reputation: 1914
I stumbled across this while starting to learn about vars here:
http://msdn.microsoft.com/en-us/library/bb384061.aspx
However, I have no idea how that is a legal expression (it is). I thought you couldn't assign to something using an a = (b=c) because (b=c) does not produce a value to assign?
Thanks for any clarification on the matter.
Upvotes: 29
Views: 2464
Reputation: 419
The assignment operator returns the value assigned.
Thus,
i = 20
returns 20
which gets assigned to i.
So,
i = (i = 20);
is as good as
i = 20;
Upvotes: 0
Reputation: 4893
While it means the same as i = 20
, it might have a useful purpose in certain situations.
If someone else will maintain your code, and sees something like this:
if ( i = some_function() )
they might think it is a mistake and relpace =
with ==
.
To signal that this is what you intended to do, you can use
if ( i = (i = some_function()) )
However, I personally find if ( i = /* = */ some_function() )
or just i = some_function(); if (i)
to be cleaner.
Upvotes: 1
Reputation: 17447
It is legal in C# because the order of evaluation for operators is left to right by default,unlike C/C++ languages that don't define a limit in sequence point.. The =
operator assign the value to 20 and returns the value as result. It's parsed as:
int i; //<- i is declared.
i = 20; // assign 20 to i variable and returns.
i = i; // assign i as i value of.
It's an ambiguous expression
Upvotes: 2
Reputation: 120
You can do same approach, on how to declare a variable.. it just the one you read make it complicated to read.
It is exists because it can be used to obfuscate code in my opinion its presence had a deep connection to security..
Upvotes: 0
Reputation: 4965
The code is non-thread safe way to assign the literal value 20 to a local variable i.
The expression i = 20
has the side affect of assigning 20 to i
, and has the value of i
after the assignment. The expression i = (i = 20)
assigns i the values of (i = 20)
, which is almost always just the value that i
has at the time of the outer assignment. If the thread is interrupted, the expression (i = 20) will still have the value 20, although i may have a different value at the point the outer assignment takes place.
There is no situation in which you would want to write this exact code.
Upvotes: 2
Reputation: 77606
This particular code is pointless. The assignment expression returns the value that was just assigned. Therefore, the result of:
i = 20
Is, of course, 20
. Thus:
i = (i = 20);
Is the same as:
i = 20;
Occasionally the fact that an assignment returns something can be useful, such as in for loops:
for (string line; (line = reader.ReadLine()) != null;) { ... }
(For what it's worth, I wouldn't use this idiom in this particular situation)
Or assigning the same value to multiple variables:
int x, y;
x = y = 5;
Now, both x
and y
have the value 5
.
Upvotes: 4
Reputation: 20576
Even the following is valid too in C++ and C# both:
int i = i = i = 20;
The statement above is a simple use of assignment operator assigning valves from right to left operand.
Upvotes: 0
Reputation:
The whole quote from MSDN is:
Variables declared by using var cannot be used in the initialization expression. In other words, this expression is legal: int i = (i = 20); but this expression produces a compile-time error: var i = (i = 20);
The point is that you can't use variables declared by var in the initialization expression. In other words, if you use var to declare i, then you can't use i on the other side of the = sign.
As others have noted, you would not actually write this code. This is a contrived example.
Upvotes: 14
Reputation: 6850
It is legal. From the = operator C# reference page:
The assignment operator (=) stores the value of its right-hand operand in the storage location, property, or indexer denoted by its left-hand operand and returns the value as its result.
(emphasis mine)
The code in the example is contrived (and pointless), but it can be used in other cases to do useful things in a more concise way. For example:
BinaryTree tree;
TreeNode node;
if((node = tree.FindNodeForKey(10)) != null)
{
// do useful things with returned node
}
Upvotes: 31
Reputation: 11955
I use that kind of thing all the time.
public class Parameters
{
public readonly bool ContainsSquareBrackets;
public Parameters(string paras)
{
if(ContainsSquareBrackets = paras.Contains(']') || paras.Contains('['))
{
// do something ...
}
}
}
Upvotes: 6