c# - found - ¿Cuál es la forma correcta de comparar el caso de char ignorando?
if string== string c# (7)
Me pregunto cuál es la forma correcta de comparar dos personajes ignorando el caso que funcionará para todas las culturas. Además, es Comparer<char>.Default
la mejor manera de probar dos personajes sin ignorar el caso? ¿Esto funciona para parejas sustitutas?
EDITAR : Se IComparer<char>
implementación de la muestra IComparer<char>
Si esto ayuda a alguien, esto es lo que he decidido usar
public class CaseInsensitiveCharComparer : IComparer<char> {
private readonly System.Globalization.CultureInfo ci;
public CaseInsensitiveCharComparer(System.Globalization.CultureInfo ci) {
this.ci = ci;
}
public CaseInsensitiveCharComparer()
: this(System.Globalization.CultureInfo.CurrentCulture) { }
public int Compare(char x, char y) {
return Char.ToUpper(x, ci) - Char.ToUpper(y, ci);
}
}
// Prints 3
Console.WriteLine("This is a test".CountChars(''t'', new CaseInsensitiveCharComparer()));
Depende de lo que quiere decir con "trabajo para todas las culturas". ¿Le gustaría que "yo" y "yo" sean iguales incluso en Turquía?
Podrías usar:
bool equal = char.ToUpperInvariant(x) == char.ToUpperInvariant(y);
... pero no estoy seguro de si eso "funciona" de acuerdo con todas las culturas por su comprensión de "obras".
Por supuesto, puede convertir ambos caracteres en cadenas y luego realizar la comparación que desee en las cadenas. Algo menos eficiente, pero te da todo el rango de comparaciones disponibles en el marco:
bool equal = x.ToString().Equals(y.ToString(),
StringComparison.InvariantCultureIgnoreCase);
Para parejas sustitutas, un Comparer<char>
no va a ser factible de todos modos, porque no tiene un solo char
. Sin embargo, podría crear un Comparer<int>
.
Lo que estaba pensando que estaría disponible dentro del tiempo de ejecución es algo como lo siguiente
public class CaseInsensitiveCharComparer : IComparer<char> {
private readonly System.Globalization.CultureInfo ci;
public CaseInsensitiveCharComparer(System.Globalization.CultureInfo ci) {
this.ci = ci;
}
public CaseInsensitiveCharComparer()
: this(System.Globalization.CultureInfo.CurrentCulture) { }
public int Compare(char x, char y) {
return Char.ToUpper(x, ci) - Char.ToUpper(y, ci);
}
}
// Prints 3
Console.WriteLine("This is a test".CountChars(''t'', new CaseInsensitiveCharComparer()));
Recomendaría comparar mayúsculas, y si no coinciden, comparando minúsculas, en caso de que la lógica de mayúsculas y minúsculas de la configuración regional se comporte ligeramente diferente.
Apéndice
Por ejemplo,
int CompareChar(char c1, char c2)
{
int dif;
dif = char.ToUpper(c1) - char.ToUpper(c2);
if (diff != 0)
dif = char.ToLower(c1) - char.ToLower(c2);
return dif;
}
Según entiendo, no hay realmente una manera que "funcione para todas las culturas". O desea comparar caracteres para algún tipo de razón interna, que no se muestra al usuario (en cuyo caso debe usar InvariantCulture), o si desea usar CurrentCulture del usuario. Obviamente, usar la cultura actual del usuario significa que obtendrás resultados diferentes en diferentes configuraciones regionales, pero serán coherentes con lo que tus usuarios esperarán en esos entornos.
Sin saber más acerca de POR QUÉ estás comparando dos personajes, realmente no puedo aconsejarte cuál debes usar.
Tu podrías intentar:
class Test{
static int Compare(char t, char p){
return string.Compare(t.ToString(), p.ToString(), StringComparison.CurrentCultureIgnoreCase);
}
}
Pero dudo que esta sea la forma "óptima" de hacerlo, pero no soy el caso que debes verificar ...
Usando la cultura por defecto (que no es invariante):
if (char.ToLower(ch1) == char.ToLower(ch2))
{ .... }
O especifica una cultura:
CultureInfo myCulture = ...;
if (char.ToLower(ch1, myCulture) == char.ToLower(ch2, myCulture))
{ .... }
string.Compare ("string a", "STRING A", true)
Funcionará para cada cuerda