- PR -

セッターで値が規定外の時って

投稿者投稿内容
R・田中一郎
ぬし
会議室デビュー日: 2005/11/03
投稿数: 979
投稿日時: 2006-01-31 19:29
題名と内容が著しく異なりすぎてしまったので、別スレを立てます。
元スレ

引用:

元スレでの Jittaさんの書き込み (2006-01-26 23:08) より:

 たとえば、「番号」に負の数が入ってくることは、想定していませんよね?でも、誰かが入れるかもしれない。Int32 の範囲を超えるような値をセットしようとするかもしれない。名前にも、常識的な長さの最大値があると思います。それを越えた設定が出来てしまいます。
 データを入力するのは、フォームからの手入力だけとは限りません。初期データを入れるときや、移行データを作るとき、ちょっとしたミスをすることは十分考えられます。そういうとき、このままでは、不正な値も入力できてしまいます。
 それを防ぐために、フィールドを private にして隠し、プロパティというメソッド経由でアクセスさせます。値の範囲チェックをするのはアクセスメソッドの中にまとめることが出来、チェックのためのコードをプログラム中にばらまかなくてすみます。
 ちなみに、チェックは必ずしてください。それがセキュアプログラミングの一歩です。つまりこれも、スマートさより、堅牢性、保守性を優先する、ということです。



この言葉に深く感銘を受けまして、現在、コードを修正中です。
そこで、セッターの値チェックの結果、規定外の値が設定されたことが判明した場合の処理ですが、どのような対処をするのが良いのでしょうか?

コード:

#Region " 番号 プロパティ "
    '****************************************************************************
    ' 番号 プロパティ
    '****************************************************************************
    Private _番号 as Integer
    Public Property 番号() as Integer
    Get
        Return (_番号)
    End Get
    Set(ByVal value As Integer)
        If (value < 1) Then
            ここの処理をどうしよう??????
            Exit Property
        End If
        _番号 = value
        End Set
    End Property



やはり、例外エラーを発生させるのが一般的なんでしょうか?

じゃんぬねっと
ぬし
会議室デビュー日: 2004/12/22
投稿数: 7811
お住まい・勤務地: 愛知県名古屋市
投稿日時: 2006-01-31 19:50
引用:

R・田中一郎さんの書き込み (2006-01-31 19:29) より:

やはり、例外エラーを発生させるのが一般的なんでしょうか?


そのクラスの仕様次第なんですが、一般的にはそうだと思います。
規定外の値が入ってきた以上、業務は続行不可能でしょう。

規定外の値を、別の値に置換して素通り、なんて危険なコードを見かけることがあります。
規定外の値が入ってくる時点で立派なバグなのですから、何ら根本的な解決になっていないため危険です。
(仕様次第では、置換した方が良いケースもあるかもしれないことを断っておきます)

デバッグをしている最中にも気付きやすい、例外をスローするのが良いでしょう。
Java Solution 会議室でも書きましたが、余計なおせっかいをするとバグが見えにくくなります。

_________________
C# と VB.NET の入門サイト
じゃんぬねっと日誌
Tdnr_Sym
ぬし
会議室デビュー日: 2005/09/13
投稿数: 464
お住まい・勤務地: 明石・神戸
投稿日時: 2006-01-31 20:05
こんばんは。

引用:

R・田中一郎さんの書き込み (2006-01-31 19:29) より:

やはり、例外エラーを発生させるのが一般的なんでしょうか?



設計によりますが、私なら次のどれかにします。
1.例外をスローする。
2.契約による設計(Design by Contract)を使う。
 .NETだとSystem.Diagnostics.Debug.Assertメソッドを使う。
3.なにもしない。(稀ですけれど)

今回の場合だと、2.のDesign by Contractかなぁ…

#挨拶を追加(~_~;)

