10

私のアプリケーションで自然な並べ替えを行うために、現在、shlwapi.dll で StrCmpLogicalW という関数を P/Invoke しています。Mono でアプリケーションを実行しようと考えていましたが、もちろん、この P/Invoke を使用することはできません (とにかく私が知る限り)。

そのメソッドの実装をどこかで見ることは可能ですか、それとも同じことを行う、クリーンで効率的な C# スニペットがありますか?

私のコードは現在次のようになっています。

[SuppressUnmanagedCodeSecurity]
internal static class SafeNativeMethods
{
    [DllImport("shlwapi.dll", CharSet = CharSet.Unicode)]
    public static extern int StrCmpLogicalW(string psz1, string psz2);
}

public class NaturalStringComparer : IComparer<string>
{
    private readonly int modifier = 1;

    public NaturalStringComparer() : this(false) {}
    public NaturalStringComparer(bool descending)
    {
        if (descending) modifier = -1;
    }

    public int Compare(string a, string b)
    {
        return SafeNativeMethods.StrCmpLogicalW(a ?? "", b ?? "") * modifier;
    }
}

したがって、私が探しているのは、 extern 関数を使用しない上記のクラスの代替です。

4

4 に答える 4

10

C# で自然な文字列比較を実装したところです。

public class NaturalComparer : IComparer<string>
{
   public int Compare(string x, string y)
   {
      if (x == null && y == null) return 0;
      if (x == null) return -1;
      if (y == null) return 1;

      int lx = x.Length, ly = y.Length;

      for (int mx = 0, my = 0; mx < lx && my < ly; mx++, my++)
      {
         if (char.IsDigit(x[mx]) && char.IsDigit(y[my]))
         {
            long vx = 0, vy = 0;

            for (; mx < lx && char.IsDigit(x[mx]); mx++)
               vx = vx * 10 + x[mx] - '0';

            for (; my < ly && char.IsDigit(y[my]); my++)
               vy = vy * 10 + y[my] - '0';

            if (vx != vy)
               return vx > vy ? 1 : -1;
         }

         if (mx < lx && my < ly && x[mx] != y[my])
            return x[mx] > y[my] ? 1 : -1;
      }

      return lx - ly;
   }
}
于 2011-04-12T20:29:13.310 に答える
5

http://www.interact-sw.co.uk/iangblog/2007/12/13/natural-sortingが探しているもののようです。

(いいえ、.NET に組み込まれている StrCmpLogicalW に相当するマネージはありません)

于 2012-01-09T19:21:23.567 に答える