- PR -

VBの日付型と暗黙の型変換

投稿者投稿内容
autumn
大ベテラン
会議室デビュー日: 2001/07/27
投稿数: 215
投稿日時: 2002-04-11 15:44
 ごめんなさい。もう1つ間違いがありました。
誤: DateTimeクラス
正: DateTime構造体
_________________
object
ぬし
会議室デビュー日: 2002/03/20
投稿数: 338
お住まい・勤務地: 香川県高松市
投稿日時: 2002-04-11 16:13
私は、コードが間違っていると言っているのではありません。
川俣さんもVB6のコードがVB.NETでは、どうなるかに付いて書いておられるので、完全に間違っておられる訳ではないと思います。

話の要点を簡単に整理しましょう。

コード
Dim d As Date
d = "2002/04/01"
に対して

VB6で
"2002/04/01"
と表示されてたものが、

VB.NETでは、
"2002/04/01 0:00:00"
と出力されてしまう。

訳ですよね。

それで、Date型には時刻情報があるにも係わらず、VB6では表示されない。設定もされていない。(デフォルトの設定値があるのなら別なのですが…でも、その時でも意識は必要だと思います。)
これは、値型、参照型に係わらず、あらゆるインスタンス値の決定に於いて、その構成要素に対する自覚が薄い可能性があるという事ではないでしょうか?

例え
Dim d As Date
d = "2002/04/01"
と2行に分けて書いていようが、その自覚が薄ければ意味が無いと思います。
逆に、意識の無いままに、一見問題のなさそうなコードがあるという事が問題を大きくすると思います。

そういう意味では、川俣さんの指摘は、VB6の意識のままでは駄目だよとという例を具体的に書いて示したんだと思います。

それから、私は、
「C++のあらゆるインスタンスは「コンストラクション」処理される。」
と考えていると思っています。それをプログラマが明示的に行うか、コンパイラが暗黙的に行うかは別にしてです。また、それがヒープかスタックか、何処にあるか関係なく、また実装レベルの詳細とも関係なくです。
これは、見解の違いかもしれません。

引用:NothingBut.NETFXさんの書き込み (2002-04-11 15:03) より
--------------------------------------------------------------------------------
このお言葉自体には同感ですが、それでは川俣さんのコード例(またはVB6/VB.NET一般)のどこが「プログラマの意志を必ずしもコンパイラに伝えきれていない」点なのでしょうか?
--------------------------------------------------------------------------------
私が言いたかったのは、上でも書きましたが、時刻に関する設定と表示に関してです。
(もちろん、あのコード例で、VB.NETユーザーが異なる表示に悩んだという事が前提で考えていますけど。)

「プログラマの意志をコンパイラに明確に伝え、コンパイラに仕事をさせる。」
これは、C++で初めて明確にされた考えであると思います。
私は、VB6ユーザーの方にも、これを自然に理解してもらう事は大切だと思います。

NothingBut.NETFXさんは VB6 の意識のままで VB.NET を使用していくのを推奨されるのですか?
NothingBut.NETFX
大ベテラン
会議室デビュー日: 2001/09/13
投稿数: 102
投稿日時: 2002-04-11 17:00
引用:

objectさんの書き込み (2002-04-11 16:13) より:
それで、Date型には時刻情報があるにも係わらず、VB6では表示されない。設定もされていない。(デフォルトの設定値があるのなら別なのですが…でも、その時でも意識は必要だと思います。)


残念ながらこのご理解が間違いです。VB6で表示されないからといって、どうして設定されていないということになるんでしょう?そう、危惧された通り、デフォルトの設定値があります。VBのデータ型はすべて宣言と同時に初期化されるのです。これはVBの常識です。次のコード(VB6)を実行したら何が表示されると思いますか?

コード:
	Dim d As Date
	d = "2002/04/01"
	Debug.Print Format(d, "yyyy/MM/dd hh:mm:ss")


こういう常識がコミュニティ内に存在しますから、

引用:

これは、値型、参照型に係わらず、あらゆるインスタンス値の決定に於いて、その構成要素に対する自覚が薄い可能性があるという事ではないでしょうか?


ということにはなりません。Stringは""で初期化され、Integerは0で初期化されているという自覚があるのです。ある意味これはC++でクラス変数を自動変数として宣言するとコンストラクタが呼ばれるのと同じです。VBは超高級言語なので、それを勝手にやってくれるんです。VBユーザーはそういう自覚をしています。自覚がないわけではありません。

引用:

そういう意味では、川俣さんの指摘は、VB6の意識のままでは駄目だよとという例を具体的に書いて示したんだと思います。


ですから、川俣さんの例ではVB6ユーザーの常識がそのまま通用しているのです。すでにスレの冒頭でリックスさんが指摘されている通り、これは文字列表現の問題であって内部データ構造の問題ではないのです。

