C#:在shlwapi.dll中实现或替代StrCmpLogicalW

对于我的应用程序中的自然排序,我目前在shlwapi.dll中调用一个名为StrCmpLogicalW的函数。 我正在考虑尝试在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 { 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函数。

我刚刚在C#中实现了自然字符串比较,也许有人可能觉得它很有用:

 public class NaturalComparer : IComparer { 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; } } 

我使用正则表达式删除特殊字符。 然后转换为int。 然后我比较整数。

输入:

列表输入=新列表{“6.04”,“6.01”,“6.03”,“6#04”}; 

预期产出:

 6.01
 6.03
 6.04
 6#04

  var output = input.OrderBy(s => s,new NaturalStringComparer());
             foreach(输出中的var排序)
             {
                 Console.WriteLine(排序);
             }


 public struct NaturalStringComparer:IComparer
     {
         public int Compare(string x,string y)
         {
             if(x == null && y == null)返回0;
             if(x == null)返回-1;
             if(y == null)返回1;

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

             int a = int.Parse(System.Text.RegularExpressions.Regex.Replace(x,@“\ D +”,“”));
             int b = int.Parse(System.Text.RegularExpressions.Regex.Replace(y,@“\ D +”,“”));

            返回a.CompareTo(b);
         }
     }