_=> what does this underscore mean in Lambda expressions?

27,248

Solution 1

That is a convention used when you don't care about the parameter.

Solution 2

It is a parameter name, albeit not a useful one, but it's the one typically used (by some conventions) when you need to specify that the expression has a parameter in order to get the code to compile, but you don't really care about it, so you're just going to ignore it.

It's basically exploiting the syntax for what a legal identifier in C# constitutes, and since an identifier can start with an underscore, and contain nothing else, it's just a parameter name.

You could just have easily have written:

var _ = 10;

Solution 3

_ is a valid variable name. They are just using _ as a variable.

Solution 4

Because lamda expression is mostly used in a short, anonymous code so that the name of the variable sometimes is not neccessary, even they do not use the variable in the code block, so that they just give a _ for a short, convention

Solution 5

I also second the use of _ => _.method() for one-line, method-call lambdas, since it reduces the instruction's cognitive weight. Specially when using generics, writing x => x.method() just adds that split-second consideration of "What's this 'x'? Is it a coordinate in space?".

Consider the following case:

Initialize<Client> ( _=>_.Init() );

Used with a Generics call, the underscore in this case works as a "bypass symbol". It avoids redundancy, defining that the type of the argument is obvious and can be infered from usage - just as when you use 'var' to prevent repeating a type declaration. Writing client=>client.Init() here would just make the instruction longer without adding any meaning to it.

Obviously, this doesn't apply to the parameters to be passed to the method, which should be named descriptively. Eg.: Do( id=>Log(id) );

The single-underscore-parameter usage for method calls is hardly justifiable when using a block of code instead of a one-liner, since the lambda identifier gets disconnected from its generics definition. In general when the same identifier is to be reused, give it a descriptive name.

The bottom line is that verbosity is only justifiable for disambiguation, especially for lambdas, which were created to simplify anonymous delegates creation in the first place. In any case, common sense should be used, balancing out legibility and conciseness. If the symbol is only a "hook" to the real functionality, one character identifiers are perfectly fine. That's the case with For-loops and the "i" and "j" letters as indexers.

Share:
27,248
Prasad
Author by

Prasad

Updated on July 08, 2022

Comments

  • Prasad
    Prasad almost 2 years

    What does an lambda expression like _=> expr mean?

    What is the purpose of _ as input to lambda?

    Example:

    int count = 0;
    list.ForEach(_ => count += 1);
    
  • Ibrahim Quraish
    Ibrahim Quraish about 14 years
    It's more common in Haskell and other functional languages. I think that's where it comes from.
  • Jörg W Mittag
    Jörg W Mittag about 14 years
    In Haskell, ML, Scala and others, _ is the wildcard character in pattern matching. It basically means "I don't care, I always want this to match". This "I don't care" then is carried over when it comes to naming things that you don't care about and from there, it spills over into other programming languages. It is, for example, also used in Ruby to mean the same thing as in this example, even though _ has absolutely no special significance in Ruby.
  • oligan
    oligan about 12 years
    @JörgWMittag True in May 2010, but not as of June 2010. Awesome timing! :) stackoverflow.com/q/6397078/38765
  • amesh
    amesh over 9 years
    Instead of _ , can we use () ?
  • Lasse V. Karlsen
    Lasse V. Karlsen over 9 years
    Did you try using that?
  • amesh
    amesh over 9 years
    Yes, I had used it when I was creating a thread using lambda expression. Thread t= new Thread(()=>doSomething(x,y)); t.start();
  • amesh
    amesh over 9 years
    What I assume is, the use of _ is passing each variable of the collection to the lambda expression even though it's not used. But when we use () it may not happen. I mean parameter less lambda.
  • Lasse V. Karlsen
    Lasse V. Karlsen over 9 years
    You need to try it using the ForEach method call. There is an overload on the Thread constructor that takes a delegate that doesn't take any parameters. Try calling a method, like that ForEach, that takes a delegate that takes a parameter instead.
  • Varvara Kalinina
    Varvara Kalinina almost 7 years
    +1 for this approach! I though I was the only one using underscores in lambdas to "reduce the cognitive weight" and not for showing that this parameter is not used. It does read easier with underscores, especially if there's lot of chaining and you can immediately infer the type, as is often the case with LINQ queries!
  • Aluan Haddad
    Aluan Haddad almost 7 years
    Do(id => Log(id)) is better abbreviated as Do(Log).