質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Q&A

解決済

2回答

208閲覧

dynamicとキャスト、どちらで実装するべきか

BluOxy

総合スコア2663

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

0グッド

0クリップ

投稿2019/01/28 09:53

編集2019/01/28 09:57

###最初に

いつもお世話になります。
C#での実装について悶々とする点があったため、力をお借りしたいです。

dynamicとキャスト、どちらで実装するべきか

特定の例外クラスに定義されているErrorCodeプロパティを取得するメソッドがあると仮定します。
メソッド内に登場するApiExceptionとHttpExceptionはどちらもErrorCodeというプロパティが定義されています。ApiExceptionとHttpExceptionは継承関係にありません。

引数にはExceptionのインスタンスを渡し、両者の型以外の場合はnullを返します。

C#

1 private static HttpStatusCode? TryGetErrorCode(Exception ex) 2 { 3 HttpStatusCode? httpStatusCode = null; 4 5 //実装1 6 switch (ex) 7 { 8 case ApiException apiEx: httpStatusCode = (HttpStatusCode)apiEx.ErrorCode; break; 9 case HttpException httpEx: httpStatusCode = (HttpStatusCode)httpEx.ErrorCode; break; 10 } 11 12 //実装2 13 dynamic dynamicEx = ex; 14 httpStatusCode = dynamicEx?.ErrorCode; 15 16 return httpStatusCode; 17 }

上記のような機能の実装に関して、私は2つの方法を考えました。
前者は型のキャストをする方法で、後者は動的な型に変換する方法です。
両者の手法は、どちらも一長一短あると考えています。

方法メリットデメリット
キャストをする方法型安全ErrorCodeを持つExceptionクラスが増えるたびにcaseを増やさなければならない。(継承関係にある場合は別)
動的な型に変換する方法コードが短いHttpStatusCode型に変換できる型(すなわちint)ではない型が来た場合に、実行時例外が発生する

※この時点で私の認識に間違いがあればご指摘をお願いします。

###質問
可読性や保守性などの考慮を含めて、本来はどちらの手法で実装するべきでしょうか。
また、別案がございましたら是非ご教授をお願いします。

よろしくお願いします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

リフレクションを使うという手もあるのではないでしょうか

csharp

1private static HttpStatusCode? TryGetErrorCode(Exception ex) 2{ 3 HttpStatusCode? httpStatusCode = null; 4 5 //実装1 6 switch (ex) 7 { 8 case ApiException apiEx: httpStatusCode = (HttpStatusCode)apiEx.ErrorCode; break; 9 case HttpException httpEx: httpStatusCode = (HttpStatusCode)httpEx.ErrorCode; break; 10 } 11 12 //実装2 13 dynamic dynamicEx = ex; 14 httpStatusCode = dynamicEx?.ErrorCode; 15 16 // 実装3 17 httpStatusCode = ex.GetType().GetProperty("ErrorCode", typeof(HttpStatusCode))?.GetValue(ex) as HttpStatusCode?; 18 19 return httpStatusCode; 20}

投稿2019/01/28 10:17

編集2019/01/28 10:22
runny_nose

総合スコア280

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

BluOxy

2019/01/28 10:31

ありがとうございます。 たしかに、変数名から直接アクセスする方法もありかもしれません。 リフレクションを使うことがあまりなかったので参考になります。
guest

0

ベストアンサー

インターフェースを適用するのが一番いいと思います。

できない場合はどっちもどっちの気もしますが、私なら dynamic を使うかもしれません。ただし ErrorCode プロパティが想定外のものである可能性もあるので、HttpStatusCode かどうかのチェックをします。

switch を使う方は確かに既存の例外ばかり扱うならパフォーマンスは良いのですが、例外クラスを新しく作ったときに更新を忘れると見つかりにくいバグの原因になります。

投稿2019/01/28 10:13

Zuishin

総合スコア28660

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

BluOxy

2019/01/28 10:25

ありがとうございます。 dynamicとswitchについてのご意見は両者とも参考になりました。 インタフェースについては、ApiExceptionクラスがswagger codegenで自動生成されているため、そこへ手を入れるのは残念ながら難しいようです。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問