Saltar al contenido

Cómo hacer que la declaración de cambio de C# use IgnoreCase

Basta ya de investigar por internet porque has llegado al lugar perfecto, contamos con la respuesta que deseas pero sin complicaciones.

Solución:

Un enfoque más simple es simplemente poner en minúsculas su string antes de que entre en la declaración de cambio, y tenga los casos más bajos.

En realidad, la parte superior es un poco mejor desde el punto de vista de un rendimiento de nanosegundos extremo puro, pero menos natural a la vista.

P.ej:

string s = "house"; 
switch (s.ToLower())  
  case "house": 
    s = "window"; 
    break;

Como parece saber, poner dos cadenas en minúsculas y compararlas no es lo mismo que hacer una comparación de ignorar mayúsculas y minúsculas. Hay muchas razones para esto. Por ejemplo, el estándar Unicode permite que el texto con signos diacríticos se codifique de varias formas. Algunos caracteres incluyen tanto el carácter base como el diacrítico en un solo punto de código. Estos caracteres también se pueden representar como el carácter base seguido de un carácter diacrítico combinado. Estas dos representaciones son iguales a todos los efectos, y la conciencia cultural string las comparaciones en .NET Framework los identificarán correctamente como iguales, ya sea con CurrentCulture o InvariantCulture (con o sin IgnoreCase). Una comparación ordinal, por otro lado, los considerará incorrectamente como desiguales.

Desafortunadamente, switch no hace nada más que una comparación ordinal. Una comparación ordinal está bien para ciertos tipos de aplicaciones, como analizar un archivo ASCII con códigos rígidamente definidos, pero ordinal string la comparación es incorrecta para la mayoría de los otros usos.

Lo que he hecho en el pasado para obtener el comportamiento correcto es simplemente simular mi propia declaración de cambio. Hay muchas formas de hacer esto. Una forma sería crear un List de pares de cadenas de casos y delegados. La lista se puede buscar utilizando el string comparación. Cuando se encuentra la coincidencia, se puede invocar al delegado asociado.

Otra opción es hacer la cadena obvia de if declaraciones. Por lo general, esto no resulta tan malo como parece, ya que la estructura es muy regular.

Lo mejor de esto es que realmente no hay ninguna penalización de rendimiento al simular su propia funcionalidad de interruptor cuando se compara con cadenas. El sistema no va a hacer una tabla de saltos O(1) de la forma en que lo hace con números enteros, por lo que va a comparar cada string uno a la vez de todos modos.

Si hay muchos casos para comparar, y el rendimiento es un problema, entonces el List La opción descrita anteriormente podría reemplazarse con un diccionario ordenado o una tabla hash. Entonces, el rendimiento puede potencialmente igualar o superar la opción de declaración de cambio.

Aquí hay un ejemplo de la lista de delegados:

delegate void CustomSwitchDestination();
List> customSwitchList;
CustomSwitchDestination defaultSwitchDestination = new CustomSwitchDestination(NoMatchFound);
void CustomSwitch(string value)

    foreach (var switchOption in customSwitchList)
        if (switchOption.Key.Equals(value, StringComparison.InvariantCultureIgnoreCase))
        
            switchOption.Value.Invoke();
            return;
        
    defaultSwitchDestination.Invoke();

Por supuesto, probablemente desee agregar algunos parámetros estándar y posiblemente un tipo de retorno al delegado CustomSwitchDestination. ¡Y querrás hacer mejores nombres!

Si el comportamiento de cada uno de sus casos no es susceptible de delegar la invocación de esta manera, como si se necesitan diferentes parámetros, entonces está atascado con encadenado if declaraciones También he hecho esto un par de veces.

    if (s.Equals("house", StringComparison.InvariantCultureIgnoreCase))
    
        s = "window";
    
    else if (s.Equals("business", StringComparison.InvariantCultureIgnoreCase))
    
        s = "really big window";
    
    else if (s.Equals("school", StringComparison.InvariantCultureIgnoreCase))
    
        s = "broken window";
    

Perdón por esta nueva publicación a una pregunta anterior, pero hay una nueva opción para resolver este problema usando C# 7 (VS 2017).

C# 7 ahora ofrece “coincidencia de patrones” y se puede utilizar para abordar este problema de la siguiente manera:

string houseName = "house";  // value to be tested, ignoring case
string windowName;   // switch block will set value here

switch (true)

    case bool b when houseName.Equals("MyHouse", StringComparison.InvariantCultureIgnoreCase): 
        windowName = "MyWindow";
        break;
    case bool b when houseName.Equals("YourHouse", StringComparison.InvariantCultureIgnoreCase): 
        windowName = "YourWindow";
        break;
    case bool b when houseName.Equals("House", StringComparison.InvariantCultureIgnoreCase): 
        windowName = "Window";
        break;
    default:
        windowName = null;
        break;

Esta solución también trata el problema mencionado en la respuesta de @Jeffrey L Whitledge de que la comparación de cadenas que no distingue entre mayúsculas y minúsculas no es lo mismo que comparar dos cadenas en minúsculas.

Por cierto, hubo un artículo interesante en febrero de 2017 en la revista Visual Studio que describe la coincidencia de patrones y cómo se puede usar en bloques de casos. Eche un vistazo: Coincidencia de patrones en C# 7.0 Case Blocks

EDITAR

A la luz de la respuesta de @LewisM, es importante señalar que el switch declaración tiene un comportamiento nuevo e interesante. Eso es que si tu case declaración contiene una declaración de variable, entonces el valor especificado en el switch parte se copia en la variable declarada en el case. En el siguiente ejemplo, el valor true se copia en la variable local b. Además de eso, la variable b no se usa, y existe sólo para que el when cláusula a la case declaración puede existir:

switch(true)

    case bool b when houseName.Equals("X", StringComparison.InvariantCultureIgnoreCase):
        windowName = "X-Window";):
        break;

Como señala @LewisM, esto se puede usar para beneficiar, ese beneficio es que lo que se compara está realmente en el switch afirmación, como ocurre con el uso clásico de la switch declaración. Asimismo, los valores temporales declarados en el case declaración puede evitar cambios no deseados o involuntarios en el valor original:

switch(houseName)

    case string hn when hn.Equals("X", StringComparison.InvariantCultureIgnoreCase):
        windowName = "X-Window";
        break;

Sección de Reseñas y Valoraciones

Agradecemos que desees auxiliar nuestro ensayo añadiendo un comentario o puntuándolo te damos las gracias.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *