2010-10-04 9 views
37

Gibt es eine Möglichkeit, eine case-Bedingung in einer switch-Anweisung zu machen, in der Sie sagen, ob eine Zeichenfolge mit etwas beginnt?C# Switch-Case-String beginnend mit

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

UPDATE Andere Strings können unterschiedlich lang sein.

abc ..

abczyv

DCS2.

QWERTY

als ...

+0

Sind Ihre Schalter Fällen gehen alle gleich lang sein? z.B. ABC, XYZ – Paddy

+0

@Paddy: Nein, sie können unterschiedliche Länge sein. Danke. – Amra

Antwort

28

Wenn Sie die Länge der Bedingungen wusste, dass Sie alles über sein die gleiche Länge dann könnten Sie sich kümmern würde:

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

Die Math.Min(3, mystring.Length) gibt es so, dass eine Reihe von weniger als 3 Zeichen nicht werfen eine Ausnahme bei der Sub-String-Operation.

Es gibt Erweiterungen dieser Technik, um z.B. eine Reihe von 2-Zeichen-Strings und eine Reihe von 3-Zeichen-Strings, bei denen nach einigen Übereinstimmungen mit 2-Zeichen-Vergleichen 3-Zeichen-Vergleiche folgen. Es sei denn, Sie haben eine sehr große Anzahl solcher Strings, aber es wird schnell weniger effizient als einfach, wenn Sie für den laufenden Code und die Person, die es pflegen muss.

Bearbeiten: Hinzugefügt, da Sie jetzt angegeben haben, dass sie unterschiedlich lang sein werden. Sie könnten das Muster tun, das ich erwähnt habe, die ersten X-Zeichen und dann die nächsten Y-Zeichen zu überprüfen, aber wenn es ein Muster gibt, bei dem die meisten Zeichenfolgen die gleiche Länge haben, ist dies sowohl ineffizient als auch schrecklich vorzeitige Pessimierung).

Das Befehlsmuster wird in einer anderen Antwort erwähnt, deshalb werde ich keine Details dazu angeben, ebenso wie das, wo Sie String-Muster IDs zuordnen, aber sie sind eine Option.

würde ich nicht von ändern if-else-Ketten oder Mapping-Muster zu befehlen, die Effizienz Schalter zu gewinnen manchmal if-else hat über, wie Sie mehr in dem Vergleichen für den Befehl oder den Erhalt des ID-Musters verlieren. Ich würde es tun, wenn es den Code klarer macht.

Eine Kette von if-else's kann ziemlich gut funktionieren, entweder mit String-Vergleichen oder mit regulären Ausdrücken (Letzteres, wenn Sie Vergleiche komplizierter als die Präfix-Übereinstimmungen bisher, die wahrscheinlich einfacher und schneller wäre, I ' Ich erwähne reg-ex nur, weil sie manchmal mit allgemeineren Fällen dieser Art von Muster gut funktionieren.

Wenn Sie sich für if-elnes entscheiden, versuchen Sie zu überlegen, welche Fälle am häufigsten auftreten, und machen Sie diese Tests vor denen für seltenere Fälle (obwohl natürlich "beginnt mit abcd" ist ein Fall zu suchen Sie nach es müsste überprüft werden, bevor "beginnt mit abc").

+1

'Math.Min (3, mystring.Length)' nette Berührung, wusste nicht von dieser +1 –

5

k Wenn alle Fälle die gleiche Länge haben, können Sie
switch (mystring.SubString(0,Math.Min(len, mystring.Length))) verwenden.
Eine andere Option ist eine Funktion, die categoryId basierend auf der Zeichenfolge zurückgibt und die ID schaltet.

1

Zusätzlich zu Teilstring-Antwort können Sie es als mystring.SubString (0,3) und Check-in Case-Anweisung, wenn seine "abc".

Aber vor der switch-Anweisung müssen Sie sicherstellen, dass Ihr mystring mindestens 3 lang ist.

13

Kurze Antwort: Nein.

Die switch-Anweisung nimmt einen Ausdruck, der nur einmal ausgewertet wird. Basierend auf dem Ergebnis wird ein weiterer Code ausgeführt.

Also was? => String.StartsWith ist eine Funktion. Zusammen mit einem gegebenen Parameter ist es ein Ausdruck. Für Ihren Fall müssen Sie jedoch für jeden Fall einen anderen Parameter übergeben, sodass er nicht nur einmal ausgewertet werden kann.

Lange Antwort # 1 wurde von anderen gegeben.

Lange Antwort # 2:

Je nachdem, was Sie versuchen könnten Sie interessieren sich für die Command Pattern/Chain-of-responsibility pattern zu erreichen. Auf Ihren Fall angewendet würde jedes Codeelement durch eine Implementierung eines Befehls dargestellt werden. Zusätzlich zu der Ausführung Methode kann der Befehl eine boolesche Accept Methode, die überprüft, ob die angegebene Zeichenfolge beginnt mit dem jeweiligen Parameter.

Vorteil: Anstelle Ihrer hartcodierten Switch-Anweisung, hardcoded StartsWith Bewertungen und hardcoded Strings, hätten Sie viel mehr Flexibilität.

Das Beispiel, das Sie in Ihrer Frage gaben dann würde wie folgt aussehen:

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"); 
    } 
}  
3

Wenn das Problem Domain eine Art von String-Kopf Konzept hat, dies als Enum modelliert werden kann.

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

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

enum StringHeader { ABC, QWERTY, ... } 
-7

Versuchen Sie dies und meine sagen, ob es es Ihnen helfen, arbeitet Hoffnung:

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

Switch(value) 
{ 
    Case "abc": 

    break; 

    default: 

    break; 
}  
+0

, warum ich downvoted wurde ??? –

+4

Ihre Antwort wird nicht funktionieren, eine grundlegende C# -Case-Anweisung ist, was Sie gezeigt haben. Dies stimmt mit der ganzen Zeichenfolge überein, nicht mit dem Anfangsabschnitt (nach dem die Frage fragt). – wonea

Verwandte Themen