wake-up-neo.com

C # -Schaltkastenzeichenfolge beginnend mit

Gibt es eine Möglichkeit, in einer switch-Anweisung eine case-Bedingung zu setzen, in der Sie angeben, ob eine Zeichenfolge mit etwas beginnt?

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 Zeichenfolgen können unterschiedlich lang sein.

aBC..

abczyv

dcs2.

qWERTY

fragen

41
Amra

Wenn Sie wüssten, dass die Länge der Bedingungen, um die Sie sich kümmern würden, alle dieselbe Länge wäre, dann könnten Sie:

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) ist vorhanden, damit eine Zeichenfolge mit weniger als 3 Zeichen keine Ausnahme für die Unterzeichenfolgenoperation auslöst.

Es gibt Erweiterungen dieser Technik, die z.B. Eine Reihe von Zeichenfolgen mit zwei Zeichen und eine Reihe von Zeichenfolgen mit drei Zeichen, auf die einige Übereinstimmungen mit zwei Zeichen und Vergleiche mit drei Zeichen folgen. Es sei denn, Sie haben eine sehr große Anzahl solcher Zeichenfolgen, wird diese schnell weniger effizient als die einfache Verkettung von if-else-Anweisungen sowohl für den laufenden Code als auch für die Person, die sie verwalten muss.

Bearbeiten: Hinzugefügt, da Sie jetzt angegeben haben, dass sie unterschiedliche Längen haben werden. Sie können das von mir erwähnte Muster anwenden, indem Sie die ersten X-Zeichen und dann die nächsten Y-Zeichen usw. überprüfen. Wenn jedoch nicht ein Muster vorhanden ist, bei dem die meisten Zeichenfolgen die gleiche Länge haben, ist dies sowohl ineffizient als auch schrecklich (ein klassischer Fall) vorzeitiger Pessimisierung).

Das Befehlsmuster wird in einer anderen Antwort erwähnt, daher werde ich keine Details dazu angeben, ebenso wie das Zuordnen von Zeichenfolgenmustern zu IDs, aber diese sind optional.

Ich würde nicht von if-else-Ketten zu Befehls- oder Zuordnungsmustern wechseln, um den Effizienzschalter zu erhalten manchmal hat Vorrang vor if-else, da Sie bei den Vergleichen für den Befehl oder beim Abrufen des ID-Musters mehr verlieren. Ich würde das allerdings tun, wenn der Code dadurch klarer würde.

Eine Kette von if-else's kann ziemlich gut funktionieren, entweder mit String-Vergleichen oder mit regulären Ausdrücken (letzteres, wenn Sie Vergleiche haben, die komplizierter sind als die bisherigen Präfix-Übereinstimmungen, die wahrscheinlich einfacher und schneller wären, erwähne ich die Registrierung). exs nur, weil sie manchmal mit allgemeineren Fällen dieser Art von Muster gut funktionieren).

Wenn Sie sich für if-elses entscheiden, überlegen Sie, welche Fälle am häufigsten auftreten werden, und führen Sie diese Tests durch, bevor Sie solche für seltenere Fälle durchführen (wenn jedoch "mit abcd beginnt" ein Fall ist, nach dem Sie suchen sollten) müssen überprüft werden, bevor "mit abc beginnt").

38
Jon Hanna

Kurze Antwort: Nein.

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

Na und? => 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, damit er nicht nur einmal ausgewertet werden kann.

Lange Antwort # 1 wurde von anderen gegeben.

Lange Antwort # 2:

Je nachdem, was Sie erreichen möchten, könnte Sie das Befehlsmuster / Muster der Verantwortungskette. Auf Ihren Fall angewendet würde jeder Code durch die Implementierung eines Befehls dargestellt. Zusätzlich zur Methode execute kann der Befehl eine boolesche Methode accept bereitstellen, die prüft, ob der angegebene String mit dem jeweiligen Parameter beginnt.

Vorteil: Anstelle Ihrer fest codierten switch-Anweisung, fest codierter StartsWith-Auswertungen und fest codierter Zeichenfolgen hätten Sie viel mehr Flexibilität.

Das Beispiel, das Sie in Ihrer Frage angegeben haben, würde dann so 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");
    }
}    
13
chiccodoro

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

5
Itay Karo

Dies ist jetzt mit der Mustererkennung in C # 7.0 möglich. Beispielsweise:

var myString = "abcDEF";

switch(myString)
{
    case string x when x.StartsWith("abc"):
        //Do something here
        break;
}
4
Raúl Bojalil

Wenn die Problemdomäne über ein Konzept für Zeichenfolgenheader verfügt, kann dies als Aufzählung modelliert werden.

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
Felix Ungman

Zusätzlich zur Teilzeichenfolgeantwort können Sie dies als mystring.SubString (0,3) ausführen und in der case-Anweisung prüfen, ob es sich um "abc" handelt.

Vor der switch-Anweisung müssen Sie jedoch sicherstellen, dass Ihr Mystring mindestens 3 Zeichen lang ist.

1
Sachin Shanbhag