[ メッセージ編集済み 編集者: Tdnr_Sym 編集日時 2006-01-31 20:11 ]
Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2006-01-31 21:39
 プロパティなら例外をスロー。

 たとえば、.NET Framework 2.0 に追加された TryParse のように、TrySet のようなメソッドを追加しておくのも1つ。
 ユーザ入力などで例外を出したくない場合は、Validate メソッドを用意して、プロパティのセッターでは Validate メソッドが false を返せば例外を送出するようにする、というのも1つ。


 やりたいことを形にする方法は1つではありません。どれだけ多くの方法を作れ、適材適所に適用できるか、ってことです。

↓kazukiさんのを見て、激しく賛成。ただ、「セッターで例外を出さない」とは、言っていません。例外は高価な処理なので、それを避ける方法を用意しておく、という意図です。

[ メッセージ編集済み 編集者: Jitta 編集日時 2006-01-31 22:37 ]
Kazuki
ぬし
会議室デビュー日: 2004/10/13
投稿数: 298
投稿日時: 2006-01-31 22:29
私ならArgumentExceptionを投げるかな。

趣味のプログラムなら好みで!
仕事のプログラムなら仕様との兼ね合いで!

趣味でも仕事でも,統一されてるのが後で幸せです。
囚人
ぬし
会議室デビュー日: 2005/08/13
投稿数: 1019
投稿日時: 2006-02-01 10:19
http://www.microsoft.com/japan/msdn/library/default.asp?url=/japan/msdn/library/ja/cpgenref/html/cpconerrorraisinghandlingguidelines.asp
Jittaさんと被りますが、例外をスローするときはそれを避ける手段が用意されていると、使用する側は気が楽ですね。

コード:
Set(ByVal value As Integer)
    If (value < 1) Then
        ここの処理をどうしよう??????
        Exit Property
    End If
    _番号 = value
End Set



この例だと、「負の値」がセットされるのは予期されるエラーです。
普通は例外をスローすべきシナリオではないかもしれません(と上記リンクでは言っている)。
Integer なのだから「負」が許容されていると、使用する側としては考えてしまいます。

bool Allow番号( int value );

みたいなメソッドや、

readonly 番号MinValue;( static でもよいか? )

みたいなものがあれば、「指定した番号が許可されているのか?」「番号の最小値」を使用する側に伝える事ができ、先のプロパティで「負の値」をセットする事は「予期しないエラー」になり、例外をスローしてよいシナリオになれるのではいでしょうか。
_________________
囚人のジレンマな日々
takacini
常連さん
会議室デビュー日: 2005/12/27
投稿数: 24
お住まい・勤務地: 東京都
投稿日時: 2006-02-01 15:24
有識者の方々の有益なレスがたくさんついているので今更って感がありますが・・・

プロパティのセッターに関しては私も Kazuki さんと同じく ArgumentException をよく使います。
ただ、業務でのチェック処理ではプロパティのセッターであがってくる例外をアテにすることはあまりなく、
それぞれのプロパティごとに Is〜 みたいなチェックメソッドを作ることが多いです。
(既出の「予期できる例外を避ける手段」です)

例えばデータ編集画面なんかを実装する場合だと、
更新ボタンの処理の先頭にユーザーが入力したデータのチェック処理を書きますが
その時こちらで準備しておいたチェックメソッドを使ってもらうようにすれば、

  • チェック処理を共通化できる。画面側はメソッドを呼び出しまくるだけなので簡単。
  • 例外生成の高コスト処理を回避できる。
  • 「入力エラーだった項目をすべていっぺんにメッセージボックスで表示して」なんて要求も実装が簡単。

プロパティのセッターでの例外生成、およびチェックメソッドの用意は
いろいろとメリットが多いと思うのでオススメです。
R・田中一郎
ぬし
会議室デビュー日: 2005/11/03
投稿数: 979
投稿日時: 2006-02-02 10:56
皆さん、いろいろと教えていただいてありがとうございました。
早速、値の確認する箇所などを検討して行きたいと思います。

ちなみに、先ほども、値の確認をさせることでバグが一つ見つかりました。

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