- PR -

shared な変数の参照

投稿者投稿内容
よねKEN
ぬし
会議室デビュー日: 2003/08/23
投稿数: 472
投稿日時: 2008-12-31 14:45
Jittaさんの2008-12-30 23:00の投稿(後半部分)の意図が、私も分かりかねるところがあるので、
(じゃんぬねっとさんの話ともかぶりますが)、コメントしたいと思います。

引用:

Jittaさんの書き込み (2008-12-30 23:00) より:
Shared:
インスタンス間で共通の、ただ一つの値を持つ変数となります。このため、あるインスタンスAでは、たとえば「開始年月日」を2005年1月1日としておきたいのに、別のインスタンスBのために2008年1月1日に変えてしまうと、Aでも2008年1月1日になってしまいます。ダイアログなので、一時に1枚しか表示されませんが、ダイアログ フォームのインスタンス(OpenDialog で開いたとき)は Close メソッドをコールしても Dispose は呼ばれないため、使い回しができます。使い回しを行うときに、問題になるかもしれません。
もちろん、毎回 ShowDialog する直前で設定していれば問題にはなりません。



まず話の大前提として、このJittaさんのこの部分の説明は、
スレ主の武史さんの「投稿日時: 2008-12-26 21:19」の投稿を受けてのコメントですよね。
以前のスレ主の投稿からだいぶ間があいているので、そういうことを明示しておいて頂けると助かります。
(私は最初、何で急に「ダイアログ」という言葉が出てきたのかわからず、スレ主の投稿でダイアログが出てくる投稿を探しました)

その上でこの説明を理解するための前提として、
Form継承クラスのインスタンスを表示するために、

(1) Showメソッドで表示(モードレスで表示)
(2) ShowDialogメソッドで表示(モーダルで表示)

の2つの方法があり、これらの方法には1つのインスタンスを
使いまわせるか/使いまわせないかの違いがあるという点がポイントなんですよね?

<(1)と(2)でフォームの使いまわしができるかどうかの違いが発生する技術的理由>
(1)で表示した場合は、Closeメソッドを呼び出すと(内部でDisposeメソッドが呼ばれて)そのインスタンスは再使用できません。
(2)で表示した場合は、Closeメソッドを呼び出しても(内部でDisposeメソッドが呼ばれないため)そのインスタンスは再使用できます。

ということがJittaさんがおっしゃりたいことの話の前提だと思いますが、合ってますか?

ここまでの理解が合っているとして、
本題は、武史さんの「投稿日時: 2008-12-26 21:19」にあるコード例を見ます。

引用:

武史さんの書き込み (2008-12-26 21:19) より:

コード:

Class 一年分のカレンダーを表示するカレンダーダイアログ
Shared Private 開始年 As Integer
Shared Private 開始月 As Integer
Shared Private 開始日 As Date

Public Sub 開始年月設定
Me.開始年 = Me.開始日.Year
Me.開始月 = Me.開始日.Month
End Sub
End Class






Jittaさんはダイアログ((2)の方法で呼び出し)か、そうでないかで
1つのインスタンスを使いまわせるかどうかの違いを強調されているようですが、
そもそも複数のインスタンスを使われれば、上記コード例のように共有メンバーを使う方法は、十分に注意してコーディングしないと問題になるのでは?

#結果的にじゃんぬねっとさんと同じ指摘をしているような・・・(汗

--
<追記>
コード例にダイアログとあるので、ShowDialogメソッドで呼ばれる(=普通はダイアログ用のインスタンスを1度に1つしか作らない)という前提でJittaさんはお話をされているんですかね。

でも、ダイアログだからと言って、Showで使わないとは言い切れないので、やはり、複数インスタンスを生成する場合は考慮対象に入れないといけないと私は思います。
</追記>


[ メッセージ編集済み 編集者: よねKEN 編集日時 2008-12-31 15:46 ]
Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2009-01-03 18:02
引用:

