out var _ and out _ difference? [duplicate]
Asked Answered
F

2

6

In C# 7 we can do like this:

byte.TryParse(p.Value, out _)

or like this

byte.TryParse(p.Value, out var _)

Are there any differences?

Fawnfawna answered 15/2, 2018 at 6:20 Comment(12)
Yes there's a difference. Have you written the same piece of code using both, and actually got it to compile?Schiff
In first syntax you will have to declare _ separately before calling this, in second syntax it will be declared as well.Cubic
@FaizanRabbani: It's not necessary to pre-initialize a variable used as an out parameter, although ref parameters do have to be definitely assigned prior to the call.Schiff
Seconds before I posted an answer.... What's new in c# 7.0 covers it.Kimikokimitri
@BenVoigt thanks, correcting my comment, declare only.Cubic
@BenVoigt, I disagree that this one is a duplicate (at least not of the one that it's marked to be a dupe of), _ are ommitted out parameters as of C# 7.Unmusical
@BenVoigt I don't see how duplicate answers this question. So, what's the difference here?Whey
I agree with Paul.Bresee
_ is for discards, this has a good answer, #42921122Bresee
@JaliyaUdagedara Yes, but this one is still different, since it explicitly asks about the difference between out _ and out var _ (spoiler: there is none)Unmusical
@JaliyaUdagedara Alright, it's covered in the accepted answer, but still: The scope of the question is different.Unmusical
@Enigmativity Sometimes out parameters are not needed. As of version 7, C# supports an out parameter that is a "throw-away" parameter, _. It will not (and cannot) be used. This is a good thing to tell your reader that the parameter is not used.Unmusical
U
5

As opposed to what others in their comments said: No, there are no differences. They both produce the exact same IL.

Both

byte.TryParse(p.Value, out _);
Console.WriteLine(_);

and

byte.TryParse(p.Value, out var _);
Console.WriteLine(_);

will produce a compiler error with C#7, since _ is not intended to be used.

The usage of _ is not restricted to out parameters, but can be used for returns, too (as Evk pointed out)

byte.TryParse(p.Value, out var _); // I don't care about the out variable
_ = SomeMethod(); // I don't care about the return value

There is an excellent answer covering most things about ommitted parameters here.

Remarks: I would prefer out _ over out var _, since there is a clear syntactic distinction between out _ and out var legalVariableName.

EDIT

Obviously I'm not quite right here. There are some subtle differences, see Ben Voigts answer.

Unmusical answered 15/2, 2018 at 6:42 Comment(7)
_ = SomeMethod() is to explicitly express that you do not care about the result (and not acidentally forgot about it). It can be used anywhere (I mean just void Main() { _ = 123;} compiles fine without any out _ and so on, so it's not related to the out var _ block).Whey
@Whey Thanks, edited my answer.Unmusical
out var identifier was legal in some prerelease versions, but not in C# 6. C# 7 is the first released version that permits out variables (which you called an inline declaration) was allowed. Semi-official referenceSchiff
I think you have this backwards: "With C#6 the former is illegal, but the latter is valid" (former is first, latter is last)Caughey
This answer is incorrect on several levels. The lines of code are not equivalent, and the claims about C# 6 are faulty.Schiff
@Rufus: In C# 6 they're both invalid, the first because _ is an undeclared identifier, the second because out typename identifier is illegal syntax.Schiff
@BenVoigt Well, yes, the variable has to be declared somewhere as byte _;. Just as whatever p is has to be declared. I thought that was assumed, but you have a point.Caughey
S
9

The difference is how they handle an existing variable named _.

string _;

int.TryParse("123", out var _); // legal syntax for discard
int.TryParse("123", out _); // compile error, string _ is incompatible with out int parameter

or

int _;

int.TryParse("123", out var _); // discard
Console.WriteLine(_); // error: variable is not assigned
int.TryParse("123", out _); // passes existing variable byref
Console.WriteLine(_); // ok: prints "123"

The reason for this is that out _ already had a meaning, and the language maintains backward compatibility with that old meaning. But out typename identifier is new syntax in C# 7, so there's no backward compatibility constraint.

Schiff answered 15/2, 2018 at 7:22 Comment(1)
Thanks for elaborating, I admit that I haven't thought about that case.Unmusical
U
5

As opposed to what others in their comments said: No, there are no differences. They both produce the exact same IL.

Both

byte.TryParse(p.Value, out _);
Console.WriteLine(_);

and

byte.TryParse(p.Value, out var _);
Console.WriteLine(_);

will produce a compiler error with C#7, since _ is not intended to be used.

The usage of _ is not restricted to out parameters, but can be used for returns, too (as Evk pointed out)

byte.TryParse(p.Value, out var _); // I don't care about the out variable
_ = SomeMethod(); // I don't care about the return value

There is an excellent answer covering most things about ommitted parameters here.

Remarks: I would prefer out _ over out var _, since there is a clear syntactic distinction between out _ and out var legalVariableName.

EDIT

Obviously I'm not quite right here. There are some subtle differences, see Ben Voigts answer.

Unmusical answered 15/2, 2018 at 6:42 Comment(7)
_ = SomeMethod() is to explicitly express that you do not care about the result (and not acidentally forgot about it). It can be used anywhere (I mean just void Main() { _ = 123;} compiles fine without any out _ and so on, so it's not related to the out var _ block).Whey
@Whey Thanks, edited my answer.Unmusical
out var identifier was legal in some prerelease versions, but not in C# 6. C# 7 is the first released version that permits out variables (which you called an inline declaration) was allowed. Semi-official referenceSchiff
I think you have this backwards: "With C#6 the former is illegal, but the latter is valid" (former is first, latter is last)Caughey
This answer is incorrect on several levels. The lines of code are not equivalent, and the claims about C# 6 are faulty.Schiff
@Rufus: In C# 6 they're both invalid, the first because _ is an undeclared identifier, the second because out typename identifier is illegal syntax.Schiff
@BenVoigt Well, yes, the variable has to be declared somewhere as byte _;. Just as whatever p is has to be declared. I thought that was assumed, but you have a point.Caughey

© 2022 - 2024 — McMap. All rights reserved.