- PR -

型変換制御(Option Strict)について

投稿者投稿内容
だんじり
大ベテラン
会議室デビュー日: 2007/08/10
投稿数: 155
お住まい・勤務地: 神奈川県
投稿日時: 2007-10-09 15:29
Visuai Basic 2005 Exprese Edition でWindowsアプリケーションを開発しています。
開発も山を越えたところですが、最初にプロジェクトデザインのコンパイルで暗黙的
な変換をエラーに設定(Option Strict を ON)するのを忘れ、規定値の「なし」で
進めてきました。そこで「エラー」に設定変更を行いデバッグしましたら、次のよう
なエラーが102個も表示されてしまいました。
→→「Object' から 'String' への暗黙的な変換です。」
さらに最後の行には「エラーの最大数の制限を越えました(102)」と表示されています

質問したいのは、次の2つです。

1.エラー箇所の修正を次のように行いましたが問題はありませんか?
Integerへの変換→CInt(SS)
Stringへの変換→NN.ToString
Booleanへの変換→CBool(NN)
正常に動作していますが"NN.ToString"以外はオブジェクト指向でないような気がします
もっとスマートな方法があれば教えてください。

2.下のコードに「Double' から 'Boolean' への暗黙的な変換です」エラーが出ます
→If dreader(2) = 誕生日 And dreader(3) = True Then
どのように修正すればよいもでしょうか?

以上よろしくお願いします。

よねKEN
ぬし
会議室デビュー日: 2003/08/23
投稿数: 472
投稿日時: 2007-10-09 15:58
引用:

1.エラー箇所の修正を次のように行いましたが問題はありませんか?



問題がないかどうかは修正対象箇所で行おうとしている内容次第ですので、
一概に正しい/正しくないということはコメントできません。
内容を確認する上での観点を挙げますので、一つ一つ内容をご自身でご確認ください。

引用:

Integerへの変換→CInt(SS)



変数SSのデータ型はなんですか?
また、そこに渡される値の内容と型はどういうものが想定されますか?
その辺を踏まえて状況を判断する必要があります。

例えば、SSというのが整数値を表す文字列が入っているのであれば、
Int32.Parseメソッド(やInt32.TryParseメソッド)を使うのが適切でしょう。

例えば、SSがObject型の変数にInt32型の値が入っている前提なら、
CIntでよいと思います。

例えば、SSにDouble型の値が入っているのなら、値をどのように丸めるのかを
意識して適切に変換する必要があるでしょう。

引用:

Stringへの変換→NN.ToString



正確にはToStringメソッドは文字列への変換を行うメソッドではありません。
あるオブジェクトに対する文字列表現を返すメソッドです。
例えば、変数NNが列挙型の場合、ToStringメソッドの結果とCStr関数による変換の
結果は異なる結果になります。

また、変数NNがObject型で、その中に文字列が入っているのであれば、
DirectCastキーワードを使うのが適切でしょう。

NNの型と実現したいことによってはToStringメソッドが適切な場合もあると思います。

引用:

Booleanへの変換→CBool(NN)



Booleanへのキャストという意味あいであれば、DirectCastキーワードが適切かと思います。
"True"という文字列とそれ以外などからの変換なら、Boolean.Parseメソッド(またはBoolean.TryParseメソッド)
を使うのがよいと思います。
また、VB6以前との互換性が必要な場合は、CBool関数を使うことになるかと思います。

引用:

正常に動作していますが"NN.ToString"以外はオブジェクト指向でないような気がします
もっとスマートな方法があれば教えてください。



オブジェクト指向的かどうかより、行っている処理が違ってきますので、
行いたい変換の内容と合致した変換方法を採用しましょう。

引用:

2.下のコードに「Double' から 'Boolean' への暗黙的な変換です」エラーが出ます
→If dreader(2) = 誕生日 And dreader(3) = True Then
どのように修正すればよいもでしょうか?



dreaderというのは何ですか?
#変数名からだいたいの想像は付きますが。
先ほどの説明を踏まえて内容に応じた変換を行ってください。

以下のキーワードについても調べてみることをお勧めします。

CType関数、DirectCast/TryCastキーワード、
(さまざまなクラスに用意されている)Parse/TryParseメソッド、
値型、参照型、ボクシング/アンボクシング
じゃんぬねっと
ぬし
会議室デビュー日: 2004/12/22
投稿数: 7811
お住まい・勤務地: 愛知県名古屋市
投稿日時: 2007-10-09 16:36
何だか元質問者さまは Cast と Convert を混同してらっしゃる様子。 型変換するならば TryCast ステートメントでしょう。 Parse なら TryParse メソッドです。 最初はこの 2 点を覚えていればよいでしょう。 変換自体は CInt でもできますけど検証のことを考える必要があります。 型に合わせた検証は難しいものです。

ToString メソッドを使う/使わないがオブジェクト指向うんぬんと関わるという発想は違和感があります。 使い分けに関しては、変数の箱の型とデータの中身の型を意識すると使い分けの場面もよくわかるはずですけどね。 ついでに、Option Strict を "型変換制御" と呼んでしまうのも違和感があります。

_________________
C# と VB.NET の入門サイト
じゃんぬねっと日誌
だんじり
大ベテラン
会議室デビュー日: 2007/08/10
投稿数: 155
お住まい・勤務地: 神奈川県
投稿日時: 2007-10-09 17:04
よねKENさん、早速ご丁寧なご指導ありがとうございます。
なにぶんACCESSしか使ったことがなく、Visuai Basic 2005での最初の開発のために
型指定の厳しさに驚いています。

