Como posso fazer uma comparação de cadeias sem distinção entre maiúsculas e minúsculas?


217

Como faço para que a linha abaixo não diferencie maiúsculas de minúsculas?

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

Hoje recebi alguns conselhos que sugeriam o uso de:

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

o problema é que não consigo fazer isso funcionar, tentei a linha abaixo, compila, mas retorna os resultados errados, retorna usuários inscritos como não inscritos e usuários não inscritos como inscritos.

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

Alguém pode apontar o problema?


1
Que tipo de dados deve drUser["Enrolled"]ser? Parece um valor booleano, mas FindIndex()retorna o índice. Se o índice desse usuário for 0, ele retornará 0, o que pode ser falso. Quando, na realidade, é verdade. O Exists()método pode ser melhor neste caso.
— drharris

Tem certeza de que não há tempo de formatação ou espaço extra em um campo que não está no outro?
— joshlrogers

1
Eu sugeriria o uso de registeredUsers.Any () em vez de FindIndex (e teste).
— Marc

Respostas:


405

Esta não é a melhor prática no .NET framework (4 e +) para verificar a igualdade

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

Use o seguinte

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

O MSDN recomenda:

  • Use uma sobrecarga do método String.Equals para testar se duas seqüências são iguais.
  • Use as String.Compare e String.CompareTo métodos para classificar cordas, não para verificar se há igualdade .

8
Você deveria usar string.Compare, não String.Compare.
— Fred

5
@ Fred Concordo, mas você pode qualificar o motivo?
— Gusdor 21/05

22
@ Fred Eu estava esperando por uma razão técnica, e não "porque a Stylecop diz isso". Estou esquecendo de algo?
— Gusdor

12
nenhuma diferença string.compare com String.Compare, sinônimos de string classe System.String. e membro Compare é um método de extensão. @ Fred @Gusdor
— Nuri YILMAZ

23
O @Gusdor stringé uma prática melhor do Stringque é uma palavra-chave no idioma. Por um lado, Stringpoderia ser algo diferente de System.String, enquanto stringnão pode ser. Além disso, stringé mais ou menos garantido que exista em C #, enquanto Stringé tecnicamente parte do .NET em vez de C #.
— Dave Cousineau

36

Você deve usar a String.Comparefunção estática como a seguir

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

6
Não, você deve usar em String.Equalsvez de String.Compare. Não há necessidade de calcular qual é o maior, apenas que eles não são iguais.
— ErikE 01/12/19

@ErikE: Eu sou maravilha, qual o método que irá recomendar para usar em 6 anos mais :-)
— Oleg

3
Eu não me pergunto! Tenho certeza de que recomendo o uso da igualdade quando você quiser a semântica da igualdade e o uso da comparação quando quiser a semântica da comparação. O que há de tão difícil nisso? IEquatablee IComparableNÃO faça a mesma coisa, e você pode ter classes que implementam uma, mas nas quais não faria sentido implementar a outra. Por exemplo, você pode solicitar amostragens de sensores por tempo sem que nenhuma delas seja igual (IComparable). E você pode indicar se as coisas são iguais (IEquatable), mas não faz sentido encomendá-las (por exemplo, números de série do computador).
— ErikE

@ErikE: Você não entende meu ponto de vista. Respostas antigas correspondem ao tempo de escrita. Não se deve tocar em respostas antigas. É verdade sobre a maioria dos produtos. A melhor prática ou a melhor escolha do ponto de vista do desempenho pode ser alterada várias vezes depois. Não vejo sentido discutir sobre qualquer resposta antiga.
— Oleg

18
Minhas desculpas, tomei isso como uma crítica à correção do meu comentário. Se o que você está dizendo é que admite que sua resposta antiga pode não ser a melhor, então é ótimo! No entanto, tenho que discordar de você sobre respostas antigas. Respostas antigas que fornecem informações precárias devem ser comentadas, devem ter votos negativos, porque ainda estão informando os leitores de hoje .
— ErikE

27

Por favor, use isso para comparação:

string.Equals(a, b, StringComparison.CurrentCultureIgnoreCase);

10
Esteja ciente das vantagens e armadilhas do uso do CurrentCultureIgnoreCase vs. OrdinalIgnoreCase. Se você não precisar da semântica da comparação de culturas, salve algum desempenho e use a comparação ordinal.
— ErikE 01/12/19

7

Outras respostas são totalmente válidas aqui, mas, de alguma forma, leva algum tempo para digitar StringComparison.OrdinalIgnoreCasee também usar String.Compare.

Eu codifiquei o método simples de extensão String, onde você pode especificar se a comparação diferencia maiúsculas de minúsculas ou sem maiúsculas e minúsculas com booleano, anexando um trecho de código inteiro aqui:

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;
    }
}

Após toda essa comparação, diminui aproximadamente 10 caracteres - compare:

Antes de usar a extensão String:

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

Depois de usar a extensão String:

testFilename.CompareTo(testToStart, true)

2
Não concordo com o nome, compare é uma função bem conhecida no desenvolvimento de software e você mudou fundamentalmente o que faz. Eu acho que você deve retornar um int como comparar ou alterar o nome para outra coisa, 'IsEqual' por exemplo.
— Fred

7

Você pode (embora polêmico) estender System.Stringpara fornecer um método de extensão de comparação sem distinção entre maiúsculas e minúsculas:

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

e use como tal:

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

O C # permite que você crie métodos de extensão que podem servir como sugadores de sintaxe em seu projeto, bastante útil, eu diria.

Não é a resposta e eu sei que esta pergunta é antiga e resolvida, eu só queria adicionar esses bits.


3

Eu acho que você encontrará mais informações neste link:

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

Use o método estático Compare na classe String para comparar as duas seqüências. Se a comparação não diferencia maiúsculas de minúsculas é determinada pelo terceiro parâmetro de uma de suas sobrecargas. Por exemplo:

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

O valor caseSensitiveResult é -1 (indicando que lowerCase é "menor que" upperCase) e o caseInsensitiveResult é zero (indicando que lowerCase "é igual a" upperCase)).



1

Eu gostaria de escrever um método de extensão para EqualsIgnoreCase

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

-11

você sempre pode usar funções: .ToLower (); .ToUpper ();

converta suas cordas e compare-as ...

Boa sorte


Eu não acho que isso resolveria o problema dele. Marque também que esta pergunta já tem mais de 4 anos.
— Vojtěch Dohnal

7
Isso cria uma nova string, então considero isso muito ineficiente. Como para criar essa nova sequência, todos os caracteres serão verificados e convertidos para o caso desejado, e a comparação deverá verificar todos os caracteres novamente. Portanto, ele usa mais memória e poder de processamento.
— Ar2

5
Essa é uma prática muito ruim por causa da alocação de memória.
— Thorbjørn Lindeijer

Não apenas isso é alocação de memória desnecessária e ineficiente; também falha no teste da Turquia .
— Dmitry
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.