C# notation understanding Select(int.Parse)
Asked Answered
G

5

8

I found a little script that I understand fully. I've got a string with *1 -2 5 40* for example. It reads the input string, splits it into a temporary array. Then this array is parsed and each element is transformed into an integer. The whole thing is order to give the nearest integer to zero.

But what I don't understand is the notation Select(int.Parse). There is no lambda expression here and the method int.Parse isn't called with brackets. Same with the OrderBy(Math.Abs)

Thank you in advance

var temps = Console.ReadLine().Split(new []{' '}, StringSplitOptions.RemoveEmptyEntries);  

var result = temps.Select(int.Parse)
    .OrderBy(Math.Abs)
    .ThenByDescending(x => x)
    .FirstOrDefault();
Gnathion answered 8/6, 2017 at 11:37 Comment(0)
Q
12

int.Parse is a method group - what you're seeing is a method group conversion to a delegate. To see it without LINQ:

Func<string, int> parser = int.Parse;
int x = parser("10"); // x=10

It's mostly equivalent to:

Func<string, int> parser = text => int.Parse(text);

... although there are plenty of differences if you want to go into the details :)

Quijano answered 8/6, 2017 at 11:40 Comment(0)
C
7

Select(int.Parse) is nearly equivalent to Select(x => int.Parse(x)).

The Select demands an Func<T, R>, which in this case is also the signature of int.Parse (it has a single parameter with a return value). It convers the method group to the matching delegate.

In this case Func<T, R> will map to Func<string, int>, so it matches the int Parse(string) signature.

Citole answered 8/6, 2017 at 11:40 Comment(0)
C
1

The parameter for .Select() is Func<T1, T2>() where T1 is the input parameter (the individual values of temps), and T2 is the return type.

Typically, this is written as a lambda function: x => return x + 1, etc. However, any method that fits the generic definitions can be used without having to be written as a lambda since the method name is the same as assigning the lambda to a variable.

So Func<string, int> parseInt = s => Convert.ToInt32(s); is syntactically equivalent to calling the method int.Parse(s).

The language creates the shortcut of automatically passing the Func parameter to the inside method to create more readable code.

Creationism answered 8/6, 2017 at 11:42 Comment(0)
G
0

int.Parse is a method with signature string -> int (or actually, a method group, with different signatures. But the compiler can infer you need this one, because it is the only one that fits.

You could use this method as a parameter wherever you would supply a delegate parameter with the same signature.

Gabardine answered 8/6, 2017 at 11:40 Comment(1)
That doesn't explain why you can use it like this.Illfavored
M
0

Select LINQ IEnumerable<> extension method signature looks like that:

public static IEnumerable<TResult> Select<TSource, TResult>(
    this IEnumerable<TSource> source,
    Func<TSource, TResult> selector
)

Look at the selector argument. In your case you pass to Select .Net standard function int.Parse which has signature:

public static int Parse(
    string s
)

.Net compiler can convert delegates to Func<...> or Action<...>. In case of int.Parse it can be converted to Func and therefore can be passed as argument to Select method.

Exactly the same with OrderBy. Look at its signature too.

Mackenziemackerel answered 8/6, 2017 at 11:44 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.