引用:

それから、私は、
「C++のあらゆるインスタンスは「コンストラクション」処理される。」
と考えていると思っています。それをプログラマが明示的に行うか、コンパイラが暗黙的に行うかは別にしてです。また、それがヒープかスタックか、何処にあるか関係なく、また実装レベルの詳細とも関係なくです。
これは、見解の違いかもしれません。


つまり、int i = 0; はコンストラクション処理であるということですか?それなら確かに私の理解とは違います。

引用:

「プログラマの意志をコンパイラに明確に伝え、コンパイラに仕事をさせる。」
これは、C++で初めて明確にされた考えであると思います。
私は、VB6ユーザーの方にも、これを自然に理解してもらう事は大切だと思います。


脱線しますが、私はC++の構文によってコンパイラに明確に意思を伝えられているとは到底思えません。

引用:

NothingBut.NETFXさんは VB6 の意識のままで VB.NET を使用していくのを推奨されるのですか?


どうもこのご発言から推測するに、VBユーザーはみんなイチから勉強しなおせ!ってことですか?だとしたら「...」としか言いようがないですね。

VB.NETはVB6とはいろいろな点で異なる言語ですから、VB.NETをやろうと思ったらそれが前提とするさまざまな事柄を知らずに済ませるわけにはいかないと思いますよ。でもJavaユーザーはVB.NETをやるときに何も考えずにJavaの意識のままでいいんですか?C++ユーザーは?Delphiユーザーは?みんな同じです。

「VB6の意識」というのが相当希薄なものだと思われているのだと思いますが、そんなことはぜんぜんありません。よしんばobjectさんの周りの「VB6の意識」がそうであったとしても、それは人間の問題であってVB6の問題ではありませんし、VB6ユーザー一般に当てはまる仮定でもありません。
object
ぬし
会議室デビュー日: 2002/03/20
投稿数: 338
お住まい・勤務地: 香川県高松市
投稿日時: 2002-04-11 18:28
話をまたまた整理します。

コード
Dim d As Date
d = "2002/04/01"
に対して

VB6では
--------------------------------------------------------------------------------
Debug.Print d
出力で
"2002/04/01"
--------------------------------------------------------------------------------
と表示されてたものが、


VB.NETでは、
--------------------------------------------------------------------------------
Trace.WriteLine(d)
出力で
"2002/04/01 0:00:00"
--------------------------------------------------------------------------------
と表示される。

でも、同じ初期化をして、同じ出力をして、何で表示が違うのですか?
これに対して、実装が違うというのが答えということですよね。

でも、何故実装を変える必要があったのですか?
これこそ問題にすべきではないですか?

想像でものをいうのは、駄目だと思いますけど、
VB6 では、時刻情報が初期化されてないのを、VBが知っているのでは?
だから、時刻情報が表示されない。
それが VB.NET 初期化された値か、初期されてない値か分からない。
.NET に於ける初期化と、今までの VB6 の初期化とマッチングしてないというこではないでしょうか?

それから、VB6 と同じコーディングをして、個々に実装レベルの違いを理解しながら、VBプログラマが仕事をしていくというのは、大変な負担だと私は思います。
何でもデフォルトで初期化するといのも危険だと思います。

最後に、話の対象を個々の VB6 ユーザに置き換えるのは、話の内容を変えていると思います。
私は VB6 がオブジェクト指向を完全にはサポートしていないという事実から VB.NET を如何に考えるかを純粋に考えているつもりです。
autumn
大ベテラン
会議室デビュー日: 2001/07/27
投稿数: 215
投稿日時: 2002-04-11 18:39
引用:

それで、Date型には時刻情報があるにも係わらず、VB6では表示されない。


 余談ですが、VB6で、
コード:
Private Sub Form_Load()
    Dim a As Date, b As Date
    a = "2001/01/01 00:00:00"
    b = "2001/01/01 00:00:01"
    Debug.Print a
    Debug.Print b
End Sub


 の実行結果は
引用:

2001/01/01
2001/01/01 0:00:01


 です。
 VB6って変な言語でしょう? 他にも変なことはいっぱいあります。正数をstrで文字列に変換したときに先頭に入る空白文字とか。「どうして?」と質問されて答えに窮することもしばしば。
object
ぬし
会議室デビュー日: 2002/03/20
投稿数: 338
お住まい・勤務地: 香川県高松市
投稿日時: 2002-04-11 18:55
引用:autumnさんの書き込み (2002-04-11 18:39) より
--------------------------------------------------------------------------------
余談ですが、VB6で、
コード:
--------------------------------------------------------------------------------
Private Sub Form_Load()
Dim a As Date, b As Date
a = "2001/01/01 00:00:00"
b = "2001/01/01 00:00:01"
Debug.Print a
Debug.Print b
End Sub
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
autumnさん、そうなんですか!
私の投稿(2002-04-11 18:28)また間違いました。
矢張り、想像で書くと駄目ですね。
済みませんでした!
でも、問題にしたかったのは、一貫性の無さですので、許して下さい。
(デフォルト処理は、特に一貫性が重要だと思います。)
NothingBut.NETFX
大ベテラン
会議室デビュー日: 2001/09/13
投稿数: 102
投稿日時: 2002-04-11 19:24
引用:

