読者です 読者をやめる 読者になる 読者になる

OAO

開発とかBTSとかIDEとかスクラムとか 書くかもしれないブログです たぶん

ぶれいすさんがコメントしてくれたのでソレを反芻(自分用エントリ)

C# LINQ

id:bleis-tift
コンパイラの気持ちになって考えると、hogelist.Where(n => n.ID == 1)というものが一意に定まるかどうかはわかりません。
なので、WhereはIEnumerableを返すようにできていて、何にもヒットしなければ空、全部ヒットしたら元のものがそのまま出てくる感じです。Selectというのは「各要素を別のものに変換する」というもので、これもIEnumerableを受け取ってIEnumerableを返すようになっています。これによって、Whereで絞ってSelectで変換かけたうえで、またWhereで絞る、と言ったことができます。で、人間様にとってはIDは一意に定まるだろ、と言うのが分かるので、最後にFirstなりSingleなりを置いてあげて、要素を取り出します。
Firstは複数要素があったとしても最初のものを返すのに対して、Singleは要素が空だったり、2個あったりすると例外が発生します(Firstも空のIEnumerableに対しては例外を投げる)。
要素が存在しなかった場合はデフォルトの値を返してほしい、という場合はFirstOrDefaultやSingleOrDefaultを使います。ちなみに、LINQ to Objectsの各メソッドは、条件を取るものが多いです。
なので、今回の例であれば、hogelist.Single(n => n.ID == 1)としても大丈夫です。
値を加工したい場合は、Selectに渡していたラムダ式の処理を外側に持って行けばいいだけです。



>コンパイラの気持ちになって考えると、hogelist.Where(n => n.ID == 1)というものが一意に定まるかどうかはわかりません。

・おっしゃるとおりですはい。

>なので、WhereはIEnumerableを返すようにできていて、何にもヒットしなければ空、全部ヒットしたら元のものがそのまま出てくる感じです。

・IEnumerableについて 参考にしたサイト:http://ufcpp.net/study/csharp/sp_foreach.html#iEnumerable

>Selectというのは「各要素を別のものに変換する」というもので、これもIEnumerableを受け取ってIEnumerableを返すようになっています。これによって、Whereで絞ってSelectで変換かけたうえで、またWhereで絞る、と言ったことができます。

・なるほどなるほど。

>で、人間様にとってはIDは一意に定まるだろ、と言うのが分かるので、最後にFirstなりSingleなりを置いてあげて、要素を取り出します。

・私が最後に挑戦したところですね。



>Firstは複数要素があったとしても最初のものを返すのに対して、Singleは要素が空だったり、2個あったりすると例外が発生します(Firstも空のIEnumerableに対しては例外を投げる)。

・これは後述



>要素が存在しなかった場合はデフォルトの値を返してほしい、という場合はFirstOrDefaultやSingleOrDefaultを使います。ちなみに、LINQ to Objectsの各メソッドは、条件を取るものが多いです。

http://www.atmarkit.co.jp/fdotnet/dotnettips/952firstordefault/firstordefault.html

・nullとかnothingが帰ってくるのでそこでフックする感じですかね。



>なので、今回の例であれば、hogelist.Single(n => n.ID == 1)としても大丈夫です。

・存在値を指定してる場合はそうなりますね。

・安全策が必要なら「SingleOrDefault」で指定してやることにします。



>値を加工したい場合は、Selectに渡していたラムダ式の処理を外側に持って行けばいいだけです。

・むむ。

・こういう理解でいいのかな。