LINQからBoost.Variant、そしてF#へ至る流れまとめ

今日勉強になった一連のまとめ。結果F#最高ということでよろしいですか?w
1
ヒロ @cz75hiro

「List<>.ConvertAll? IEnumerable<>.Select使えよ」って言ったら変な顔された

2011-01-20 18:51:24
@kassyi

@cz75hiro どっちでもいい気がするのですが…?

2011-01-20 18:56:57
ヒロ @cz75hiro

@kassyi Select使うと遅延評価出来るとです

2011-01-20 18:59:15
ヒロ @cz75hiro

サンプル書いてみた。ステップ実行したらわかるかも。 https://gist.github.com/787681

2011-01-20 19:01:26
ヒロ @cz75hiro

「FindAllとかConvertAllで毎回全要素なめるなんて時代遅れですよ!」って言いたいけど、言ったらやっぱり変な顔されそうなので言わないことにする

2011-01-20 19:02:32
ヒロ @cz75hiro

サンプルに誤字あった。まぁいいや

2011-01-20 19:02:57
ヒロ @cz75hiro

遅延評価…後付で条件増やしても、ループの回数を抑えられる可能性がある可愛いやつ。ただし可能性があるだけで毎回ToListしちゃう人なんかにはお勧めできない。

2011-01-20 19:05:03
ヒロ @cz75hiro

IEnumerable<>.Unionは要素内のオブジェクトが等価な場合、結果から省かれるのか。 https://gist.github.com/787695

2011-01-20 19:13:25
neuecc @neuecc

@cz75hiro .Addはダサいのでコレクション初期化子お~。あとCast<T>もありますよ!

2011-01-20 19:19:24
ヒロ @cz75hiro

@neuecc おおCast!使わないので忘れてました。確かに確かに!コレクション初期化子は、参照型の場合、自分で混乱するので余り使いませんのです。プリミティブ型のコレクションの時ならたまに使います!自分で言っててすごく言い訳がましいなぁw

2011-01-20 19:25:44
ヒロ @cz75hiro

CastとSelectの内部的な違いがわからない…

2011-01-20 19:28:48
ヒロ @cz75hiro

Castはほんとにasでキャストしてるだけか

2011-01-20 19:34:01
neuecc @neuecc

@cz75hiro not typesafeなのでevilですね!二つのサブクラスを継承してもげもげしたい時は、Listのほうを、new List<Base> としてキャストしないで済むようにすると吉な感。

2011-01-20 19:35:44
ヒロ @cz75hiro

@neuecc Bese使えという意見はごもっともです。しかし社内フレームワーク(笑)が、サブクラスのListしか返してくれないのですよ。ふふふ・・・(TT

2011-01-20 19:39:07
neuecc @neuecc

@cz75hiro いやまあ、戻り値は具象に近いほうがいい(それで、利用先でダウンキャストが頻発するならアップキャストよりヤバい)ので、その辺は難しいですよねー。

2011-01-20 19:45:58
ヒロ @cz75hiro

@neuecc 一番楽なのは、キャストが必要な振る舞いをサブクラスにカプセル化して、サブクラス側でやらしとけばいいのかなと思ってます。しかしそうなるとインターフェースの定義をしっかりしないと逆に後から苦しくなる、かなぁ・・・

2011-01-20 19:50:23
ヒロ @cz75hiro

List<T>を返すメソッドを持つGenericなクラスは、意外と融通がきかない。List<Base>なら融通効くけどその場合はGenericがいらない子になってしまう。そういう設計が望ましいのかなぁ

2011-01-20 19:46:21
neuecc @neuecc

@cz75hiro あ、.Select(x => (T)x)だとCast<T>と違ってタイプセーフでした。基底型に変換するならSelectのほうがいいかも、ちょっと冗長ですが。アップは(ダウンと違って)そこまで忌避しなくてもいいので、こちらならまだ全然アリなのかも。

2011-01-20 19:53:51
ヒロ @cz75hiro

@neuecc あれ?そうですかね? https://gist.github.com/787734 これで実行時エラーになりますので注意は必要だと思いますが。アップキャスト限定の話でしょうか?

2011-01-20 20:02:36
neuecc @neuecc

@cz75hiro はい。new List<inheritHoge1>().Select(x => (inheritHoge2)x); はコンパイル不可 new List<inheritHoge1>().Cast<inheritHoge2>(); は実行時例外なので。

2011-01-20 20:07:15
ヒロ @cz75hiro

@neuecc おお、確かに。仕事でスーパークラスのコレクションをあまり使う機会がなかったので、結構発見がありますね

2011-01-20 20:16:10
neuecc @neuecc

@cz75hiro あと List<Sub1>.Cast<Base>().Union(List<Sub2> が成立している(List<Sub2>側にはキャストが不要)なのはジェネリックの共変(covariance)のお陰ですね。多分、VS2008だとコンパイル通らないかとー。

2011-01-20 20:20:22
ヒロ @cz75hiro

@neuecc そうか・・・VS2010には共変があったんでしたね。Union細やかな挙動でスゲーとかアホなこと思ってました(^^;

2011-01-20 20:25:21
ヒロ @cz75hiro

hoge1List.Select(x => (Hoge)x).Union(hoge2List.Select(x => (Hoge)x));いきなりキモいコードになった

2011-01-20 20:26:50