objectさんの書き込み (2002-04-11 18:28) より:
でも、同じ初期化をして、同じ出力をして、何で表示が違うのですか?
これに対して、実装が違うというのが答えということですよね。


違います。何度も書いてあるとおり文字列表現のデフォルトが変わったんです。Dateの内部が変わったこととは関係ありません。

引用:

それから、VB6 と同じコーディングをして、個々に実装レベルの違いを理解しながら、VBプログラマが仕事をしていくというのは、大変な負担だと私は思います。
何でもデフォルトで初期化するといのも危険だと思います。


すみません、意味がわかりません。VB6と同じコーディングをしたらだめだ、ということ自体は川俣さんの記事のメインテーマだと思いますし、そのことに反対はしていません。このスレは、あくまでも日付に関する記述の話です。で、川俣さんのかかれた内容には誤解があるのでは?というリックスさん(と私)の問いに対して、川俣さんがそれをお認めになっているにもかかわらず、objectさんは「〜という説明も間違いではないと思います。 」とおっしゃっているので、「いいえ、これは間違いです。」と言い続けているだけです。

引用:

最後に、話の対象を個々の VB6 ユーザに置き換えるのは、話の内容を変えていると思います。


あの、それじゃこの話↓は?
引用:

私は、VB6ユーザーの方にも、これを自然に理解してもらう事は大切だと思います。

NothingBut.NETFXさんは VB6 の意識のままで VB.NET を使用していくのを推奨されるのですか?


VBユーザーが何かを理解していないというご主張だったと思いますが、私はそれに対して、VBユーザー一般が何かを理解していないということと、今このスレで問題にしているDateにかかわるコードの例とは何の関係もないという主張をしています。

引用:

私は VB6 がオブジェクト指向を完全にはサポートしていないという事実から VB.NET を如何に考えるかを純粋に考えているつもりです。


ですから、VB6でもVB.NETでもDate/DateTimeの初期化方法は同じなんです。宣言と同時に値がすべて0で埋められた状態になります。その後で値が設定されれば、設定された部分(今回であれば年月日)だけが更新されているんです。その後に、現在のオブジェクトの状態を文字列でどう表現するのかが、VB6からVB.NETで変わったということです。こんな変更はVB6がオブジェクト指向を完全にサポートしていないということと何の関係もありません。

引用:

でも、問題にしたかったのは、一貫性の無さですので、許して下さい。
(デフォルト処理は、特に一貫性が重要だと思います。)


デフォルト処理に一貫性がないとおっしゃられているのはどの部分ですか?変数は宣言と同時にすべてゼロで埋めるというのは十分一貫性がありますね。autumnさんのご発言の例のことをおっしゃっているのでしたら、何度も何度も書きますが、これはDateの文字列化アルゴリズムがそういう決まりで作られているからであって、VB6の意識とかオブジェクト指向とかは一切関係ありません。
object
ぬし
会議室デビュー日: 2002/03/20
投稿数: 338
お住まい・勤務地: 香川県高松市
投稿日時: 2002-04-12 00:12
引用:

NothingBut.NETFXさんの書き込み (2002-04-11 19:24) より:
違います。何度も書いてあるとおり文字列表現のデフォルトが変わったんです。Dateの内部が変わったこととは関係ありません。


私も、Dateの内部が変わったことと関係があるとは言ってません。同じ事を言ってると思います。


引用:

ですから、VB6でもVB.NETでもDate/DateTimeの初期化方法は同じなんです。宣言と同時に値がすべて0で埋められた状態になります。その後で値が設定されれば、設定された部分(今回であれば年月日)だけが更新されているんです。その後に、現在のオブジェクトの状態を文字列でどう表現するのかが、VB6からVB.NETで変わったということです。こんな変更はVB6がオブジェクト指向を完全にサポートしていないということと何の関係もありません。



そうなんですか?
VB6と同じ初期化方法しかないんですか?
それでは、次の様なコーディング

Dim d2 As Date
d2 = New DateTime(2002, 4, 1, 0, 0, 0, 0)
Trace.WriteLine(d2)
Trace.WriteLine(d2.ToString("yyyy'年'MM'月'dd'日'"))

はどうなんですか?。
私には、こちらの方がスッキリ来ます。

でも、大体この辺で終わりにしましょう。

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