AnonymousComparer - ver.1.3.0.0

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

Profile

Yoshifumi Kawai

Cysharp, Inc
CEO/CTO

Microsoft MVP for Developer Technologies(.NET)
April 2011
|
July 2025

X:@neuecc GitHub:neuecc

Archive