- PR -

C# 戻り値の型を動的に変更することは可能ですか?

投稿者投稿内容
nanbu
大ベテラン
会議室デビュー日: 2004/08/19
投稿数: 178
投稿日時: 2005-05-08 01:10
引用:

Jittaさんの書き込み (2005-05-07 21:37) より:
 事故レス。。。これだと、例外が発生することを想定しているのだから、業務フロー上のエラーなのか。。。

 えっと、ユーザに入力してもらう数値のエラーを、2つ考えました。1つは「Decimalとして理解できない入力」、もう1つは「割引率として設定してはいけない入力」です。後者を、セットアクセスメソッドで、ArgumentOutOfRangeExceptionにて通知し、前者はDecimal.Parseが送出するであろう例外で検知しよう、としています。

 ここで、「割引率として…」は、業務ルールとして設定しているのだから当然検査しなければなりません。しかし、「Decimalとして…」は、ここで検査すべきかどうかは微妙です。


南部です。

確かに、業務フロー設計として割引率の設定が例外をスローすることは
想定されています。
しかし、GoodsクラスのDiscountRateプロパティが範囲外の値の設定に対し
スローする例外は業務エラーでしょうか。
それとも、クラスライブラリとしてパラメータ引数が有効であることを
チェックしたときのアプリケーションエラーでしょうか。

業務エラーであるとした場合、業務エラーを表現するために「例外」を
使用しませんので、
public bool SetDiscountRate(decimal discountRate);
のようなインターフェースになると思います。
#なんかしっくりこないです。
#読み直しているうちに「しっくりこない」がしっくりこなくなってきた。

クラスライブラリとしてのパラメータチェックであれば、
呼び出しメソッド側(クラスライブラリを使用するビジネスメソッド)で、
範囲外例外を業務エラーとして切り替えることで実現します。

私は、モデルの意味合いが強そうなGoodsクラスは業務フローから
切り離したいと考えますので、後者を選択します。

ところで、DiscountRateをプロパティからメソッドに変更する理由は
なんでしょう?
[編集]
Jittaさんの書き込み (2005-05-07 22:16)の
Validatorの絡み部分見落としていました。
でも、Validator、というか、ASP.NETやったことないので
プロパティよりメソッドのほうが都合がよいものなんだと
して、上記質問を削除します。
[/編集]

[ メッセージ編集済み 編集者: nanbu 編集日時 2005-05-08 03:29 ]
nak2k
ベテラン
会議室デビュー日: 2003/07/17
投稿数: 86
投稿日時: 2005-05-08 02:36
かなり感覚的な話になって申し訳ないのですが、戻り値はできるだけ「関数の値」であったほうが自然な感じがすると思います。
なので、「〜を取得する」や「〜を計算する」メソッドが計算結果を戻り値として返すのはいいのですが、「〜をセットする」や「〜にログインする」メソッドに戻り値があるのを見ると何か不自然な感じがして気になります。

しかし、戻り値を返さないほうが自然な関数だとしてもその関数の主となる処理を実行できないケースはあり得るので、そのときは関数内部から呼び出し元への「イベント通知」機構である例外を使用する、という考え方はどうでしょうか?

みなさんの議論を読んで改めて自分がわりと積極的に例外を利用している理由(例外を例外的なものとして扱ってない理由)をまとめるとこんな感じかなぁ、と。


ただ、この考え方を徹底するとかなり例外を積極的に活用することになるので、あちこちにtry〜catch文が現れて可読性下げそうですけどね。

その場合、こういう風な文法があったら便利だろうなぁ、って今思いつきました。
コード:

file.Open(〜) catch(FileNotFoundException) { 〜 };


ノリとしてはPerlの「open 〜 or die 〜」ってとこです。


[ メッセージ編集済み 編集者: k-nak 編集日時 2005-05-08 02:41 ]
Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2005-05-08 07:05
引用:

nanbuさんの書き込み (2005-05-08 01:10) より:
[編集]
Jittaさんの書き込み (2005-05-07 22:16)の
Validatorの絡み部分見落としていました。
でも、Validator、というか、ASP.NETやったことないので
プロパティよりメソッドのほうが都合がよいものなんだと
して、上記質問を削除します。
[/編集]


とりあえず、ここだけ

 あれ?Windowsにもありませんでしたっけ?
