Why if I write
void Main()
{
string value = @"C:\";
if (!string.IsNullOrEmpty(value)) {
string sDirectory = Path.GetDirectoryName(value);
}
}
it compiles.
And in case if I write
void Main()
{
string value = @"C:\";
if (!string.IsNullOrEmpty(value))
string sDirectory = Path.GetDirectoryName(value);
}
It doesn't ?
It's clear that from pure functional point of view the declaration of the variable in the second example is useless, but why it magically becomes usefull in first example, so ?
The IL code produced by both examples is exactly the same.
IL_0000: ldstr "C:\"
IL_0005: stloc.0
IL_0006: ldloc.0
IL_0007: call System.String.IsNullOrEmpty
IL_000C: brtrue.s IL_0015
IL_000E: ldloc.0
IL_000F: call System.IO.Path.GetDirectoryName
EDIT:
Forgot to mantion that to produce the IL
code for the second case (so the case which is not compilable), it's enough to compile without string sDirectory =
The production for an if
statement is in section 8.7.1 of the C# spec, and it goes like this:
if-statement:
if ( boolean-expression ) embedded-statement
if ( boolean-expression ) embedded-statement else embedded-statement
The start of section 8 of the C# spec explicitly talks about the embedded-statement production after giving the specification for it:
embedded-statement: block empty-statement expression-statement selection-statement iteration-statement jump-statement try-statement checked-statement unchecked-statement lock-statement using-statement yield-statement
The embedded-statement nonterminal is used for statements that appear within other statements. The use of embedded-statement rather than statement excludes the use of declaration statements and labeled statements in these contexts. The example
void F(bool b) { if (b) int i = 44; }
results in a compile-time error because an if statement requires an embedded-statement rather than a statement for its if branch. If this code were permitted, then the variable i would be declared, but it could never be used. Note, however, that by placing i’s declaration in a block, the example is valid.
Note that an assignment counts as an expression-statement - but a local variable declaration doesn't. (That's a declaration-statement, as in section 8.5.)
In terms of a design decision, it makes no sense to declare a variable that you can't then use - so it's good that the compiler stops you from doing it.
Your second form tries to use what is effectively two statements (a variable declaration and a variable assignment) where only a single statement could be used. Think of it as:
if (!string.IsNullOrEmpty(value))
string sDirectory;
sDirectory = Path.GetDirectoryName(value);
You can see this won't compile!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With