じゃんぬねっとさんの書き込み (2008-12-31 01:08) より:
引用:

は Close メソッドをコールしても Dispose は呼ばれないため、使い回しができます。使い回しを行うときに、問題になるかもしれません。
もちろん、毎回 ShowDialog する直前で設定していれば問題にはなりません。


これはどういう意味なのでしょうか? 共有メンバ (C# では静的メンバ) はインスタンスの Dispose メソッドとは何ら関係がないので、Dispose メソッドが呼ばれないことによって問題になるという発想はおかしいと思います。


一つのインスタンスを使いまわししている分には、問題はないでしょう。「開始年月日」という名前から、カレンダーを表示しているダイアログで、そのカレンダーで設定可能な最古日であると思われます。同様に、「終了年月日」のような最新日を設定するメンバーもあると思われます。
そういうダイアログを何のために使うと考えると、「日付による検索」の、開始日と終了日を指定するために用いることが考えられます。終了日のほうには、開始日で指定したよりも後の日付で、今日までの日付が設定可能と考えるのが妥当でしょう。そうすると、開始日指定ダイアログと、終了日指定ダイアログがあることが予想されます。
この2つのダイアログを、2つのインスタンスで使いまわししている時、クラス変数ですから、同じ値を参照することになります。これは、問題とならないでしょうか。
もし、Dispose するように作っていれば、「Dispose したのだから、新たに設定しなければならない」と思うでしょう。ですから、クラス変数の性質を理解せずに、複数のインスタンスを使用しているなら、Dispose しないことで問題となるでしょう。
じゃんぬねっと
ぬし
会議室デビュー日: 2004/12/22
投稿数: 7811
お住まい・勤務地: 愛知県名古屋市
投稿日時: 2009-01-03 22:40
引用:

Jittaさんの書き込み (2009-01-03 18:02) より:

一つのインスタンスを使いまわししている分には、問題はないでしょう。「開始年月日」という名前から、カレンダーを表示しているダイアログで、そのカレンダーで設定可能な最古日であると思われます。同様に、「終了年月日」のような最新日を設定するメンバーもあると思われます。
そういうダイアログを何のために使うと考えると、「日付による検索」の、開始日と終了日を指定するために用いることが考えられます。終了日のほうには、開始日で指定したよりも後の日付で、今日までの日付が設定可能と考えるのが妥当でしょう。そうすると、開始日指定ダイアログと、終了日指定ダイアログがあることが予想されます。
この2つのダイアログを、2つのインスタンスで使いまわししている時、クラス変数ですから、同じ値を参照することになります。これは、問題とならないでしょうか。
もし、Dispose するように作っていれば、「Dispose したのだから、新たに設定しなければならない」と思うでしょう。ですから、クラス変数の性質を理解せずに、複数のインスタンスを使用しているなら、Dispose しないことで問題となるでしょう。


(内容が理解できているか不安ですが) えっーと、Dispose メソッドはインスタンスに対してであるのに、共有メンバと混同すると? 共有メンバを理解できていない人が 'わざわざ' static | Shared というキーワードはつけると? もしくはその意味さえ理解できずに使ってしまうような方がいるということですか? 違いがわからない人はそもそもインスタンスを理解できていない、ストレートに言ってしまえば思考回路が停止しているような方ですよね? Dispose メソッドがあってもなくても何も考えることができないので結果としては変わらないのでは?

仮にそのような類稀なる生兵法コーダが存在するとして、これまでの話の流れについてはやはり理解ができないです。 「勘違いしていました」 の方がしっくりと理解できそうだとも思ったのですが、そもそも私が内容をきちんと理解できていない可能性もあります。 私ではレベルが足らないということかもしれません。 あとは同じことを指摘してそうなよねKENさんにお任せしたいと思います。

# ここ最近いろんなところで他人の文章が理解できないです。orz

_________________
C# と VB.NET の入門サイト
じゃんぬねっと日誌
べる
ぬし
会議室デビュー日: 2003/09/20
投稿数: 1093
投稿日時: 2009-01-05 22:30
あら、自分が書き込んだスレが進んでいたことにまったく気づいてなかった。

私が2008-12-26 10:04でリンクを張ったのは、Jittaさんが
「静的であることを示すのは、アプリケーション ハンガリアンだと思います。」
と書いているのに対して、未記入さんが「ハンガリアン記法って、・・・」と書いていたので、
「ハンガリアン記法」という言葉とはイコールでない「アプリケーション ハンガリアン」という言葉が
ありますということを、未記入さんだけにというわけではなく、後に議論を続ける方々や
後にここを見る方々に示すために書きました。
そう書けばよかったですね。私が元で不快な思いをした方々、すいません。

引用:
ところで、あなたは日本語を母国語とされている方でしょうか?

はい。ただ、実際に日本語を母国語としていなくても(ちゃんとした日本語を使って)
ここを利用している方もいることと思いますし、こういう書き方はよくないと思います。
Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2009-01-05 22:57
引用:

じゃんぬねっとさんの書き込み (2009-01-03 22:40) より:
(内容が理解できているか不安ですが) えっーと、Dispose メソッドはインスタンスに対してであるのに、共有メンバと混同すると? 共有メンバを理解できていない人が 'わざわざ' static | Shared というキーワードはつけると? もしくはその意味さえ理解できずに使ってしまうような方がいるということですか? 違いがわからない人はそもそもインスタンスを理解できていない、ストレートに言ってしまえば思考回路が停止しているような方ですよね? Dispose メソッドがあってもなくても何も考えることができないので結果としては変わらないのでは?


以下に書くことが、質問者さんに当てはまるかどうか、わかりません。しかし、ここしばらくの間に2〜3の掲示板でされている複数の質問から、ウェブ掲示板に投稿される質問に、次のような傾向があるように思います。

1.マネージド リソースと、アンマネージ リソースの混同
 「タスクマネージャが報告する数値が下がらない」「Dispose したら全て解放される」「GC が管理するから何もしなくてよい」など、管理されているリソースと、管理されていないリソースを混同している傾向があると思います。この点では、「Dispose メソッドがあってもなくても何も考えることができないので結果としては変わらないのでは?」は、その通りだと思います。その通りと思いながらなぜ書いたのかについては、後ほど。

2.生兵法
 じゃんぬさんは「VB6 は、すでにオブジェクト指向言語である」と何度か書かれていますが、そう思っていない人も多くいらっしゃると思います。あるいは、「VB.NET でオブジェクト指向の考え方が取り入れられた」と思っている人に対して「VB6 は…」と書かれたこともあったのではないでしょうか。そのように、特に Ver.6 より前からのユーザーに、VB.NET で急にオブジェクト指向の考え方が取り入れられたと考えている人が、多いように思います。次に示すようなコードは、そういった人に多い書き方ではないでしょうか。
コード:
Dim r As New IDataReader
r = IDbCommand.ExecuteReader
(インターフェイスで書いていますが、それを実装するクラス、クラスのインスタンスに置き換えてください。)


このコードでは、ExecuteReader によって、IDataReader のインスタンスが戻されます。そのため、「As New IDataReader」と書く必要はありません。しかし、質問される方々から出されるコードには、「As New」となっているコードの方が多いように思います。
 これはどういうことでしょう?おそらく、なぜ「As New」なのかを解説していない何かを読んだ、または誰かに聞いて、あるいはコピペによって、何でもかんでも「As New Type」と書いているように思われます。
 そのような方々と、今回の質問者さんが同じかどうかはわかりません。しかし、静的メンバーを Me から参照していること、静的メンバーしか参照しないと思われるメソッドを静的メソッドにしていないことから、静的メンバーを理解できているとは思えませんでした。何かで Shared となっているのを見て、あるいは誰かに言われて、そのまま利用しているのではないかと思っています。


 この2つの問題だろうと思われることを元に、質問者さんの理解度がわからないので、理解できていないことを前提に、「質問者本人が疑問に思ってくれて、かつ、調べてくれればいいや」と思って書く手間を省いたら、面倒なことになった...
 「書かれていることの意味がわからない」「説明不足にしか思えない」というご批判は、ごもっともです。質問者さんが、どこまでわかっているか、わかっていることを書いて「こういうことですか?」と尋ねてくれることを目的に、書きましたので。例えば、2008-12-26 21:19 の、「s_ とかをつけるんだとしたら、典型的なシステムハンガリアンの一つですよね。」という返答は期待通りの反応であり、ここから、アプリケーション ハンガリアンとするためにどのような注意が必要かわかっていない、ということがわかります。
 あれ?「クラス変数は全てのインスタンスで同じになりますから」に対して、「同じとはどういうこと?」と質問があったように思ったけど、見つからない。えっと、それを質問者さんから尋ねていただきたかったのですが、確か未記入さんからだったので、ちょっと残念でした。


引用:

よねKENさんの書き込み (2008-12-31 14:45) より:

まず話の大前提として、このJittaさんのこの部分の説明は、
スレ主の武史さんの「投稿日時: 2008-12-26 21:19」の投稿を受けてのコメントですよね。


 はい、そうです。
引用:

本題は、武史さんの「投稿日時: 2008-12-26 21:19」にあるコード例を見ます。

そもそも複数のインスタンスを使われれば、上記コード例のように共有メンバーを使う方法は、十分に注意してコーディングしないと問題になるのでは?


 はい、十分に注意してコーディングしないと、問題になります。しかし、十分に注意されているかどうかは、提示されているコードからはわかりません。質問者さんが「え?」と思ってコード、Shared の説明を見直してくれれば、投稿の目的は達成されたことになります。
未記入
大ベテラン
会議室デビュー日: 2008/02/07
投稿数: 115
投稿日時: 2009-01-06 01:03
引用:

あれ?「クラス変数は全てのインスタンスで同じになりますから」に対して、「同じとはどういうこと?」と質問があったように思ったけど、見つからない。えっと、それを質問者さんから尋ねていただきたかったのですが、確か未記入さんからだったので、ちょっと残念でした。



私はそのような指摘はしていないです。おそらく、ぶさいくろうさんの発言にある「これは文章がおかしいと思うんだが・・・」のことでしょうね。

引用:

静的メンバーしか参照しないと思われるメソッドを静的メソッドにしていないことから、静的メンバーを理解できているとは思えませんでした。何かで Shared となっているのを見て、あるいは誰かに言われて、そのまま利用しているのではないかと思っています。



時間が経過して記憶があやふやになっていませんか?

質問者である武史さんがコード例を提示したのは、Jitta さんの 2度の発言の後なんです。なので、Jitta さんの 1回目、2回目の発言時の心境・判断について「質問者が静的メソッドを使うべき状況で使っていなかった」ことを理由にすることはできません。


引用:

「s_ とかをつけるんだとしたら、典型的なシステムハンガリアンの一つですよね。」という返答は期待通りの反応であり、ここから、アプリケーション ハンガリアンとするためにどのような注意が必要かわかっていない、ということがわかります。



ん? Jitta さんの方法論ってアプリケーションハンガリアンになりますか?

質問者の「s_ とかをつけるんだとしたら、典型的なシステムハンガリアンの一つですよね。」という投げかけに、Jitta さんは「いいえ、違います。」と答えていますよね。でも、s_ を付けるのはシステムハンガリアンです。これには Jitta さんも異論はないでしょう。そうすると、Jitta さんの「いいえ、違います。」という発言は「システムハンガリアンである」という部分を否定していたのではなく、s_ を付けるという方法自体を否定していたと読むことができます。つまり、「s_ を付けるのではなく、もっと上位(応用)概念の接頭辞を付けろ、それがアプリケーションハンガリアンというものだ」ということを言いたかったのですかね?

そうだとして、静的メンバに共通で付けることができる、そんな上位(応用)概念の接頭辞なんて存在しますか? いまちょっと考えてみたんですけど、私には思い付きませんでした。たとえば、カレンダーダイアログの例では静的メンバである開始年などに、初期値であることをあわらす def を付けるということを考えてみました。def開始年、def開始月、def開始日です。これならアプリケーションハンガリアンと言えますね。そして、システム設計ドメインで「初期値はクラスで共通の値を持つ」という決まりがあれば「インスタンスごとに変えなければならない状況下で def 接頭辞が付いている変数が出てくる」のは間違いだと判断することができるようになります。

Jitta さんは、このようなことを意図してアプリケーションハンガリアンを提案していたのでしょうか?

だとすると、Jitta さんの最初の発言「静的であることを示すのは、アプリケーション ハンガリアンだと思います。」はおかしなことになります。私が挙げた例だと「初期値であることを示すのはアプリケーションハンガリアン(が適切)だと思います。」のように限定した表現をしなければならなくなります。やはり、静的であることという汎用概念に接頭辞を付けようとすると s_ しかない、つまりシステムハンガリアンでしか静的であることを示すことはできないと思うのです。(=静的であることをアプリケーションハンガリアンで表現することはできない。)

どうでしょうか?

静的な初期値には def、静的な最小値には min、静的な最大値には max というように決めていけばアプリケーションハンガリアンで接頭辞を付けていくことはできますが、これらは「静的である」ことを示す唯一の接頭辞とは言えません。

もしかすると、Jitta さんの言っているのは「アプリケーションハンガリアン」として共通化できるようなものではなく、「インスタンスで共有していることがすぐに分かる、分かりやすい変数名を付けなさい」ということではありませんか?

Jitta さんが静的メンバに、どのような接頭辞を付けてアプリケーションハンガリアンを実現しようと考えているのか、とても興味があります。ぜひ、教えてください。
武史
ベテラン
会議室デビュー日: 2007/09/21
投稿数: 71
投稿日時: 2009-01-06 10:51
どうも、スレ主です。
がんばってみなさんの議論についていこうとしているのですが、
なかなかついていけていなくてすいません。


あと、変な例で申し訳なかったです。
単に長いクラス名として、思いついただけのクラスでした。
その架空のダイアログクラスの意味論が議論のタネに
なってしまい、反省してます。
あんまり、深くつっこまないで頂ければ幸いです。


さて、「アプリケーションハンガリアン」は、比較的最近はやってきた
言葉に感じていますが、まだ過渡的な言葉なのか、
「型名をつけなければアプリケーションハンガリアン」とか、
まだ、共通理解がされていないように感じています。


私も、概念の一部は知っていて、
理解が十分にできていないのではないかと思います。


今回のをきっかけに、一応いくつかは調べてみたのですが、
未だ、Jitta 氏の意図が理解できておりません。

引用:

Jittaさんの書き込み (2009-01-05 22:57) より:
ここから、アプリケーション ハンガリアンとするためにどのような注意が必要かわかっていない、ということがわかります。



できたら、この辺りの注意が書いてあるようなサイト等を
教えていただければありがたく思います。
セラフ
ベテラン
会議室デビュー日: 2005/12/01
投稿数: 95
お住まい・勤務地: 東北の顔の形といえば
投稿日時: 2009-01-06 11:20
間違ったコードは間違って見えるようにする

べるさんが貼った内容の詳細です。答えは書いてありませんが、アプリケーションハンガリアンとシステムハンガリアンの違いについて書かれています。「注意」につてい書いてあるサイトは探せませんでしたが、参考にはなるかな?っと・・・

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