[解決済み] C# SwitchステートメントでIgnoreCaseを使用する方法
質問
switch-case ステートメントで switch 内のオブジェクトが string の場合、ignoreCase 比較は可能でしょうか。
例えばこんなのがあります。
string s = "house";
switch (s)
{
case "houSe": s = "window";
}
ウィル
s
は、値 "window" を取得するのでしょうか?switch-caseステートメントをオーバーライドして、ignoreCaseを使用して文字列を比較するようにするにはどうすればよいですか?
どのように解決するのですか?
ご存知のように、2 つの文字列を小文字にして比較することは、大文字小文字を無視した比較を行うこととは異なります。これには多くの理由があります。たとえば、Unicode 標準では、発音区別符号を含むテキストを複数の方法でエンコードすることができます。一部の文字は、基本文字と発音区分符号の両方を 1 つのコードポイントに含んでいます。これらの文字は、基本文字の後に結合された発音区分け文字として表現されることもあります。これらの2つの表現はすべての目的のために等しく、.NET Frameworkの文化認識文字列比較は、CurrentCultureまたはInvariantCulture(IgnoreCase付きまたはなし)のいずれかで、それらを等しいものとして正しく識別します。一方、序数比較では、誤ってそれらを非同等と見なします。
残念ながら
switch
は序数比較以外のことは行いません。序数比較は、厳密に定義されたコードを持つ ASCII ファイルを解析するような特定の種類のアプリケーションでは問題ありませんが、序数文字列比較は他のほとんどの用途で間違っています。
正しい動作を得るために私が過去に行ったことは、単に私自身の switch 文をモックアップすることでした。これを行うには多くの方法があります。1 つの方法は
List<T>
を作成し、ケース文字列とデリゲートのペアを作成することです。このリストは、適切な文字列比較で検索することができます。一致するものが見つかると、関連するデリゲートが呼び出されるかもしれません。
もう一つの方法は、明らかな連鎖である
if
ステートメントを連鎖させることです。これは通常、構造が非常に規則的であるため、それほど悪いものではないことがわかります。
これの素晴らしいところは、文字列と比較するときに独自のスイッチ機能をモック化しても、パフォーマンス上のペナルティがないことです。システムは整数でできるような O(1) のジャンプテーブルを作ろうとしないので、いずれにせよ各文字列を一度に比較することになります。
比較するケースが多く、パフォーマンスが問題になる場合は
List<T>
オプションはソートされた辞書やハッシュテーブルに置き換えることができます。そうすれば、パフォーマンスは潜在的にswitch文オプションと同等かそれ以上になるかもしれません。
デリゲートリストの例です。
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();
}
もちろん、CustomSwitchDestinationデリゲートに標準的なパラメータと、場合によっては戻り値の型を追加したいと思うことでしょう。そして、より良い名前を付けたいと思うことでしょう!
各ケースの動作が、異なるパラメータが必要であるなど、この方法でのデリゲート呼び出しに従わない場合、連鎖的な
if
ステートメントを連鎖させることになります。私も何度かやったことがあります。
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";
}
関連
-
[解決済み] リフレクションを使用して文字列からプロパティ値を取得する
-
[解決済み] Rubyのswitch文の書き方
-
[解決済み] C#でenumからint値を取得する
-
[解決済み] IDisposable インターフェースの正しい使用法
-
[解決済み] Pythonのswitch文の代用品?
-
[解決済み] 特定のプロパティに対するLINQのDistinct()
-
[解決済み] JavaScriptSerializer - 列挙型を文字列としてJSONシリアライズする
-
[解決済み] switch文の中で変数を宣言してはいけないのはなぜですか?
-
[解決済み] Stringでswitch文が使えないのはなぜですか?
-
[解決済み】大文字・小文字を区別しない「Contains(string)
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】プログラム実行中に1秒待つ
-
[解決済み】Ajax処理で「無効なJSONプリミティブ」と表示される件
-
[解決済み] メンバー '<メンバー名>' にインスタンス参照でアクセスできない
-
[解決済み】WebForms UnobtrusiveValidationModeは、jqueryのScriptResourceMappingを必要とする
-
[解決済み】WPFでXamlファイルにコメントを追加する方法は?
-
[解決済み】URLから画像をダウンロードする方法
-
VSでscanfエラーを恒久的に解決するには、ソースファイルを作成し、自動的に#define _CRT_SECURE_NO_WARNINGS 1を追加してください。
-
[解決済み】名前 'ViewBag' が現在のコンテキストに存在しない - Visual Studio 2015
-
[解決済み】Nullableオブジェクトは値を持たなければならない?
-
[解決済み] C#のswitch文の制限 - なぜ?