y-staba
@y-staba

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

C# LINQ Selextの引数について

LINQ Selectの引数について

C#で競技プログラミングに挑戦しています。
その際、int配列を作成するのにLINQが便利だと知りました。
ただ、Selectを使用する時に、引数を省略できる場合があります。(下記の例であれば変数x)
その理由について説明をいただきたいです。

ソースコード

//標準入力{"1", "22", "333"} の場合、int配列{1, 22, 33} を作成

int[] input = Console.ReadLine().Split(' ').Select(int.Parse).ToArray();
int[] input = Console.ReadLine().Split(' ').Select(x => int.Parse(x)).ToArray();
0

2Answer

//標準入力{"1", "22", "333"} の場合、int配列{1, 22, 33} を作成

"1 22 33" の入力ですよね?

であれば、Microsoft のドキュメント、

Select<TSource,TResult>(IEnumerable<TSource>, Func<TSource,TResult>)
https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.select?view=net-8.0#system-linq-enumerable-select-2(system-collections-generic-ienumerable((-0))-system-func((-0-1)))

によると、引数 selector に渡すのは Func<TSource,TResult> というデリゲートで、

int.Parse

x => int.Parse(x)

もその型のデリゲートだからでしょう。

select.png

【追伸】

引数を省略できる場合があります。(下記の例であれば変数x)

「引数を省略できる」というわけではないですよ。上のデバッグ画像の「値」にあるように int.Parsex => int.Parse(x) は別物です。前者は Int32 構造体の静的メソッドのデリゲート、後者はラムダ式のデリゲートです。

0Like

Comments

  1. @y-staba

    Questioner

    ご回答ありがとうございます。
    ご指摘の通り、入力はstring配列{"1", "22", "333"}ではなく、1行の文字列"1 22 33"が正しいです。

    int.Parse と x => int.Parse(x) 、どちらを指定しても動作は同じですが、別の種類のデリゲートなんですね。
    デリゲートについて知識が乏しいため、今回の機会にFuncやラムダ式を含めて学習したいと思います。

  2. デリゲートは C++ で言う関数のポインタ(アドレス)のようなもの、Func は .NET Framework に定義済みのデリゲートです。そう思ってドキュメントを読むと分かりやすいかも。

  3. 質問者さん、このスレッドの課題は解決したと思いますが、であればクローズしてください。オープン状態のまま放置しないようお願いします。

  4. @y-staba

    Questioner

    ご指摘ありがとうございます。

デリゲートについてどのくらい理解されていますか?

Func<string, int> 型にはstring型の引数を1つとりint型の戻り値を返すメソッドを代入できます。

int.Parseはその条件を満たすためそのまま代入できますが、ラムダ式 x => int.Parse(x) も(型推論により)同じ条件のメソッドとして扱われるためどちらで書くことも出来ます。
厳密には2つは違うビルド結果になったりもするのですが、挙動は同じです。

0Like

Comments

  1. @y-staba

    Questioner

    ご回答ありがとうございます。
    デリゲートの知識はほぼない状態です。
    Funcやラムダ式などと一緒にデリゲートを学びたいと思います。

  2. そうですね、まずデリゲートについて学ばれることをお勧めします。
    Funcはデリゲートの型の一種ですので、デリゲートの学習の中で登場するかと思います。ただし、同時にジェネリックの知識も必要になります。
    ラムダ式はその後がよろしいかと。

Your answer might help someone💌