Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Discards inside C# Linq queries

Tags:

c#

linq

c#-7.0

I wonder if that's good pattern to use Discards in Linq queries according to https://docs.microsoft.com/en-us/dotnet/csharp/discards, example:

public bool HasRedProduct => Products.Any(_=>_.IsRed == true);

What's pros / cons instead using

public bool HasRedProduct => Products.Any(x=>x.IsRed == true);
like image 273
boski Avatar asked Apr 25 '19 06:04

boski


2 Answers

That isn't a discard - it's a lambda expression parameter called _. It falls into the note later in the article:

Note that _ is also a valid identifier. When used outside of a supported context, _ is treated not as a discard but as a valid variable.

You can tell it's not a discard because its value isn't discarded - you're using it in the rest of the lambda expression. I would strongly discourage the use of _ as a lambda expression parameter name when you are using the value. It's fine to use _ as a parameter name when you want to discard it though, even if it's not technically a discard from a language perspective. The name _ was chosen for discards precisely because that's how it was already being used in practice.

like image 148
Jon Skeet Avatar answered Nov 10 '22 16:11

Jon Skeet


Those underscores are just lambda parameters named _ as they did in C# 6. They are not discards.

Discards where introduced in C# 7 in some new contexts (for example, out variable declarations) and some existing contexts (for example, assignment _ = expression;). In the latter case, the C# 6 interpretation of the underscore wins, if one exists, to respect backwards compatibility.

Discards are variables which you can assign to, but cannot read from. They don't have names. Instead, they are represented by an '_' (underscore). In C#7.0, they can appear in the following contexts:

  • out variable declarations, such as bool found = TryGetValue(out var _) or bool found = TryGetValue(out _)
  • deconstruction assignments, such as (x, _) = deconstructable;
  • deconstruction declarations, such as (var x, var _) = deconstructable;
  • is patterns, such as x is int _
  • switch/case patterns, such as case int _:

The principal representation of discards is an _ (underscore) designation in a declaration expression. For example, int _ in an out variable declaration or var (_, _, x) in a deconstruction declaration.

The second representation of discards is using the expression _ as a short-hand for var _, when no variable named _ is in scope. It is allowed in out vars, deconstruction assignments and declarations, and plain assignments (_ = IgnoredReturn();). It is, however, not allowed in C#7.0 patterns. When a variable named _ does exist in scope, then the expression _ is simply a reference to that variable, as it did in earlier versions of C#.

https://github.com/dotnet/roslyn/blob/master/docs/features/discards.md

like image 30
Julien Couvreur Avatar answered Nov 10 '22 17:11

Julien Couvreur