・・・
ErrorProvider
Validatorコントロールじゃなかった、イベントだった。
nanbu
大ベテラン
会議室デビュー日: 2004/08/19
投稿数: 178
投稿日時: 2005-05-08 16:32
引用:

Jittaさんの書き込み (2005-05-08 07:05) より:

イベントだった。



南部です。

いいサンプルですね。
業務エラーの判定をValidatingで行っています。

恐らくモデルであるGoodsのDiscountRateプロパティでは
範囲外の値を設定すると「例外」をスローするでしょう。
(モデルの整合性のためと、このクラスライブラリを使用する
 開発者のためです、、もちろん分かりやすいメッセージ求む)

さらに、この「例外」がほぼ正常ルートに戻されるであろうことから、
割引率の正当性をチェックするメソッドを公開するといいかも知れません。
(Validatingの実装者が楽だし、、)
未記入
ぬし
会議室デビュー日: 2004/09/17
投稿数: 667
投稿日時: 2005-05-08 17:49
ちょっと分からない点があるので質問させてください。

引用:
しかし、GoodsクラスのDiscountRateプロパティが範囲外の値の設定に対しスローする例外は業務エラーでしょうか。


ずっと気になっていたんですが「業務エラー」とは何なのでしょうか。業務エラー以外には、どのようなエラーがあるのでしょうか。nanbu さんが考えているエラーの種類を列挙していただいて分類していただけると、私にも理解できるかもしれないです。

私は「入力欄の文字がすべて数値で構成されている」とか「文字列がメールアドレスの書式を満たしている」などの検査ロジックは、業務依存性が低く「業務エラー」とやらには該当しないと勝手に思い込んでいたんですが…。どうやら違うっぽい。

引用:
業務エラーであるとした場合、業務エラーを表現するために「例外」を使用しませんので


では、どのようなエラーを表現する場合に「例外」の使用が適切なのでしょうか。前に、「アプリケーションエラー」「システムエラー」という言葉が出てきていますが、私はこれらを、かなり致命的な障害(Java の Error 相当)でキャッチすべきではない(==フローへの復帰が困難な)ものと認識していました。この認識がそもそも間違っているのかな?

引用:
それとも、クラスライブラリとしてパラメータ引数が有効であることをチェックしたときのアプリケーションエラーでしょうか。


この文脈からすると、アプリケーションエラーはそれほど致命的な状態をあらわすものではないような気もしてきます。

引用:
クラスライブラリとしてのパラメータチェックであれば、呼び出しメソッド側(クラスライブラリを使用するビジネスメソッド)で、範囲外例外を業務エラーとして切り替えることで実現します。


なぜ、わざわざ水際で例外をキャッチして、戻り値方式などに切り替える必要があるのでしょうか。例外をキャッチできるということはプログラマが例外がスローされることを理解しているのだから、(チェック例外でなくても)正しく扱えそうな気がしますが…。そもそも常に水際で例外をキャッチして戻り値方式に切り替えるくらいなら、汎用ライブラリ自体が例外を投げずに戻り値方式を採用していたほうが良くないですか? なぜ、標準ライブラリは例外を投げているのでしょうか?

引用:
私は、モデルの意味合いが強そうなGoodsクラスは業務フローから切り離したいと考えますので、後者を選択します。


モデルとは何ですか? MVC のモデルですか? MVC のモデルだとした場合・・・モデルは業務フローから切り離したいと考える理由はなんでしょうか? 私は MVC に関係なく Goods と命名されたクラスは業務依存性が高そうなので、業務フロー(設計)と密接な位置に置いておくほうがいいかな、と思いました。

また、ここで後者(アプリケーションエラー?)を選択すると「例外の使用が正当化される」というのも良く分かりません。

以下、このスレでの私の認識。

  • C# の例外はフローへの復帰が困難な重大なアプリケーションエラー、システムエラーに使用する。(≒これが業務エラーには使用しないということだと思っていました)
  • よって C# の例外は投げたら投げっぱなしで、基本的にキャッチすべきではない。
渋木宏明(ひどり)
ぬし
会議室デビュー日: 2004/01/14
投稿数: 1155
お住まい・勤務地: 東京
投稿日時: 2005-05-08 18:40
引用:

