[解決済み] スイッチオンタイプ」これ以上の代案はないのでしょうか?
2022-03-14 09:29:05
質問
C#では
switch
をType上で使用することができます。
is
リレーションは、複数の異なる
case
が適用されるかもしれません)、これ以外にタイプの切り替えをシミュレートする良い方法はないでしょうか?
void Foo(object o)
{
if (o is A)
{
((A)o).Hop();
}
else if (o is B)
{
((B)o).Skip();
}
else
{
throw new ArgumentException("Unexpected type: " + o.GetType());
}
}
解決方法は?
型の切り替えは、C#では確実に不足している( UPDATE: C#7 / VS 2017では、型の切り替えがサポートされています -。 Zachary Yatesの回答を参照 ). 大きなif/else文なしにこれを行うには、別の構造で作業する必要があります。TypeSwitchの構造を構築する方法については、しばらく前にブログ記事を書きました。
https://docs.microsoft.com/archive/blogs/jaredpar/switching-on-types
ショートバージョン。TypeSwitchは冗長なキャストを防ぎ、通常のswitch/case文と同様の構文になるように設計されている。例えば、標準的なWindowsのフォームイベントにおけるTypeSwitchの動作は以下のとおりです。
TypeSwitch.Do(
sender,
TypeSwitch.Case<Button>(() => textBox1.Text = "Hit a Button"),
TypeSwitch.Case<CheckBox>(x => textBox1.Text = "Checkbox is " + x.Checked),
TypeSwitch.Default(() => textBox1.Text = "Not sure what is hovered over"));
TypeSwitchのコードは、実はとても小さく、簡単にプロジェクトに入れることができます。
static class TypeSwitch {
public class CaseInfo {
public bool IsDefault { get; set; }
public Type Target { get; set; }
public Action<object> Action { get; set; }
}
public static void Do(object source, params CaseInfo[] cases) {
var type = source.GetType();
foreach (var entry in cases) {
if (entry.IsDefault || entry.Target.IsAssignableFrom(type)) {
entry.Action(source);
break;
}
}
}
public static CaseInfo Case<T>(Action action) {
return new CaseInfo() {
Action = x => action(),
Target = typeof(T)
};
}
public static CaseInfo Case<T>(Action<T> action) {
return new CaseInfo() {
Action = (x) => action((T)x),
Target = typeof(T)
};
}
public static CaseInfo Default(Action action) {
return new CaseInfo() {
Action = x => action(),
IsDefault = true
};
}
}
関連
-
[解決済み] このコマンドに関連する開いているDataReaderがすでにあり、最初にそれを閉じる必要があります。
-
[解決済み】Socket.Selectがエラー "An operation was attempted on something that is not a socket" を返す。
-
[解決済み】Unity 「関連するスクリプトを読み込むことができません」「Win32Exception: システムは指定されたファイルを見つけることができません"
-
[解決済み] 大なり小なりのSwitchステートメント
-
[解決済み】「switch」は「if」よりも速い?
-
[解決済み】Swift。switchステートメントでクラスの型をテストする
-
[解決済み】C#でif/elseとswitch-caseを使うことに大きな違いはあるのでしょうか?
-
[解決済み】switch文からreturn outするのはbreakを使うより良い方法と考えられるか?[クローズド]
-
[解決済み] Swiftのswitch文での小なり大なり
-
[解決済み] このスイッチ/パターンマッチングの考え方にメリットはあるのでしょうか?
最新
-
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 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】Ajax処理で「無効なJSONプリミティブ」と表示される件
-
[解決済み】文字列が有効な DateTime " format dd/MM/yyyy " として認識されなかった。
-
解決済み] Critical error detected c0000374 - C++ dll returns pointer off allocated memory to C# [解決済み] Critical error detected c0000374 - C++ dll returns pointer off allocated memory to C#.
-
[解決済み】非静的メソッドはターゲットを必要とする
-
[解決済み】値が期待した範囲に収まらない
-
[解決済み】インデックスが範囲外でした。コレクションパラメータname:indexのサイズより小さく、非負でなければなりません。
-
[解決済み】パラメータ付きRedirectToAction
-
[解決済み】Unityでゲームオブジェクトのすべての子をループスルーして破壊する方法?
-
[解決済み】C#のスイッチオンタイプ【重複あり
-
[解決済み] Case/SwitchとGetTypeを使用してオブジェクトを決定する【重複】。