変換しようとしている変数のデータ型、及び変換先に渡す値の内容と型によって判断す
る必要がるようですね。オブジェクト指向的より、行っている変換の内容と合致した
変換方法かが重要なことも理解できました。全く勉強不足で申し訳ありません。
とりあえず暗黙的な変換を規定値にしておき、次のことについてもう少し勉強します。

Int32.Parseメソッド(やInt32.TryParseメソッド)
Double型の場合は値のに丸めるのかを意識して適切に変換

変数NNが列挙型の場合、ToStringメソッドの結果とCStr関数による変換の結果は異なる
変数NNがObject型でその中に文字列が入っている場合はDirectCastキーワードを使う
NNの型と実現したいことによってはToStringメソッドが適切な場合もあると

Booleanへのキャストという意味あいであれば、DirectCastキーワードが適切
Boolean.Parseメソッド(またはBoolean.TryParseメソッド)
CType関数、DirectCast/TryCastキーワード、
(さまざまなクラスに用意されている)Parse/TryParseメソッド、
データ型変換に関する勉強のキーワードがつかめました。
よねKENさん、ありがとうございました。
じゃんぬねっと
ぬし
会議室デビュー日: 2004/12/22
投稿数: 7811
お住まい・勤務地: 愛知県名古屋市
投稿日時: 2007-10-09 23:59
引用:

だんじりさんの書き込み (2007-10-09 17:04) より:

なにぶんACCESSしか使ったことがなく、Visuai Basic 2005での最初の開発のために型指定の厳しさに驚いています。


Access は VBA ですから型指定できる言語ですよね。 VB.NET の Option Strict オプションのようなものは確かにありません。

引用:

変換しようとしている変数のデータ型、及び変換先に渡す値の内容と型によって判断す
る必要がるようですね。


変数自体の型とデータの中の型という意味なら間違いではないです。

引用:

変数NNがObject型でその中に文字列が入っている場合はDirectCastキーワードを使う


ここまで限定的な条件ではないと思いますよ。 このあたりはアップキャストとかダウンキャストを調べると吉なのかもしれません。

引用:

Booleanへのキャストという意味あいであれば、DirectCastキーワードが適切


これはどうでしょうね。 Boolean 型に変換したことがないのでわかりません。 2 値でかつ相反するものを示しているのですから、普通に If (2 つ (true か false) に分岐する) で判定してしかるべき値を入れた方が安全だとおもいますね。 そもそもそういった場面さえも少ないと思います。

_________________
C# と VB.NET の入門サイト
じゃんぬねっと日誌
Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2007-10-10 06:32
本筋から外れるところでひとつ。

引用:

2.下のコードに「Double' から 'Boolean' への暗黙的な変換です」エラーが出ます
→If dreader(2) = 誕生日 And dreader(3) = True Then
どのように修正すればよいもでしょうか?


「AndAlso」を使いましょう。
 And は、式の両方を評価します。いま、「dreader(2) not equal 誕生日」の場合、「dreader(3) = True」の評価は必要ないはずです。この場合、「dreader(2) = 誕生日 AndAlso dreader(3) = True」とすることで、左の評価が否の時、右の評価をショートカットできます。

 これだとあまりメリットがないようですが、このように使うと、どうでしょう?
If (Not dreader(2) = DbNull.Value) AndAlso dreader(2) = 誕生日 Then

 DbNull は、おそらく DateTime 型であろう「誕生日」と比較できないと思います。実行時にキャスト例外が発生すると思う。それを回避できます。And だと、両方評価されるので、例外がスローされます。

# 「OrElse」



あれ?DbNull.Value との比較は = でよかったっけ?

[ メッセージ編集済み 編集者: Jitta 編集日時 2007-10-10 06:35 ]
よねKEN
ぬし
会議室デビュー日: 2003/08/23
投稿数: 472
投稿日時: 2007-10-10 09:25
引用:

じゃんぬねっとさんの書き込み (2007-10-09 23:59) より:
引用:

Booleanへのキャストという意味あいであれば、DirectCastキーワードが適切


これはどうでしょうね。 Boolean 型に変換したことがないのでわかりません。 2 値でかつ相反するものを示しているのですから、普通に If (2 つ (true か false) に分岐する) で判定してしかるべき値を入れた方が安全だとおもいますね。 そもそもそういった場面さえも少ないと思います。



補足になりますが、「Booleanへのキャストという意味あい」というのは、

Dim b As Boolean = True
Dim o As Object = b
Console.WriteLine(DirectCast(o, Boolean))

というようなパターンを指しています。
確かに自分の書くコードではこのようなパターンを使うことはめったにありませんね。
#例えば、型付データセットの場合、自動生成されたコードの中でCType関数で同様のことをしています
だんじり
大ベテラン
会議室デビュー日: 2007/08/10
投稿数: 155
お住まい・勤務地: 神奈川県
投稿日時: 2007-10-10 10:10
じゃんぬねっとさん、いつもお世話になります。
ご指摘の「Cast と Convert」について理解していません。また「型変換するならば
TryCast ステートメントで、Parse なら TryParse メソッド」であることも理解でき
ていません。早速、開発を中断して勉強します。

Jittaさん、先ほど「TextBoxで文字が消える」でもお世話になりました。
「AndAlso」及び「OrElse」 についてのご指導ありがとうございます。2005から使用
できるようになったそうですね。今後は後方の評価が不要な場合は使うようにします。

ところで、2番目の質問の「Double' から 'Boolean' への暗黙的な変換です」エラー
ですが、次のように評価片方にするとエラーが出ないのですが両方にするとエラーにな
ります。変換のエラーならどちらかで発生すると思いますが、なぜなのでしょうか?
前評価のみ→If dreader(2) = 誕生日 Then
後評価のみ→If dreader(3) = True Then
ヒントだけでも教えていただければ自分自身で勉強します。

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