如何进行不区分大小写的字符串比较?


217

如何使下面的行不区分大小写?

drUser["Enrolled"] = 
      (enrolledUsers.FindIndex(x => x.Username == (string)drUser["Username"]) != -1);

今天早些时候给我一些建议,建议我使用:

x.Username.Equals((string)drUser["Username"], StringComparison.OrdinalIgnoreCase)));

问题是我无法使用它,我尝试了下面的代码行,虽然编译但返回了错误的结果,它使已注册用户返回为未注册,未注册用户返回为已注册。

drUser["Enrolled"] = 
      (enrolledUsers.FindIndex(x => x.Username.Equals((string)drUser["Username"], 
                                 StringComparison.OrdinalIgnoreCase)));

谁能指出这个问题?


1
什么数据类型应该drUser["Enrolled"]是?它看起来像一个布尔值,但FindIndex()返回索引。如果该用户的索引为0,则它​​将返回0,这可能为false。何时,实际上是真的。Exists()在这种情况下,该方法可能更好。
drharris 2010年

您确定一个字段中没有格式化时间或一个字段中没有多余的空间吗?
joshlrogers

1
我建议使用enrolledUsers.Any()代替FindIndex(和测试)。
Marc 2010年

Answers:


405

这不是.NET Framework(4&+)中检查相等性的最佳实践

String.Compare(x.Username, (string)drUser["Username"], 
                  StringComparison.OrdinalIgnoreCase) == 0

使用以下内容代替

String.Equals(x.Username, (string)drUser["Username"], 
                   StringComparison.OrdinalIgnoreCase) 

MSDN建议:

  • 使用String.Equals方法的重载来测试两个字符串是否相等。
  • 使用String.CompareString.CompareTo 方法对字符串进行排序,而不是检查是否相等

8
您应该使用string.Compare,而不是String.Compare
弗雷德(Fred)

5
@Fred我同意,但您可以限定原因吗?
古斯多

22
@Fred我之所以希望是出于技术原因,而不是因为“ Stylecop这样说”。我想念什么吗?
古斯多

12
string.compare与String.Compare没有区别,字符串同义词为System.String类。和成员Compare是一种扩展方法。@ Fred @Gusdor
Nuri

23
与@Gusdor string相比String,它是一种更好的做法,因为它是一个语言关键字。对于一个,String可能不是System.String,而是string不能。而且,string或多或少可以保证C#中存在,而String从技术上讲,它是.NET而不是C#的一部分。
Dave Cousineau

36

您应该使用静态String.Compare函数,如下所示

x => String.Compare (x.Username, (string)drUser["Username"],
                     StringComparison.OrdinalIgnoreCase) == 0

6
不,您应该使用String.Equals代替String.Compare。无需计算哪个更大,只要它们不相等即可。
ErikE '16

@ErikE:我很好奇,您建议在6年后再使用哪种方法:-)
Oleg

3
我不奇怪!我相信我会建议您在需要相等语义时使用相等,并在需要比较语义时使用compare。那有什么困难呢?IEquatable并且IComparable不要做同样的事情,您可以拥有实现一个类的类,但是实现另一个类是没有意义的。例如,您可以按时间排序传感器采样,而没有一个采样值相等(IComparable)。并且,您可以指示事物是否相等(IEquatable),但是对它们进行排序(例如,计算机序列号)是没有意义的。
ErikE

@ErikE:你不理解我的观点。旧答案对应撰写本文的时间。一个人不应该碰旧的答案。大多数产品都是如此。从性能的角度来看,最佳实践或最佳选择可以在以后多次更改。我认为讨论任何旧答案毫无意义。
Oleg

18
抱歉,我认为这是对我评论的正确性的批评。如果您要说的是您承认您的旧答案可能不是最佳答案,那就太好了!但是,对于旧的答案,我必须不同意。那些提供不良信息的旧答案应该被评论,应该被否决,因为它们仍在通知当今的读者。
ErikE


7

其他答案在这里是完全有效的,但是以某种方式键入StringComparison.OrdinalIgnoreCase和使用也需要一些时间String.Compare

我已经编写了简单的String扩展方法,您可以在其中指定比较是区分大小写还是不区分大小写,并在其中附加整个代码段:

using System;

/// <summary>
/// String helpers.
/// </summary>
public static class StringExtensions
{
    /// <summary>
    /// Compares two strings, set ignoreCase to true to ignore case comparison ('A' == 'a')
    /// </summary>
    public static bool CompareTo(this string strA, string strB, bool ignoreCase)
    {
        return String.Compare(strA, strB, ignoreCase) == 0;
    }
}

之后,整个比较大约缩短10个字符-比较:

使用字符串扩展之前:

String.Compare(testFilename, testToStart,true) != 0

使用字符串扩展名后:

testFilename.CompareTo(testToStart, true)

2
我不同意命名,compare是软件开发人员中众所周知的功能,您已经从根本上改变了它的功能。我认为您应该返回一个如compare的int或将名称更改为其他名称,例如“ IsEqual”。
弗雷德(Fred)

7

您可以(尽管有争议)进行扩展System.String以提供不区分大小写的比较扩展方法:

public static bool CIEquals(this String a, String b) {
    return a.Equals(b, StringComparison.CurrentCultureIgnoreCase);
}

并这样使用:

x.Username.CIEquals((string)drUser["Username"]);

C#允许您创建扩展方法,这些扩展方法可以在项目中用作语法建议,我想说这很有用。

这不是答案,我知道这个问题已经解决了,我只想添加这些内容。


3

我想您会在此链接中找到更多信息:

http://codeidol.com/community/dotnet/controlling-case-sensitivity-when-comparing-two-st/8873/

在String类上使用Compare静态方法比较两个字符串。比较是否区分大小写由其重载之一的第三个参数确定。例如:

string lowerCase = "abc";
string upperCase = "AbC";
int caseInsensitiveResult = string.Compare(lowerCase, upperCase,
  StringComparison.CurrentCultureIgnoreCase);
int caseSensitiveResult = string.Compare(lowerCase,
  StringComparison.CurrentCulture);

caseSensitiveResult值是-1(指示lowerCase“小于” upperCase),而caseInsensitiveResult是零(指示lowerCase“等于” upperCase)。



1

我想为EqualsIgnoreCase写一个扩展方法

public static class StringExtensions
{
    public static bool? EqualsIgnoreCase(this string strA, string strB)
    {
        return strA?.Equals(strB, StringComparison.CurrentCultureIgnoreCase);
    }
}

-11

您可以随时使用以下函数:.ToLower(); .ToUpper();

转换您的字符串,然后比较它们...

祝好运


我认为这不会解决他的问题。还请注意,这个问题已经存在了4年以上。
Vojtěch多纳尔

7
这将创建一个新字符串,因此我认为这效率很低。因为要创建此新字符串,将检查所有字符并将其转换为所需的大小写,因此比较器必须再次检查所有字符。因此,它使用更多的内存和处理能力。
Air2 2014年

5
由于内存分配,这是非常不好的做法。
托尔比约恩Lindeijer

这不仅是不必要的内存分配,而且效率低下。它也没有通过土耳其测试
德米特里
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.