2007年8月8日水曜日

数値のソート

実際にソートして例外見るまで気づかなかった。
今のところ拡張したDataGridViewの数値用セルではValueTypeをNullable(Of Decimal)に固定してはいるんだけど、実際にValueプロパティに設定される値はDecimalであることは保障されないのよね。これがデータバウンドとかValueプロパティでTypeConverter使うぞとか、そういった方式を利用しているなら「ありえねー」ってことで一蹴できたんだけど、今回の様に全てをアンバウンドで行っている以上は、必ず発生するんだよな、これが。

簡単に書くと次のようなケース。
DataGridView1.Rows(0).Cells(0).Value = 10000
DataGridView1.Rows(0).Cells(0).Value = 100000
こう書いた場合、最初の行はIntegerで入ってくるんだな。次の行はIntegerの限度を超えているのでLongとかDecimalに変換されて入ってくる。さて、こういった場合にどんな問題が起きるか?というと。
Dim originalValueInstance As Object = originalCell.Value
Dim comparedValueInstance As Object = comparedCell.Value
Dim execCellValue As IComparable = TryCast(originalValueInstance, IComparable)
Dim result As Integer = execCellValue.CompareTo(comparedValueInstance)
こんな風に比較ロジックを書いた場合に例外が出てしまうんだな。というのも、originalValueInstance とcomparedValueInstance の型が異なっているから。originalValueInstance がIntegerで、comparedValueInstance がDecimalなんてことになった場合、CompareToメソッド呼び出しのところで「二つの型が一致しねぇ!」と怒られてしまうわけだ。
さてどうすっか、と言われると「どちらかの型に変換して比較する」となるんだよね。幸いにもConvertクラスなんてものが用意されているのでこれを利用すれば型の統一は可能。ただ問題点が一つ。
AとB、大きい値が入る型はどっちだ?
型からインスタンス生成して数値系の型でほとんど実装されているMaxValueプロパティの値を比較するってのもあるけど、そもそもAもBも数値なのか?という点ではどうしても力技になってしまうんだよね。それなら最初から力技でやってしまっても、そうそう変わらないんじゃないかなぁ・・・と思ったり。
符号のありなしで困るんだけどね、どっちにしても。

0 件のコメント:

コメントを投稿