- PR -

Hashtableが初期化されてしまう

投稿者投稿内容
nabe
常連さん
会議室デビュー日: 2006/04/13
投稿数: 29
投稿日時: 2008-07-10 14:03
いつもお世話になっております。
Hashtableの変数に意図しない動きがあり悩んでおります。
皆様の知識をお借りしたく書き込みさせて頂きました。
どうかご教授お願い致します。

ある画面ソースのクラスモジュールから別の画面ソースのクラスモジュールへと
遷移の動作確認を行っております。
遷移元画面からモーダルオープンにて遷移先画面を呼び出し、
さらに遷移元画面に戻る動作確認にて、
意図しない動きをしています。
遷移元から遷移先にモーダルオープンするFunction内の
モーダルオープンする前にHashtableの変数にキーと値を
数個設定しています。
遷移先画面に行き戻ってきた時点で先ほど設定したHashtableが
初期化されてしまっています。
なぜ初期化されるのでしょうか?
別のString型の変数は初期化されずに値が残っているのですが。。。

何かヒントでも良いので知っていれば教えて頂けないでしょうか?
よろしくお願いいたします。

かずくん
ぬし
会議室デビュー日: 2003/01/08
投稿数: 759
お住まい・勤務地: 太陽系第三惑星
投稿日時: 2008-07-10 15:12
使用している開発環境(Visual Studioのバージョン、サービスパック)
使用しているOS
プロジェクトの対象(Win Form or ASP.NET)

程度は、最低記述して頂かないと、正確な回答は得られないと思います。

で、Win Formと仮定して、以下のようなミニマムコードを実行してみましたが、
初期化されることはありませんでした。
結論として、あなたのコードのどこか(おそらく子フォームの中)で、Hashtableを初期化しているからでしょう。

フォームを二つ用意し、親フォームにボタンを張る。
ボタンのクリックイベントハンドラに以下のコードを記述し実行。
ボタンをクリックしてみる。
出力の結果を確認。

コード:

private void button1_Click(object sender, EventArgs e) {
Hashtable table = new Hashtable();
table.Add("1", "a");
table.Add("2", "b");

System.Console.WriteLine("=========== before showing sub form ==================");
foreach (DictionaryEntry entry in table) {
System.Console.WriteLine(string.Format("[key = {0}] value = {1}", entry.Key, entry.Value));
}

new SubForm().ShowDialog();

System.Console.WriteLine("=========== after showing sub form ==================");
foreach (DictionaryEntry entry in table) {
System.Console.WriteLine(string.Format("[key = {0}] value = {1}", entry.Key, entry.Value));
}
}



結果
コード:

=========== before showing sub form ==================
[key = 1] value = a
[key = 2] value = b
=========== after showing sub form ==================
[key = 1] value = a
[key = 2] value = b



追記:

自分で書いときながら、使用環境を記述してなかった。スマン
WInXP SP2
Visual Studio 2005 SP1

[ メッセージ編集済み 編集者: かずくん 編集日時 2008-07-10 15:18 ]
rain
ぬし
会議室デビュー日: 2006/10/19
投稿数: 549
投稿日時: 2008-07-10 15:17
記述してもらう事項に「Hashtable型の変数をどこで宣言しているか」ってのも追加でお願いします。

再現コードを貼ってもらうと、いろんな人が確認しやすいのでさらにお勧めです。
nabe
常連さん
会議室デビュー日: 2006/04/13
投稿数: 29
投稿日時: 2008-07-10 16:11
かずくんさん、rainさん
返事ありがとうございます。

開発環境とプロジェクトが何か記述してなかったですね。
すみません。
開発環境はWinXP SP1
VS は2005 SP1
プロジェクトはWindowsアプリです。
そしてソースを下記に記述しておきます。
モーダル画面の部品から帰ってきたら
objParam1、objParam2、objParam3とも
空になっているのです。
部品が画面を開く以外にパラメータを初期していたとしても
objParam2,objParam3は初期化されないと思うのですが。。。

どうなんでしょうか?
すみません知識があまりないので説明をわかりにくいですが
よろしくお願い致します。

---------------------------------------------------------------
dim objParam1 as new HashTable
dim objParam2 as new HashTable
dim objParam3 as new HashTable

objParam1.Add("A", 1)
objParam1.Add("B", 2)

objParam2.Add("C", 1)
objParam2.Add("D", 2)

objParam3 = objParam2

'モーダルで画面遷移をする部品
CommonFormManager.showFormModal("遷移先画面", objParam1)

end sub
-----------------------------------------------------------------


rain
ぬし
会議室デビュー日: 2006/10/19
投稿数: 549
投稿日時: 2008-07-10 16:30
提示されたコードに、Hashtableの内容を出力するコードを追加してみました。
# かずくんさんのを拝借

