繁体   English   中英

.net - Array.Sort 和 Array.BinarySearch 的问题 - 文化和全球化

[英].net - Problems with Array.Sort and Array.BinarySearch - culture and globalization

我需要对包含单词列表的数组进行排序,并使用 binarysearch 进行搜索。 由于某些原因,单词列表必须始终使用“en-US”的排序规则(即美国区域设置)进行排序。 该代码将在各种国际操作系统下运行,当然,这意味着单词列表将根据使用的本地区域设置进行不同的排序。 在运行立陶宛区域设置的计算机/设备上可能会出现一个问题。 为什么? 因为字母“ Y ”在大多数语言中的排序方式为 X- Y - Z,而在立陶宛语中,排序顺序为 I- Y -J。 这种行为会对我的程序造成严重破坏。

在台式 PC 上,我可以使用以下命令将区域设置暂时更改为美式英语:

Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture("en-US")

然而,由于我是为 Windows Mobile (CF.NET) 开发的,这段代码是不可能实现的。

我发现了一些可以让我以编程方式更改设备上的区域设置的技巧,但它们不是“官方的”并且被认为是有风险的,所以我更愿意避免这些。

所以我的问题是:如何在排序和搜索时强制 Array.Sort 和 Array.BinarySearch 使用 CultureInfo = "en-US" 而不管设备上设置的区域设置如何?

我相信我可以使用:

Public Shared Function BinarySearch(Of T) ( _
    array As T(), _
    value As T, _
    comparer As IComparer(Of T) _
) As Integer

并实施比较器以考虑 CultureInfo(并将其设置为“en-US”),但尽管努力尝试,但我不知道如何做到这一点。 如果有人可以在 VB.Net 或 C# 中发布一些示例代码或解释如何做到这一点,我将不胜感激。

如果您知道任何适用于 CF.Net 的替代解决方案,那么,当然,我全神贯注。

谢谢。

编辑:

我将 Twanfosson 的答案视为公认的解决方案,因为我的问题清楚地表明我想保持与英语的联系。

但是,在灵活性方面,我相信Guffa的答案是最好的。 为什么? 让我们再举一个例子:在德语中,字母Ö排序为Ö -XZ 而在瑞典语和芬兰语中,排序为 XZ- Ö 在爱沙尼亚语中,排序顺序是 Z- Ö -X。 很复杂,不是吗? Guffa 的解决方案将让我在德国区域设置下运行的设备上强制瑞典排序顺序(更改 CultureInfo)。 在这种情况下,使用Comparer.DefaultInvariant及其与英语的关联无济于事,可能字母Ö以 O 结尾。因此我的投票将投给 Guffa。

好吧,两者的答案都是实现一个比较器。 创建一个实现IComparer(Of String)接口的类,并拥有自己的CultureInfo对象,用于比较字符串:

Public Class StringComparerEnUs
   Implements IComparer(Of String)

   Private _culture As CultureInfo

   Public Sub New()
      _culture = New CultureInfo("en-US")
   End Sub

   Public Function Compare(ByVal x As String, ByVal y As String)
      Return String.Compate(x, y, false, _culture)
   End Function

End Class

现在您可以使用它对字符串进行排序:

Array.Sort(theArray, New StringComparerEnUs())

并找到它们:

pos = BinarySearch(theArray, "Dent, Arthur", new StringComparerEnUs())

(当然,可以通过在构造函数中接受区域性字符串来使该类更通用,并且您还可以添加一个变量以使用String.Compare调用中的ignoreCase参数。)

不能使用不变文化吗?

InvariantCulture 检索不变文化的实例。 它与英语相关,但与任何国家/地区无关。

使用不变文化将使这变得微不足道。

Array.Sort( myArray, Comparer.DefaultInvariant );

Array.BinarySearch( myArray, myString, Comparer.DefaultInvariant );

试试这个:

class EnglishComparer : IComparer<string>
{
  static CultureInfo __english = new CultureInfo("en-US");

  public int Compare(string x, string y)
  {
    return string.Compare(x, y, __english, CompareOptions.None);
  }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM