AnonymousComparer - ver.1.3.0.0
- C# - 10.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臭いんだよ。無名クラス(別に欲しくはないけど)がないから作るの面倒なんだよ。ということです。あるとそれなりに便利です。