コード:
    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

        Dim objParam1 As New Hashtable
        Dim objParam2 As New Hashtable
        Dim objParam3 As New Hashtable

        objParam1.Add("A", 1)
        objParam1.Add("B", 2)

        objParam2.Add("C", 1)
        objParam2.Add("D", 2)

        objParam3 = objParam2

        System.Console.WriteLine("=========== before showing sub form ==================")
        For Each entry As DictionaryEntry In objParam1
            System.Console.WriteLine(String.Format("objParam1 [key = {0}] value = {1}", entry.Key, entry.Value))
        Next
        For Each entry As DictionaryEntry In objParam2
            System.Console.WriteLine(String.Format("objParam2 [key = {0}] value = {1}", entry.Key, entry.Value))
        Next
        For Each entry As DictionaryEntry In objParam3
            System.Console.WriteLine(String.Format("objParam3 [key = {0}] value = {1}", entry.Key, entry.Value))
        Next

        'モーダルで画面遷移をする部品 
        CommonFormManager.showFormModal("遷移先画面", objParam1)

        System.Console.WriteLine("=========== after showing sub form ==================")
        For Each entry As DictionaryEntry In objParam1
            System.Console.WriteLine(String.Format("objParam1 [key = {0}] value = {1}", entry.Key, entry.Value))
        Next
        For Each entry As DictionaryEntry In objParam2
            System.Console.WriteLine(String.Format("objParam2 [key = {0}] value = {1}", entry.Key, entry.Value))
        Next
        For Each entry As DictionaryEntry In objParam3
            System.Console.WriteLine(String.Format("objParam3 [key = {0}] value = {1}", entry.Key, entry.Value))
        Next

    End Sub


このコードを実行しても、
コード:
=========== before showing sub form ==================
objParam1 [key = A] value = 1
objParam1 [key = B] value = 2
objParam2 [key = C] value = 1
objParam2 [key = D] value = 2
objParam3 [key = C] value = 1
objParam3 [key = D] value = 2
=========== after showing sub form ==================
objParam1 [key = A] value = 1
objParam1 [key = B] value = 2
objParam2 [key = C] value = 1
objParam2 [key = D] value = 2
objParam3 [key = C] value = 1
objParam3 [key = D] value = 2


このような結果にはならなかったということでしょうか?
どのような結果になるのでしょうか(もしくは例外が発生?)

ちなみに確認環境:
Windows XP Pro. SP3
Visual Studio 2005 Pro. SP1
nabe
常連さん
会議室デビュー日: 2006/04/13
投稿数: 29
投稿日時: 2008-07-10 17:10
rainさんありがとうございます。

特に異常になってるようにはみえません。
遷移先画面から戻ってきた時点で、
objParam1 、objParam2、objParam3が
Newされた状態(キー件数がゼロ)になっているのです。
画面を遷移させる部品が悪いと考えるべきなんでしょうかね?

部品以外に何か原因がありそうでしたら、
回答お願い致します。
unibon
ぬし
会議室デビュー日: 2002/08/22
投稿数: 1532
お住まい・勤務地: 美人谷        良回答(20pt)
投稿日時: 2008-07-10 17:19
引用:

nabeさんの書き込み (2008-07-10 16:11) より:
'モーダルで画面遷移をする部品
CommonFormManager.showFormModal("遷移先画面", objParam1)


推理も混じりますが、おそらく、そのモーダルフォームの中で DoEvents などを使っていて、そのメソッド(モーダルフォームを呼んでいるメソッド)がモーダルフォームの中から再度呼ばれている状態になっているのではないでしょうか?
デバッガーの呼び出し履歴のウィンドウで、スタックの積み重ねを確認すると分かります。

#以下、追記。

でも、だとしたら、

引用:

nabeさんの書き込み (2008-07-10 14:03) より:
別のString型の変数は初期化されずに値が残っているのですが。。。



の説明ができませんね。

再現できる最低限のコードを提示されるか、あるいは、コードを削ると再現しなくなる、という事実のいずれかを示されるほうが良いと思います。

#以下、さらに追記。

でも、その「別のString型の変数」が、提示されたコード中に存在していないですね。その変数は、Hashtable の変数とは、扱いが異なっているのではないですか?もしそうならば、その「別のString型の変数」は参考にならないでしょう。

[ メッセージ編集済み 編集者: unibon 編集日時 2008-07-10 17:26 ]
nabe
常連さん
会議室デビュー日: 2006/04/13
投稿数: 29
投稿日時: 2008-07-10 17:36
unibonさんありがとうございます。

別のStringの変数は
Hashtableと同じ場所にDim宣言し
画面を遷移する前に値を設定しています。

元々全ての変数の値が消えたのではないかと思い、
テスト的にStringの変数を作ってみたのですが、
Hashtableの変数のみ初期化されていました。

ちなみにファンクション内で定義している変数はHashtableとStringのみです。

すみませんが、何かありましたら回答お願い致します。

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