One of the handiest new features in C# 6 is nameof
, which allows the programmer to effectively eliminate the use of magic strings.
Per the documentation, nameof
returns a string:
Used to obtain the simple (unqualified) string name of a variable, type, or member.
That works just fine with explicit typing in the following code example:
string magicString = nameof(magicString);
However, when using implicit typing with the var
keyword:
var magicString = nameof(magicString);
the compiler throws an error:
Cannot use local variable 'magicString' before it is declared
I then did some more experimenting with the C# Interactive window available in Visual Studio. Again, the first example worked fine, but the second example threw a different error this time:
error CS7019: Type of 'magicString' cannot be inferred since its initializer directly or indirectly refers to the definition.
The nameof
expression clearly returns a string, so why can't the compiler implicitly type it when being used with the initialized variable?
Implicit type conversion in C language is the conversion of one data type into another datatype by the compiler during the execution of the program. It is also called automatic type conversion.
Implicit Type Conversion is also known as 'automatic type conversion'. It is done by the compiler on its own, without any external trigger from the user. It generally takes place when in an expression more than one data type is present.
The EXPLICIT keyword is optional; by default, the CREATE CAST statement creates an explicit cast. An implicit cast is a cast that the database server can invoke automatically when it encounters data types that cannot be compared with built-in casts.
Also known as 'automatic type conversion'. Done by the compiler on its own, without any external trigger from the user. Generally takes place when in an expression more than one data type is present. In such condition type conversion (type promotion) takes place to avoid loss of data.
The language team felt that this wasn't worth the spec complexity.
You can see the discussion here.
The underlying reason for this behavior is that the spec says (§8.5.1) names declared with var
aren't visible in the declaring statement, since before nameof
, there was no way in which that could be valid.
Implicitly typed local variable declarations are subject to the following restrictions:
- ...
- The initializer expression cannot refer to the declared variable itself
Without var
, statements like int x = x = 1;
or int x = 1, y = x;
are legal; with var
, nothing in that form is valid.
The ability to declare a variable and assign it in the same statement is syntactic sugar. For example, when you say this:
string magicString = nameof(magicString);
what you're really saying is this:
string magicString; magicString = nameof(magicString);
Since magicString
is already declared, you can use it in the next logical statement as part of the naemof
operator. This is because magicString
is now part of the scope that is visible to subsequent statements.
Now, the above doesn't hold true when you use var
because anything that uses var
to make an assignment is really all part of just one statement, not syntactic sugar for two statements like the above example. The variable magicString
doesn't actually get declared until after your function call / operator / assignment, so therefore the variable is not part of the scope until it has done the assignment, i.e. in the next statement(s).
SLaks referred to the original discussion about this issue, but what is pointed out in the notes from this later C# design team meeting about this issue on the question of "Should var x = nameof(x) work?":
This works the same as with any other construct, i.e.: not. This is not a special case for nameof, and it doesn't seem worth special casing to allow it.
In other words, it's not specific to nameof
.
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