AnonymousComparer - ver.1.3.0.0
- 2010-10-18
ver 1.3というか、バグフィックスです。ToDictionaryとかだと拡張メソッドが本来あるのとオーバーロードが被ってて使おうとするとコンパイル通らなかったのです。気づいてたんだけど放置してました、すみませんすみません。というわけで幾つかのものを削りました。これでコンフリクトなし。
どんなものかというと、こんなものです。最初投稿した時のの流用で(こらこら)
class MyClass
{
public int MyProperty { get; set; }
}
static void Main()
{
// 例として、こんな配列があったとします
var mc1 = new MyClass { MyProperty = 3 };
var mc2 = new MyClass { MyProperty = 3 };
var array = new[] { mc1, mc2 };
// Distinctは重複を取り除く。でも結果として、これは、2です。
var result = array.Distinct().Count();
// 参照の比較なので当然です。では、MyPropertyの値で比較したかったら?
// DistinctにはIEqualityComparerインスタンスを受け付けるオーバーロードもあります
// しかしIEqualityComparerはわざわざ実装したクラスを作らないと使えない
// そこで、キー比較のための匿名Comparerを作りました。
// ラムダ式を渡すことで、その場だけで使うキー比較のIEqualityComparerが作れます。
array.Distinct(AnonymousComparer.Create((MyClass mc) => mc.MyProperty));
// でも、長いし、型推論が効かないから型を書く必要がある
// Linqに流れているものが匿名型だったりしたら対応できないよ!
// というわけで、本来のLinqメソッドのオーバーロードとして、記述出来るようにしました
// ちゃんと全てのIEqualityComparerを実装しているLinq標準演算子に定義してあります
array.Distinct(mc => mc.MyProperty);
// 短いし、型推論もちゃんと効くしで素晴らしいー。
// 匿名型でもいけます(VBの匿名型はC#(全ての値が一致)と違ってKey指定らしいですね)
var anonymous = new[]
{
new { Foo = "A", Key = 10 },
new { Foo = "B", Key = 15 }
};
// true
anonymous.Contains(new { Foo = "dummy", Key = 10 }, a => a.Key);
}
つまり、LinqのIEqualityComparerのオーバーロードうぜえ、何がインターフェースだよクソが、Linqならラムダ式だろ、インターフェースとかJava臭いんだよ。無名クラス(別に欲しくはないけど)がないから作るの面倒なんだよ。ということです。あるとそれなりに便利です。