【问题标题】:Difference between ASCII comparison and string comparisonASCII比较和字符串比较的区别
【发布时间】:2014-09-17 00:10:46
【问题描述】:

我正在使用 C#。当我比较两个 char 值时,它会向我发送正确的输出,例如,

'-'.CompareTo('!') //Its sending me positive value 12

表示 '-' > '!'true

但是当我比较两个相同值的字符串时,它会发送给我不同的结果

"-".CompareTo("!") //Its sending me negative value -1

表示 "-" > "!"false

谁能解释一下为什么会这样?这两种情况都不应该是“真的”吗?

【问题讨论】:

  • CompareTo 用于排序,而不是(必须)用于检查相等性。如果CompareTo 返回零,则实例被视为“相等”。请参阅Char.CompareToString.CompareTo 了解更多信息。
  • 来自Char.CompareTo :此方法执行的比较是基于此实例和的编码值,而不是它们的字典特征。
  • @Corak - 我正在为字符串实现二进制搜索方法。所以我需要一个排序数组。那么你认为我应该使用 CompareTo() 还是我自己的比较方法?
  • @Arnab 进行自定义字符串比较时要小心,除非您真的了解文化之间的差异(或者您使用单一文化)。字符比较(如您所见)非常具有误导性。
  • "Depends"... 无论如何,在比较 strings 时,您可能不希望使用 char 逻辑。问题是您希望它们如何 排序。它应该是文化意识的,还是文化独立的,还是字典独立的? String.CompareToString.CompareToOrdinal 是否像您想要的那样排序?然后使用这些,否则构建您自己的排序逻辑。 -- 你可能还想看看Compare with StringComparisonCompare with CultureInfo

标签: c# string-comparison


【解决方案1】:

此比较'-'.CompareTo('!') 将执行序数比较。它将比较数字 UTF-16 编码值(4533)。

字符串比较"-".CompareTo("!") 不同,它将执行文化感知比较。这意味着,无论数值如何,字符都将根据当前文化的排序规则进行排序。

您可以尝试使用字符串的序号比较:

String.CompareOrdinal("-", "!")

这将对字符串进行序数比较,然后您将得到相同的结果 (12)。

您无法对 Char 执行(真正的)文化感知比较(如果您需要它,只需将其转换为 string),因为排序顺序可能会受到您比较之前和/或之后的字符的影响, 单个字符可能不是字素(并且排序可能不适用)。一个例子:在捷克语中,C 出现在 H 之前,那么您期望 "ch".CompareTo("h") == -1...错误,“ch”是一个 digraph,它是在 HI 之间然后"ch".CompareTo("h") == 1!!!更多信息请访问this more detailed post

顺序比较是不同的,仅仅是因为 ASCII 的传统(我尝试的每种文化都返回了相同的排序结果)。它们保留了 ASCII 顺序以实现兼容性(以及更容易迁移到 Unicode),但对于字符串比较,它们必须遵守文化规则。

一个更常见的例子是使用大写/小写字符(注意 '" 执行序数和文化感知比较):

'A'.CompareTo('a') != "A".CompareTo("a")

如果您这样做是为了执行文本搜索,那么我强烈建议您不要直接使用 Char 比较,除非您了解文化问题(排序)和 Unicode 细节(代理和编码,主要)。

【讨论】:

    【解决方案2】:

    String 的 Compare 方法是特定于文化的。这就是为什么你会得到不同的结果。改用string.CompareOrdinal,这是逐字节比较的。

    var v = '-'.CompareTo('!');//12
    var s = string.CompareOrdinal("-", "!");//12
    

    Best Practices for Using Strings in the .NET Framework

    【讨论】:

    • 我正在实现字符串的二进制搜索方法。所以我需要一个排序数组。那么你使用 CompareTo() 会有什么问题还是我应该使用 CompareOrdinal ?
    • 这取决于您的结果需要如何,如果您需要与文化相关的比较,请使用CompareTo,还有其他选项可以比较,它们是InvariantCulture,并忽略它们的大小写变体。请参阅我提供的链接并选择最适合您的链接。
    【解决方案3】:

    这是由于 CharString 类中 IComparable 方法 CompareTo 的实现不同

    字符.cs

    public int CompareTo(Char value) {
          return (m_value-value);
    }
    

    字符串.cs

    public int CompareTo(String strB) {
        return CultureInfo.CurrentCulture.CompareInfo.Compare(this, strB, 0);
    }
    

    其中逻辑是文化感知比较,它依赖于内部InternalCompareString

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-07
      • 2013-05-06
      • 2014-01-30
      相关资源
      最近更新 更多