【C#】型による処理の分岐【Switch】

Type による処理の分岐をしたかった

System.Type より処理の分岐を Switch でやりたかったけど悩んだので、対応メモ

if文で書くとこうなりますが、冗長的で比較判定も多いので避けたい。
Switch でなんとかしたい。

Type type;
if( type is int)
{
	// intの処理
}
else
if( type is float)
{
	// floatの処理
}
else
if( type is Color)
{
	// Colorクラスの処理
}

失敗例1

switch( type)
{
	case typeof( int):
		// intの処理
		break;
	case typeof( float):
		// floatの処理
		break;
	case typeof( Color):
		// Colorクラスの処理
		break;
}
error CS0150: A constant value is expected

と怒られる。
case には定数が必要らしい

失敗例2

そうだ 新必殺技 型Switch を使おう

switch( type)
{
	case int @_:
		// intの処理
		break;
	case float @_:
		// floatの処理
		break;
	case Color @_:
		// Colorクラスの処理
		break;
}
error CS8121: An expression of type 'Type' cannot be handled by a pattern of type 'int'.

怒られた。
そもそも type は Type型 なので int や float に変換できねーよと。

ここで諦めかけてぐぐってみると、同じ悩みの人がいらっしゃるようで こちら を参考に解決しました。

成功例

Type type = ...
switch( type)
{
	case Type @_ when @_ == typeof( int):
		// intの処理
		break;
	case Type @_ when @_ == typeof( float):
		// floatの処理
		break;
	case Type @_ when @_ == typeof( Vector4):
		// Vector4クラスの処理
		break;
	case Type @_ when @_ == typeof( Color):
		// Colorクラスの処理
		break;
}

type を Type に型変換 し、 when 文で 内容を判定。

うーむ、結局比較処理が何度も行われそうですが、最適化してくれるのでしょうか?
速度的な部分は未検証。

もっと良い方法を探してまーす。

追記 2020/7/1

もう少し調べたけど良い方法は見つかりませんでした。
多少修正

var type = typeof( T);
switch( System.Type.GetTypeCode( type))
{
	case TypeCode.Int32:
		break;
	case TypeCode.Single:
		break;
	case TypeCode.Object when type == typeof( Color):
		break;
	case TypeCode.Object when type == typeof( Vector4):
		break;
	case TypeCode.Object when type == typeof( Texture):
		break;
}

基本型は TypeCode で分岐し、それ以外は when で判定してます。

もっとミニマムに書く方法があると思うけど
もうこれでいいや。

Add a Comment

メールアドレスが公開されることはありません。 が付いている欄は必須項目です