【问题标题】:Possible to create case insensitive string class?可以创建不区分大小写的字符串类吗?
【发布时间】:2015-08-21 17:24:45
【问题描述】:

创建一个不区分大小写的字符串类型需要什么?

我从未听说过有人制作这样不区分大小写的字符串类型,而且它显然不是框架的一部分,但它似乎非常有用。 SQL 默认进行不区分大小写的比较这一事实就是一个很好的例子。所以我认为这要么是不可能的,要么是有一个真的很好的理由说明为什么没有人这样做我不知道。

我知道它需要使用隐式运算符进行赋值,并且您必须覆盖等于运算符。而对于覆盖 GetHashCode(),我想你可以只返回 ToLower().GetHashCode()。

我错过了什么?

【问题讨论】:

  • 你应该看看这个字符串比较。 msdn.microsoft.com/en-us/library/e6883c06(v=vs.110).aspx
  • @deathismyfriend 过去我只需要在这里或那里的某个地方执行此操作,但现在我正在开发一个数据上传工具,我确实需要它在任何地方都不区分大小写。如果可能的话,拥有一种实际以这种方式工作而不是使用实用方法的类型会更棒。但我同意这是目前我所知道的最好的处理方式。
  • @EZI 但是,难道没有一千个永远“不需要”解决的 XY 问题,而是因为它使代码更清晰,整个编程体验更好。
  • 在您提出实际问题之前,您不知道没有更清洁的解决方案。 SQL 是一个怎样的例子? SQL just a 有不同的默认值。 SQL 对于不区分大小写的 char 没有单独的数据类型。为什么不尝试那些你知道它需要的东西。

标签: c# .net string class case-insensitive


【解决方案1】:

它的行为不会“完全像一个字符串”。 string 类型很特殊,并且被纳入语言规范。 C# 字符串表现出特殊的行为,例如

  • 作为 reference 类型,按值传递。引用类型通常通过...好吧...引用传递。

  • 默认情况下是实习。这意味着给定字符串只有一个实例。以下代码只创建了一个字符串:abc 都指向字符串 quick 的完全相同的实例。这意味着在比较任意两个时Object.ReferenceEquals() 为真:

    string a = "The quick brown dog...".Substring(4,5) ;
    string b = new string(new char[]{'q','u','i','c','k'});
    string c = new StringBuilder().
               .Append('q')
               .Append('u')
               .Append('i')
               .Append('c')
               .Append('k')
               .ToString()
               ;
    

[编辑注释:虽然有人可能认为这应该是可能的,但稍微摆弄一下表明实际上无法创建自定义实现/CompareInfo 的子类型,因为它没有公共构造函数,其默认构造函数是internal。更多关于这个问题的答案:Globally set String.Compare/ CompareInfo.Compare to Ordinal

咕噜……]

可以做的是这样的:

字符串比较是使用当前区域性的排序规则/比较规则完成的。为您的应用创建自定义文化,例如,使用您需要的排序规则/比较规则的美国文化副本。将其设置为当前文化和 Bob 的叔叔。

您仍然会收到编译器/ReSharper 的抱怨,因为您在没有指定所需的比较语义的情况下进行字符串比较,但您的代码将是干净的。

更多详情,请参阅

【讨论】:

  • 谢谢,我想我实际上不会担心它在内存管理方面的表现相同;但显然,按值传递的部分很重要。
  • AFAIK 您的特殊字符串行为示例不正确。 1. 所有 C# 类型在不带修饰符的情况下按值传递,而不仅仅是字符串(参见C# spec v.5 10.6.1.1 节或msdn:Passing Reference-Type Parameters (C# Programming Guide))。 2.您的示例字符串abc,在将任何两个与ReferenceEquals进行比较时返回false。此外,他们都没有被实习,您可以通过运行例如检查。 ReferenceEquals(a, string.IsInterned(a)).
【解决方案2】:

比较字符串相当容易。您可以简单地使用 equals 方法或 compare 方法。

例子:

string s = "A";
s.Equals("a", StringComparison.InvariantCultureIgnoreCase); // Will return true.

string s = "A";
s.Equals("a", StringComparison.InvariantCulture); // Will return false.

您还应该查看this。这将解释更多关于比较字符串的内容。

【讨论】:

  • 谢谢。我确实知道如何进行不区分大小写的字符串比较。我想要一个内置了这个特性的类型,这样我的代码看起来更干净。
  • 您可以随时添加扩展方法,但我只会使用上面的等号。
【解决方案3】:

基于上面deathismyfriend的回答类型,我将扩展字符串类:

public static class StringExtensions
{
    public static int CaseInsensitveCompare(this string s, string stringToCompare)
    {
        return String.Compare(s, stringToCompare, StringComparison.InvariantCultureIgnoreCase);
    }
}

然后打电话:

int result = firstString.CaseInsensitveCompare(secondString);

【讨论】:

  • 是的,这可能是最实用的解决方案。
  • 很高兴为您提供帮助。如果这满足您的需求,请标记为答案。
  • 丹,他在原始问题中要求的内容无法完成。这里的所有答案都是替代解决方案。我的回答会给你一种方法来进行不区分大小写的比较。告诉我,为什么我需要在“int result = s1.CaseInsensitveCompare(s2);”上做“if (s1 == s2)” ?但是在这里的每一个答案中,你都会来我的答案并投反对票?为什么老兄?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-11-22
  • 2016-01-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多