AnonymousComparer - ver.1.2.0.0

AnonymousComparerを再度バージョンアップしました。ダウンロードは上記リンク先、CodePlexからどうぞ。バグがなければ、これで最後だと思います。いやもう内容的には出尽くしたかな、と。更新内容はIComparer<T>を作成可能にしました。また、OrderByでIComparer<T>を利用するものへ、拡張メソッドを追加しました。

// こんなシーケンスがあるとして、IComparer<T>を使用してその場で自由に比較を指定したい
var seq = new[] { 1, 2, 3 };
// IComparer<T>を作る
var comparer = AnonymousComparer.Create<int>((x, y) => y - x);
seq.OrderBy(x => x, comparer);
// OrderBy/ThenByに拡張メソッドが追加されているので、型推論が効いたまま書けます
// List.Sort(Comparison)みたいなイメージですかね
seq.OrderBy(x => x, (x, y) => y - x); // 3, 2, 1
seq.OrderByDescending(x => x, (x, y) => y - x); // 1, 2, 3

LinqにはDescendingが用意されているので、あまり使い道はなさそうですね。私もOrderByのICompare<T>オーバーロードを使いたいと思ったシチュエーションが今までにありませんし……。第一引数がkeySelectorなので、それで十分用を足せちゃうのですよね。それにしても、DescendingでIComparerを指定した場合の結果は紛らわしくていかんですな。

さて、更新内容はもう一つあって、むしろこっちのほうが重要なのですが、compareKeySelectorを利用したオーバーロード(Linq演算子への拡張メソッドは全部それです)で、シーケンスにnullが含まれている場合にnullで落ちるのを修正しました。今回からはヌルぽで落ちません。どういうこっちゃ、というと説明しづらいのでコードで。

class MyClass
{
    public int MyProperty { get; set; }

    public override string ToString()
    {
        return "Prop = " + MyProperty;
    }
}

static void Main()
{
    var array = new[]
    {
        new MyClass{MyProperty=1},
        null,
        new MyClass{MyProperty=2},
        null,
        new MyClass{MyProperty=1}
    };
    var r1 = array.Count(); // 5
    var r2 = array.Distinct().Count(); // 4 (nullが重複として消える)
    foreach (var item in array.Distinct(mc => mc.MyProperty))
    {
        Console.WriteLine((item == null) ? "ヌルぽ" : item.ToString());
    }
    // 出力結果は
    // Prop = 1
    // ヌルぽ
    // Prop = 2
}

といった感じです。分かったような分からないような?

Profile

Yoshifumi Kawai

Cysharp, Inc
CEO/CTO

Microsoft MVP for Developer Technologies(C#)
April 2011
|
July 2023

Twitter:@neuecc GitHub:neuecc

Archive