初心者が迷ったReactivePropertyを使用した数値型の処理
Modelの型が数値型のプロパティは、TextBoxにバインドするときにはView Modelで文字列型に変換するという話をしました。
しかし、単純に、数値型といっても整数型、浮動小数点型、固定小数点型など、いろいろある。
Parseメソッド、TryParseメソッドで文字列を数値型に変換する場合に注意しないといけないことは、以下の例外の発生条件です。
- FormatException
https://msdn.microsoft.com/ja-jp/library/system.formatexception(v=vs.110).aspx
- OverflowException
https://msdn.microsoft.com/ja-jp/library/system.overflowexception(v=vs.110).aspx
数値型の変換に関しては以下の情報がある。
NumberStyles 列挙体 (System.Globalization)
何が言いたいかというと、
- 整数型のParseメソッドはデフォルトでは小数点を受け付けないので、小数点を受け付けるNumberStylesを使う
- 一般ユーザの感覚として、本当に整数型が妥当かどうかも怪しいデータの入力で小数点のチェックに引っかかるというのはバグにしか見えない
- 出来れば桁区切り文字も受け付けるNumberStylesを指定した方が更に親切
- カンマとピリオドの意味が入れ替わる国もあるので、一応国際化対応は考慮しておいた方が良い
- ヨーロッパ人が1.500のつもりで1,500を入れたら1500になった
- ヨーロッパ人が1500のつもりで1.500を入れたら1.500になった
- すべて良くある話
- スイスのように1つの国で何パターンもある国もあるので、OSの設定に連動するとか、UIのCultureInfoをユーザが設定できるようにすると良い
- 範囲チェックの前にオーバーフローに引っかかる可能性がある
- 一般ユーザの感覚として、範囲チェックの前に数値型のMinValue/MaxValueのチェックに引っかかるというのはバグにしか見えない
- intは整数部が9桁を超えたときにオーバーフローが発生する場合がある
- longは整数部が18桁を超えたときにオーバーフローが発生する場合がある
- floatは整数部が7桁を超えたときにオーバーフローが発生する場合がある
- doubleは整数部が15桁を超えたときにオーバーフローが発生する場合がある
- decimalは整数部が28桁を超えたときにオーバーフローが発生する場合がある * unsigned型で負の数を入力したとき
ということ。
いろいろ考えると、これからプロジェクトにWPF+MVVM+ReactivePropertyを入れるなら以下の方針にするのが良いと初心者なりに思った。
- 変換とチェックの拡張メソッドを作っておくのが無難
- 入力するデータはdecimalで一旦受けることを検討
- 整数は小数点以下の桁数が0のdecimalである
- 一番有効桁数が多く丸め処理が細かく出来るdecimalで検証後に必要な精度に丸めてキャストする
- いろんな型の拡張メソッドを作るより分かりやすい
- 実装方法が統一できるので使いまわしができる
- 有効桁数や型変更などの仕様変更に強い
- 天文学的数値を扱うときのみdoubleを使用するが、そもそも指数表記で入力するケースはあまりない
まあ、バカチョンでもユーザに怒られないなら、何も考えずにModelの型を使ったら良いです。
いわゆる個別対応って奴ですね。
つづく。