Cadena de mayúsculas y minúsculas de C# que comienza con


¿Hay alguna manera de hacer una condición case en una instrucción switch donde se dice si una cadena comienza con algo?

Ex

Switch (mystring)
{
   case("abc")://String begins with abc (abcd or abc1 or abcz or abc.. or abc will fall in this condition).
      //Do Something
      break;
   default:
      break;
}

ACTUALIZACIÓN Otras cuerdas pueden tener una longitud diferente.

Abc..

Abczyv

Dcs2.

Qwerty

As...k

Author: Amra, 2010-10-04

6 answers

Si supieras que la longitud de las condiciones que te importarían sería la misma longitud entonces podrías:

switch(mystring.substring(0, Math.Min(3, mystring.Length))
{
  case "abc":
    //do something
    break;
  case "xyz":
    //do something else
    break;
  default:
    //do a different thing
    break;
}

El Math.Min(3, mystring.Length) está allí para que una cadena de menos de 3 caracteres no arroje una excepción en la operación de sub-cadena.

Hay extensiones de esta técnica para hacer coincidir, por ejemplo, un grupo de cadenas de 2 caracteres y un grupo de cadenas de 3 caracteres, donde algunas comparaciones de 2 caracteres coincidentes son seguidas por comparaciones de 3 caracteres. A menos que tenga un gran número de tales cadenas sin embargo, rápidamente se vuelve menos eficiente que el simple encadenamiento if-else tanto para el código en ejecución como para la persona que tiene que mantenerlo.

Edit: Añadido desde que has declarado que serán de diferentes longitudes. Podrías hacer el patrón que mencioné de verificar los primeros caracteres X y luego los siguientes caracteres Y, etc., pero a menos que haya un patrón donde la mayoría de las cadenas tengan la misma longitud, esto será ineficiente y horrible de mantener (un caso clásico de prematuridad pesimismo).

El patrón de comando se menciona en otra respuesta, así que no daré detalles de eso, como es que donde mapeas patrones de cadena a IDs, pero son opción.

No cambiaría de cadenas if-else a patrones de comando o mapeo para obtener el interruptor de eficiencia a veces tiene sobre if-else, ya que se pierde más en las comparaciones para el comando u obtener el patrón ID. Aunque lo haría si hiciera el código más claro.

Una cadena de la lata de if-else funciona bastante bien, ya sea con comparaciones de cadenas o con expresiones regulares (esta última si tienes comparaciones más complicadas que las coincidencias de prefijo hasta ahora, lo que probablemente sería más simple y rápido, estoy mencionando reg-ex solo porque a veces funcionan bien con casos más generales de este tipo de patrón).

Si opta por if-elses, trate de considerar qué casos van a suceder con mayor frecuencia, y haga que esas pruebas sucedan antes que las de los casos menos comunes (aunque, por supuesto si " comienza con abcd "es un caso a buscar tendría que ser comprobado antes de"comienza con abc").

 33
Author: Jon Hanna,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-10-04 09:15:21

Respuesta corta: No.

La instrucción switch toma una expresión que solo se evalúa una vez. Basado en el resultado, se ejecuta otra pieza de código.

¿Y qué? => Cadena.StartsWith es una función. Junto con un parámetro dado, es una expresión. Sin embargo, para su caso necesita pasar un parámetro diferente para cada caso, por lo que no se puede evaluar solo una vez.

La respuesta larga #1 ha sido dada por otros.

Respuesta larga # 2:

Dependiendo de lo que usted está tratando de lograr, usted podría estar interesado en el Patrón de Comandos/Patrón de cadena de responsabilidad. Aplicado a su caso, cada pieza de código estaría representada por una implementación de un Comando . Además del método execute, el comando puede proporcionar un método booleano Accept, que comprueba si la cadena dada comienza con el parámetro respectivo.

Ventaja: En lugar de su interruptor codificado declaración, codificado StartsWith evaluaciones y codificado cadenas, tendría mucha más flexibilidad.

El ejemplo que diste en tu pregunta se vería así:

var commandList = new List<Command>() { new MyABCCommand() };

foreach (Command c in commandList)
{
    if (c.Accept(mystring))
    {
        c.Execute(mystring);
        break;
    }
}

class MyABCCommand : Command
{
    override bool Accept(string mystring)
    {
        return mystring.StartsWith("abc");
    }
}    
 13
Author: chiccodoro,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-10-11 12:56:47

Si todos los casos tienen la misma longitud puede utilizar
switch (mystring.SubString(0,Math.Min(len, mystring.Length))).
Otra opción es tener una función que devuelva CategoryID basado en la cadena y cambie el id.

 5
Author: Itay Karo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-10-04 08:48:07

Si el dominio del problema tiene algún tipo de concepto de encabezado de cadena, esto podría modelarse como una enumeración.

switch(GetStringHeader(s))
{
    case StringHeader.ABC: ...
    case StringHeader.QWERTY: ...
    ...
}

StringHeader GetStringHeader(string s)
{
    if (s.StartsWith("ABC")) return StringHeader.ABC;
    ...
}

enum StringHeader { ABC, QWERTY, ... }
 3
Author: Felix Ungman,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-10-04 09:23:04

Además de substring answer, puedes hacerlo como mystring.SubCadena (0,3) y comprobar en la instrucción case si es "abc".

Pero antes de la instrucción switch, debe asegurarse de que su mystring tenga al menos 3 de longitud.

 1
Author: Sachin Shanbhag,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-10-04 08:42:54

Prueba esto y dile a mi si funciona espero que te ayude:

string value = Convert.ToString(Console.ReadLine());

Switch(value)
{
    Case "abc":

    break;

    default:

    break;
}       
 -7
Author: Amaterasu Hiro,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-05-17 22:45:40