Reputation: 18507
When reading a comment to an answer I saw the following construct to declare and initialize a variable:
int variable = int.TryParse(stringValue, out variable) ? variable : 0;
Is this allowed, correct and well defined in C#? What happens under the hood? Is the following what happens?
variable
first initialized to zero?int.TryParse
(which assigns a value)?int.TryParse
return true
)?Upvotes: 15
Views: 747
Reputation: 1658
I haven't opened Visual Studio to try this, but yes, this is allowed.
It all depends on the "stringValue" variable. If that is parsable to an integer, int.TryParse
will return true, and [variable] will have an integer value. If not, then variable
will be set to 0.
Does this make for readable code? Apparently not.
Upvotes: 2
Reputation: 7028
Yes you are right for execution. You can also look into MSIL generated here
C# Code
string stringValue = "5";
int variable = int.TryParse(stringValue, out variable) ? variable : 0;
MSIL generated
1. IL_0000: nop
2. IL_0001: ldstr "5" // load string
3. IL_0006: stloc.0
4. IL_0007: ldloc.0
5. IL_0008: ldloca.s variable
6. IL_000a: call bool [mscorlib]System.Int32::TryParse(string, int32&)
7. IL_000f: brtrue.s IL_0014
8. IL_0011: ldc.i4.0
9. IL_0012: br.s IL_0015
10. IL_0014: ldloc.1
11. IL_0015: stloc.1
12. IL_0016: ret
Which clarifies what it does behind the scene.
Statement 5 is allocating the variable onto stack. Statement 6 is calling the method. Statement 7,8,9 are actually exeuting the bool expression.
Upvotes: 10
Reputation:
int variable
declares variable
, and out variable
necessarily initializes it. Both of these things must happen before variable
is used anywhere, and because of the out
declaration, this holds true.
As pointed out by Lasse V. Carlsen, from TryParse's documentation, TryParse
will by default assign it the value of 0
if the conversion fails:
When this method returns, [
return
] contains the 32-bit signed integer value equivalent of the number contained in s, if the conversion succeeded, or zero if the conversion failed. (emph. mine)
If you expand the ternary function out, you'd see:
int variable;
if (int.TryParse(stringValue, out variable))
variable = variable;
else
variable = 0;
which is, in and of itself, a legal expression. The two paths are:
TryParse
assigns the value to variable
and returns true, leading to an assignment of variable
to itselfTryParse
initializes variable
to 0
and returns false, leading to the assignment of variable
as zero by the ternary conditionThis isn't particularly clear code, though, and I wouldn't recommend doing it.
Upvotes: 5
Reputation: 391336
This is a trick that happens to work because it is simply a rewriting of an ordinary if-statement. This code is equivalent to this:
int variable;
if (int.TryParse(stringVariable, out variable))
variable = variable;
else
variable = 0;
The sequence is as follows:
int.TryParse
is called, variable
is not initialized before this but it doesn't have to either. An out
parameter does not require a definite assigned variable. As part of the method execution, the variable
will be given a value, and int.TryParse
will return true
or false
.
If the method returns true
then the result of the expression will be variable
and thus we will execute basically variable = variable
.
If the method returns false
then the result of the expression will instead be 0
, and variable
will now be given the value 0
regardless of what it was given as part of int.TryParse
. In this case, however, this will not change the variable because int.TryParse
has already given the variable
a default value when it returns false
which also happens to be 0
.
This is basically a way to get everything onto one line.
Personally I would've written this code like this:
int variable;
int.TryParse(stringValue, out variable);
Upvotes: 8