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?

Jamie
fonte
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 .
ocean4dream
fonte
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
Oleg
fonte
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);
Gautam Kumar Sahu
fonte
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)
TarmoPikaro
fonte
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.

Felype
fonte
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)).

i_thamary
fonte
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);
    }
}
Ranga
fonte
-11

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

converta suas cordas e compare-as ...

Boa sorte

user3895427
fonte
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