以下、このスレでの私の認識。

  • C# の例外はフローへの復帰が困難な重大なアプリケーションエラー、システムエラーに使用する。(≒これが業務エラーには使用しないということだと思っていました)
  • よって C# の例外は投げたら投げっぱなしで、基本的にキャッチすべきではない。




そう決まりきったもんでもないんじゃないかな?

あるスコープで、どんな種類の例外を捕捉するべきかは「場合による」と思います。

ただ、.NET には Java のチェック例外に相当する機能が(都合により=前述)存在しないので、致命的な障害と例外的な例外?(=いわゆる例外?)が同じ「例外」で表現するほか無くて、「使い分けが難しいね」という話なんじゃないかと。

# この辺は Java に一日の長がありますね。
# でも、起こり得る例外を捕捉しているかどうかをコンパイル時に「完全に」検査するのは無理だろうなぁ>.NET


_________________
// 渋木宏明 (Hiroaki SHIBUKI)
// http://hidori.jp/
// Microsoft MVP for Visual C#
//
// @IT会議室 RSS 配信中: http://hidori.jp/rss/atmarkIT/
nodera
大ベテラン
会議室デビュー日: 2003/09/08
投稿数: 200
投稿日時: 2005-05-08 19:27
こんにちは。

自分はJavaについてはそれほど詳しくありませんが、例外に対する考え方は最初の未記入さんの発言内容をほぼ支持します。途中で南部さんの発言等によりC#での例外の認識を「例外は投げたら投げっぱなしで、基本的にキャッチすべきではない」ということになってしまって、あれれと思っていました。

C#でも業務フローの中では当然例外をキャッチもします。例外をキャッチするということは、その例外が発生することが予測可能であり、かつキャッチした場合はアプリケーションの状態を復帰することができるということです。逆にいうとわけもわからず全ての例外をキャッチしてしまうようなことがあれば、それは例外の間違った使い方だと言わざるおえません。(エラーコードを完全に制御することは難しいという意味において、アプリケーションが不安定な状態のまま続行される危険性がある、ということと同じ状態になってしまいます)

南部さんが「後者」と言っているは、「アプリケーションエラー」ではなく「クラスライブラリ」をさしているのだと思います。南部さんが使う言葉がちょっとあいまい(言葉の定義において南部さんの認識と他者の認識が一致していない)なんで誤解を招いているのだと思いますよ。自分も業務フローや業務エラー、ビジネスメソッドという言葉がどの辺りを指しているのか、何度も読み返してなんとなく判ってきたところです。
ちなみに自分は、MVCに置き換えるなら、業務フローはVとCで実装されるロジックであり、業務エラーもそこで発生するエラー、Mはクラスライブラリで、そこで発生するエラーはアプリケーションエラーと認識しました。

自分も南部さんにひとつたずねたいのですが、「CLRのデザインルール」ってのは具体的のどのドキュメントのどの部分を指しているのでしょうか?それを読めば、南部さんの言わんとしていることがもうちょっと理解できるかな。
ちなみにburton999さんが最初に貼り付けたリンク先には、「.NET の世界ではエラー処理が "エラー コード" を使用するスタイルから、 例外を使用するスタイルに移行している」と書いてあります。


Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2005-05-08 21:43
引用:

未記入さんの書き込み (2005-05-08 17:49) より:

ずっと気になっていたんですが「業務エラー」とは何なのでしょうか。業務エラー以外には、どのようなエラーがあるのでしょうか。nanbu さんが考えているエラーの種類を列挙していただいて分類していただけると、私にも理解できるかもしれないです。


 これ、そうですね。私も「事故レス」あたりからわからなくなりました。

 想定されている例外が「業務エラー」なら、たとえば数値を入力するところで、「ここには『数値を表すラベル』を付けているのだから、数値以外の入力はない」と思いこんでいれば、想定されない例外が発生します。そして、プログラミング初心者は、そういうコーディングをよくするでしょう。
 しかし、「どんなリードの仕方をしても、ユーザは何を入力するかわからない」という前提に立てば、想定された例外が発生します。
 とすると、設計者やコーディング者の経験や知識によって、変わるのでしょうか。

#####
[投稿日時: 2005-05-05 16:02]あたりのものを元に、例外の種類を分けています。
_________________

スキルアップ/キャリアアップ(JOB@IT)