¿Cómo puedo hacer una comparación de cadenas sin distinción entre mayúsculas y minúsculas?

217

¿Cómo puedo hacer que la línea debajo de mayúsculas y minúsculas?

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

Hoy me dieron algunos consejos que sugirieron usar:

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

el problema es que no puedo hacer que esto funcione, probé la línea a continuación, esto compila pero devuelve los resultados incorrectos, devuelve a los usuarios inscritos como no inscritos y usuarios no inscritos como inscritos.

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

¿Alguien puede señalar el problema?

Jamie
fuente
1
¿Qué tipo de datos debería drUser["Enrolled"]ser? Parece un valor booleano, pero FindIndex()devuelve el índice. Si el índice de ese usuario es 0, devolverá 0, que puede ser falso. Cuando, en realidad es cierto. El Exists()método puede ser mejor en este caso.
drharris
¿Está seguro de que no hay tiempo de formateo o un espacio adicional en un campo que no está en el otro?
joshlrogers
1
Sugeriría usar enrolledUsers.Any () en lugar de FindIndex (y prueba).
Marc

Respuestas:

405

Esta no es la mejor práctica en .NET Framework (4 y +) para verificar la igualdad

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

Use lo siguiente en su lugar

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

MSDN recomienda:

  • Use una sobrecarga del método String.Equals para probar si dos cadenas son iguales.
  • Use los métodos String.Compare y String.CompareTo para ordenar las cadenas, no para verificar la igualdad .
ocean4dream
fuente
8
Deberías usar string.Compare, no String.Compare.
Fred
55
@Fred Estoy de acuerdo, pero ¿puedes calificar el motivo?
Gusdor
22
@Fred Esperaba por una razón técnica en lugar de "porque Stylecop lo dice". ¿Me estoy perdiendo de algo?
Gusdor
12
no hay diferencia string.compare con String.Compare, sinónimos de cadena de la clase System.String. y member Compare es un método de extensión. @ Fred @Gusdor
Nuri YILMAZ
23
@Gusdor stringes una mejor práctica que Stringya que es una palabra clave de lenguaje. Por un lado, Stringpodría ser algo más que System.String, mientras stringque no puede ser. Además, stringestá más o menos garantizado de existir en C #, mientras Stringque técnicamente es parte de .NET en lugar de C #.
Dave Cousineau
36

Debe usar la String.Comparefunción estática como la siguiente

x => String.Compare (x.Username, (string)drUser["Username"],
                     StringComparison.OrdinalIgnoreCase) == 0
Oleg
fuente
66
No, deberías usar en String.Equalslugar de String.Compare. No es necesario calcular cuál es mayor, solo que no son iguales.
ErikE
@ErikE: Me pregunto qué método recomendará usar en 6 años más :-)
Oleg
3
No me pregunto Estoy seguro de que recomendaré usar igualdad cuando desee semántica de igualdad, y usar comparar cuando desee semántica de comparación. ¿Qué tiene de difícil eso? IEquatabley IComparableNO hagas lo mismo, y puedes tener clases que implementen una, pero en las cuales NO tendría sentido implementar la otra. Por ejemplo, puede ordenar muestras de sensores por tiempo sin que ninguno de ellos sea igual (IComparable). Y puede indicar si las cosas son iguales (IEquatable) pero no tiene sentido ordenarlas (por ejemplo, números de serie de la computadora).
ErikE
@ErikE: No entiendes mi punto de vista. Las respuestas antiguas corresponden al momento de la escritura. Uno no debe tocar viejas respuestas. Es cierto sobre la mayoría de los productos. La mejor práctica o la mejor opción desde el punto de vista del rendimiento se puede cambiar varias veces más tarde. No tengo sentido discutir sobre ninguna vieja respuesta.
Oleg
18
Mis disculpas, lo tomé como una crítica sobre la exactitud de mi comentario. Si lo que estás diciendo es que admites que tu respuesta anterior puede no ser la mejor, ¡genial! Sin embargo, tengo que estar en desacuerdo con usted sobre viejas respuestas. Las viejas respuestas que brindan información deficiente deben comentarse, deben rechazarse, porque todavía están informando a los lectores de hoy .
ErikE
27

Utilice esto para comparar:

string.Equals(a, b, StringComparison.CurrentCultureIgnoreCase);
Gautam Kumar Sahu
fuente
10
Solo tenga en cuenta las ventajas y desventajas de usar CurrentCultureIgnoreCase vs. OrdinalIgnoreCase. Si no necesita la semántica de la comparación cultural, guarde algo de rendimiento y use la comparación ordinal.
ErikE
7

Las respuestas de otros son totalmente válidas aquí, pero de alguna manera lleva algún tiempo escribirlas StringComparison.OrdinalIgnoreCasey también usarlas String.Compare.

Codifiqué un método de extensión de cadena simple, donde podría especificar si la comparación distingue mayúsculas de minúsculas o mayúsculas y minúsculas con boolean, adjuntando el fragmento de código completo aquí:

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

Después de que toda la comparación se acorta en 10 caracteres aproximadamente, compare:

Antes de usar la extensión de cadena:

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

Después de usar la extensión de cadena:

testFilename.CompareTo(testToStart, true)
TarmoPikaro
fuente
2
No estoy de acuerdo con el nombre, compare es una función bien conocida en el desarrollo de software y ha cambiado fundamentalmente lo que hace. Creo que debería devolver un int como comparar o cambiar el nombre a otra cosa, 'IsEqual' por ejemplo.
Fred
7

Puede (aunque controvertido) extenderse System.Stringpara proporcionar un método de extensión de comparación sin distinción entre mayúsculas y minúsculas:

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

y usar como tal:

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

C # le permite crear métodos de extensión que pueden servir como sugerencia de sintaxis en su proyecto, bastante útil, diría yo.

No es la respuesta y sé que esta pregunta es antigua y está resuelta, solo quería agregar estos bits.

Felype
fuente
3

Creo que encontrará más información en este enlace:

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

Use el método Comparar estático en la clase Cadena para comparar las dos cadenas. El tercer parámetro de una de sus sobrecargas determina si la comparación no distingue entre mayúsculas y minúsculas. Por ejemplo:

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

El valor caseSensitiveResult es -1 (lo que indica que lowerCase es "menor que" upperCase) y caseInsensitiveResult es cero (lo que indica que lowerCase "es igual a" upperCase).

i_thamary
fuente
1

Me gustaría escribir un método de extensión para EqualsIgnoreCase

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

siempre puedes usar funciones: .ToLower (); .ToUpper ();

convierte tus cadenas y luego compáralas ...

Buena suerte

usuario3895427
fuente
No creo que esto resuelva su problema. También marque que esta pregunta ya tiene más de 4 años.
Vojtěch Dohnal
77
Esto crea una nueva cadena, por lo que considero que esto es muy ineficiente. Debido a que para crear esta nueva cadena todos los caracteres serán verificados y convertidos al caso deseado, entonces la comparación debe verificar todos los caracteres nuevamente. Por lo tanto, utiliza más memoria y potencia de procesamiento.
Air2
55
Esta es una práctica muy mala debido a la asignación de memoria.
Thorbjørn Lindeijer
No solo es una asignación de memoria innecesaria e ineficiente; También falla la prueba de Turquía .
dmitry