Reputation: 3563
I have declared a variable as underscore character _
like below and the compiler able to execute the code smoothly.
int _ = 10;
_ += 10;
onsole.WriteLine(_);
But, the compiler is not detecting the variable named as underscore character _
for a Deconstruction syntax shown below.
(string _, int age) = new Student("Vimal", "Heaven", 20);
At the same time, compiler and Visual Studio intellisense detect the variable named as underscore _
for another syntax shown below.
var student = new Student("Vimal", "Heaven", 20);
(string _, int age) details = student.GetDetails();
Console.WriteLine(details._);
I understand that nobody use underscore character to name a variable. Why compiler is inconsistent in handling the underscore _
character?
I am not discussing about the C# discards
here.
The Student
class referred in the sample.
public class Student
{
public string Name { get; set; }
public string Address { get; set; }
public int Age { get; set; }
public Student(string name, string address, int age = 0) => (Name, Address, Age) = (name, address, age);
public void Deconstruct(out string name, out int age) => (name, age) = (Name, Age);
public (string, int) GetDetails() => (Name, Age);
}
Upvotes: 4
Views: 620
Reputation: 273510
Why compiler is inconsistent in handling the underscore _ character?
In each of the first three code snippets, the _
character is interpreted a different way.
Here:
(string _, int age) details = student.GetDetails();
(string _, int age)
is syntactically the type of the variable details
, and the variable name is details
, not _
. _
is part of the type name, specifically the tuple field name.
From the docs (emphasis mine):
You indicate that a variable is a discard by assigning it the underscore (_) as its name.
So the _
in (string _, int age) details
is not a discard. This is why you can access it as details._
.
Later in the same page:
In C# 7.0, discards are supported in assignments in the following contexts:
- Tuple and object deconstruction.
- Pattern matching with is and switch.
- Calls to methods with out parameters.
- A standalone _ when no _ is in scope.
The situation you have here:
int _ = 10;
_ += 10;
Console.WriteLine(_);
is not on the list, so discards do not apply there. In the first line, It is not "A standalone _
", so _
is not a discard, and you declared a variable called _
. In the following lines, there is a _
in scope, because you declared a variable with that name on the first line.
The second code snippet you showed:
(string _, int age) = new Student("Vimal", "Heaven", 20);
is a "Tuple and object deconstruction", which is on the list, so this time _
is treated as a discard, and this time it doesn't declare a variable called _
.
Upvotes: 5