Come posso fare un confronto di stringhe senza distinzione tra maiuscole e minuscole?


217

Come posso rendere la riga sotto maiuscole e minuscole?

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

Oggi mi è stato dato qualche consiglio che mi ha suggerito di usare:

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

il problema è che non riesco a farlo funzionare, ho provato la riga qui sotto, questo compila ma restituisce i risultati sbagliati, restituisce gli utenti registrati come utenti non registrati e non registrati come iscritti.

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

Qualcuno può sottolineare il problema?


1
Quale tipo di dati dovrebbe drUser["Enrolled"]essere? Sembra un valore booleano, ma FindIndex()restituisce l'indice. Se l'indice di quell'utente è 0, restituirà 0, che potrebbe essere falso. Quando, in realtà è vero. Il Exists()metodo potrebbe essere migliore in questo caso.
drharris,

Sei sicuro che non ci sia tempo di formattazione o spazio extra in un campo che non sia nell'altro?
joshlrogers,

1
Suggerirei di usare registeredUsers.Any () invece di FindIndex (e test).
Marc,

Risposte:


405

Questa non è la migliore pratica in .NET framework (4 & +) per verificare l'uguaglianza

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

Utilizzare invece quanto segue

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

MSDN consiglia:

  • Utilizzare un sovraccarico del metodo String.Equals per verificare se due stringhe sono uguali.
  • Utilizzare i metodi String.Compare e String.CompareTo per ordinare le stringhe, non per verificare l'uguaglianza .

8
Dovresti usare string.Compare, no String.Compare.
Fred,

5
@Fred Sono d'accordo ma puoi qualificarne il motivo?
Gusdor,

22
@Fred Speravo per un motivo tecnico piuttosto che "perché lo dice Stylecop". Mi sto perdendo qualcosa?
Gusdor,

12
nessuna differenza string.compare con String.Compare, sinonimi stringa Classe System.String. e il confronto tra membri è un metodo di estensione. @ Fred @Gusdor
Nuri YILMAZ,

23
@Gusdor stringè una pratica migliore rispetto a Stringquando è una parola chiave della lingua. Per uno, Stringpotrebbe essere qualcosa di diverso da System.String, mentre stringnon può essere. Inoltre, stringè più o meno garantito che esista in C #, mentre Stringtecnicamente fa parte di .NET piuttosto che C #.
Dave Cousineau,

36

È necessario utilizzare la String.Comparefunzione statica come segue

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

6
No, dovresti usare String.Equalsinvece di String.Compare. Non è necessario calcolare quale è maggiore, solo che non sono uguali.
ErikE

@ErikE: Mi chiedo quale metodo raccomanderai di usare per altri 6 anni :-)
Oleg

3
Non mi chiedo! Sono fiducioso che consiglierò di usare l'uguaglianza quando si desidera la semantica dell'uguaglianza e di usare compare quando si desidera la semantica di confronto. Cosa c'è di così difficile? IEquatablee IComparableNON fare la stessa cosa, e puoi avere classi che implementano una ma in cui NON avrebbe senso implementare l'altra. Ad esempio, è possibile ordinare i campionamenti dei sensori per tempo senza che nessuno di essi sia uguale (IComparable). E puoi indicare se le cose sono uguali (IEquatable) ma non ha senso ordinarle (diciamo, numeri di serie del computer).
ErikE

@ErikE: non capisci il mio punto di vista. Le vecchie risposte corrispondono al tempo di scrittura. Non si devono toccare le vecchie risposte. È vero per la maggior parte dei prodotti. La migliore pratica o la migliore scelta dal punto di vista delle prestazioni può essere modificata più volte in seguito. Non ho senso discutere di qualsiasi vecchia risposta.
Oleg,

18
Mi scuso, l'ho preso come una critica sulla correttezza del mio commento. Se quello che stai dicendo è che ammetti che la tua vecchia risposta potrebbe non essere la migliore, allora fantastico! Tuttavia, non sono d'accordo con te riguardo alle vecchie risposte. Le vecchie risposte che forniscono informazioni di scarsa qualità dovrebbero essere commentate, dovrebbero essere sottovalutate, perché stanno ancora informando i lettori di oggi .
ErikE

27

Si prega di utilizzare questo per il confronto:

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

10
Basta essere consapevoli dei vantaggi e delle insidie ​​dell'utilizzo di CurrentCultureIgnoreCase rispetto a OrdinalIgnoreCase. Se non hai bisogno della semantica del confronto culturale, salva alcune prestazioni e usa il confronto ordinale.
ErikE

7

Altri rispondono qui sono totalmente validi, ma in qualche modo ci vuole un po 'di tempo per scrivere StringComparison.OrdinalIgnoreCasee usare String.Compare.

Ho codificato un semplice metodo di estensione String, in cui è possibile specificare se il confronto fa distinzione tra maiuscole e minuscole o insensato con booleano, allegando qui l'intero frammento di codice:

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

Dopo tutto questo confronto si accorcia di circa 10 caratteri - confronta:

Prima di utilizzare l'estensione String:

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

Dopo aver usato l'estensione String:

testFilename.CompareTo(testToStart, true)

2
Non sono d'accordo con la denominazione, il confronto è una funzione ben nota nello sviluppo di software e hai sostanzialmente cambiato ciò che fa. Penso che dovresti restituire un int come il confronto o cambiare il nome in qualcos'altro, ad esempio "IsEqual".
Fred,

7

È possibile (sebbene controverso) estendere System.Stringper fornire un metodo di estensione del confronto senza distinzione tra maiuscole e minuscole:

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

e utilizzare come tale:

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

C # ti consente di creare metodi di estensione che possono fungere da suggar di sintassi nel tuo progetto, direi piuttosto utile.

Non è la risposta e so che questa domanda è vecchia e risolta, volevo solo aggiungere questi bit.


3

Penso che troverai maggiori informazioni in questo link:

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

Utilizzare il metodo Confronta statico sulla classe String per confrontare le due stringhe. Se il confronto non fa distinzione tra maiuscole e minuscole è determinato dal terzo parametro di uno dei suoi sovraccarichi. Per esempio:

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

Il valore caseSensitiveResult è -1 (che indica che lowerCase è "minore di" upperCase) e caseInsensitiveResult è zero (che indica che lowerCase "è uguale a" upperCase).



1

Vorrei scrivere un metodo di estensione per EqualsIgnoreCase

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

-11

puoi sempre usare le funzioni: .ToLower (); .ToUpper ();

converti le tue stringhe e poi confrontale ...

In bocca al lupo


Non penso che questo risolva il suo problema. Segna anche che questa domanda ha già più di 4 anni.
Vojtěch Dohnal,

7
Questo crea una nuova stringa, quindi la ritengo molto inefficiente. Perché per creare questa nuova stringa tutti i caratteri verranno controllati e convertiti nel caso desiderato, quindi il confronto deve ricontrollare tutti i caratteri. Quindi utilizza più memoria e potenza di elaborazione.
Air2,

5
Questa è una cattiva pratica a causa dell'allocazione di memoria.
Thorbjørn Lindeijer,

Non solo questo è inutile allocazione della memoria e inefficiente; fallisce anche il test della Turchia .
Dmitry
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.