Wie Sie anscheinend wissen, ist das Verringern und Vergleichen von zwei Zeichenfolgen nicht dasselbe wie das Vergleichen von Groß- und Kleinschreibung. Dafür gibt es viele Gründe. Der Unicode-Standard ermöglicht beispielsweise die mehrfache Codierung von Text mit diakritischen Zeichen. Einige Zeichen enthalten sowohl das Basiszeichen als auch das diakritische Zeichen in einem einzelnen Codepunkt. Diese Zeichen können auch als Basiszeichen dargestellt werden, gefolgt von einem kombinierten diakritischen Zeichen. Diese beiden Darstellungen sind für alle Zwecke gleich, und die kulturbewussten Zeichenfolgenvergleiche in .NET Framework identifizieren sie korrekt als gleich, entweder mit der CurrentCulture oder der InvariantCulture (mit oder ohne IgnoreCase). Ein Ordnungsvergleich hingegen betrachtet sie fälschlicherweise als ungleich.
Tut leider switch
nichts anderes als einen ordinalen Vergleich. Ein Ordnungsvergleich ist für bestimmte Arten von Anwendungen in Ordnung, z. B. das Parsen einer ASCII-Datei mit fest definierten Codes, aber der Ordnungszeichenfolgenvergleich ist für die meisten anderen Anwendungen falsch.
Was ich in der Vergangenheit getan habe, um das richtige Verhalten zu erzielen, ist nur meine eigene switch-Anweisung zu verspotten. Es gibt viele Möglichkeiten, dies zu tun. Eine Möglichkeit wäre, ein List<T>
Paar von Fallzeichenfolgen und Delegaten zu erstellen . Die Liste kann mit dem richtigen Zeichenfolgenvergleich durchsucht werden. Wenn die Übereinstimmung gefunden wird, kann der zugeordnete Delegat aufgerufen werden.
Eine andere Möglichkeit besteht darin, die offensichtliche Kette von if
Aussagen zu machen. Dies stellt sich normalerweise als nicht so schlecht heraus, wie es sich anhört, da die Struktur sehr regelmäßig ist.
Das Tolle daran ist, dass es keine wirklichen Leistungseinbußen gibt, wenn Sie Ihre eigene Switch-Funktionalität beim Vergleich mit Strings nachahmen. Das System wird eine O (1) -Sprungtabelle nicht so erstellen, wie es mit ganzen Zahlen möglich ist, daher wird es sowieso jede Zeichenfolge einzeln vergleichen.
Wenn viele Fälle verglichen werden müssen und die Leistung ein Problem darstellt, kann die List<T>
oben beschriebene Option durch ein sortiertes Wörterbuch oder eine Hash-Tabelle ersetzt werden. Dann kann die Leistung möglicherweise mit der Option switch-Anweisung übereinstimmen oder diese überschreiten.
Hier ist ein Beispiel für die Liste der Delegierten:
delegate void CustomSwitchDestination();
List<KeyValuePair<string, CustomSwitchDestination>> 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();
}
Natürlich möchten Sie dem CustomSwitchDestination-Delegaten wahrscheinlich einige Standardparameter und möglicherweise einen Rückgabetyp hinzufügen. Und du wirst bessere Namen machen wollen!
Wenn das Verhalten jedes Ihrer Fälle nicht dazu geeignet ist, den Aufruf auf diese Weise zu delegieren, z. B. wenn unterschiedliche Parameter erforderlich sind, bleiben Sie bei verketteten if
Anweisungen hängen. Ich habe das auch ein paar Mal gemacht.
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";
}
ToUpperInvariant()
oderToLowerInvariant()
? Außerdem vergleicht er nicht zwei unbekannte Zeichenfolgen , sondern eine unbekannte Zeichenfolge mit einer bekannten Zeichenfolge. Solange er weiß, wie man die geeignete Groß- oder Kleinschreibung fest codiert, sollte der Schaltblock einwandfrei funktionieren.