関西弁を使う約1名が必死に噛み付いてるのはなぜ?
>>948 これから713は713としてかきこんでくれ。おまいが言ってるように。
ほかの人は出来るだけ相手にしないでください。スレ汚されるのが我慢ならん。
いや、ここまでくるとネタだろ とりあえずスルー推奨 &相手する奴も嵐
Hashtableでkeyの値を上書きするのは Hashtable[key] = 値ですが、 以下の文だと、実行時に foreachが抜ける辺りで InvalidOperationExceptionが 発生してしまいます。 ご存じの方、原因をご教示下さい。 //ハッシュテーブルの全ての値をkey値の2倍にする。 public static Hashtable TestHash() { Hashtable h = new Hashtable(); h.Add(1, 0); h.Add(2, 0); h.Add(3, 0); foreach (int i in h.Keys) { h[i] = i * 2; } return h; }
原因は例外メッセージに書いてるとおりだが。
foreachの取り出し元の変数に変更加えちゃいけないんだっけか? そのような処理したい場合はいったん配列にキーコピーとかかしら?
つーことでこれでうごいたぽいけど、いい方法かどうかはしらん Hashtable h = new Hashtable(); h.Add(1, 0); h.Add(2, 0); h.Add(3, 0); int[] a = new int[h.Count]; h.Keys.CopyTo(a, 0); foreach (int i in a) { Console.WriteLine("{0}, {1}", i, h[i]); h[i] = i * 2; }
>>958-959 ありがとうございます。
foreach のループ対象はkeyの値ですし、
実際に取り出したkey値を操作するのではなく、
ハッシュリストの値の方を編集するわけですし・・・
実際のコードは、以下の様に、編集後のレコードを
もう一つ別に作成したHashtableに入れて、返しています。
キーをコピーした方法も試してみます。
Hashtable h = new Hashtable();
Hashtable rh = new Hashtable();
h.Add("a", 1);
h.Add("b", 2);
h.Add("c", 3);
foreach (string key in h.Keys)
{
rh.Add(key,(int)h[key] * 2);
}
return rh;
961 :
936 :2006/04/13(木) 18:58:33
LVN_ITEMCHANGEDの定義を調べてみたんだが、
こんなのや
#define GVN_SELCHANGED LVN_ITEMCHANGED
こんなの
#define LVN_FIRST ((UINT)-100)
#define LVN_ITEMCHANGED (LVN_FIRST-1)
しか見つからない。
ダメもとでm.Msg == checked((uint)-0x100-1)なんてのも試した。
ローカルの.NET関連のフォルダも見たけどだめ。
WndProcをフォームとリストビューそれぞれに置いてメッセージを調べてみたが、
項目のフォーカスが変更されたときに発行されるものがないような。
それとも
>>938 は、項目のフォーカスが変更される可能性のある操作を
すべて受け取れって意味だったのかな。
あ、そこから解説必要だった? **N_*** ってメッセージは NotifyMessage って言われるもんで、WM_NOTIFY で親フォームに送られる。 WM_NOTIFY を受け取った場合、LPARAM を NMHDR 構造体にキャストして code メンバでどのメッセージなのか確認する。 // これに関しては unsafe でポインタ使った方が凄い楽。 で、pnmhdr->code == LVN_ITEMCHANGED のときにあれこれする。 ちなみに、WM_NOTIFY は親フォームに流れるけど、 .NET では親フォームはそのコントロール自身にも (WM_REFLECT + WM_NOTIFY) を改めて送信するので、 コントロール自身でも判断可能だ。
713の降臨まだぁ?
964 :
713 :2006/04/14(金) 00:12:53
今APIについて猛勉強中 資料が少ないから大変だけど、おもしろいねこれ てか、選ぶ言語間違えたかな。C++のほうがいいみたい
965 :
704 :2006/04/14(金) 00:32:40
>>705 うーん、以下のコードだと呼ばれないんですが。
適当なFormの中のコードです。
Formに配置されたボタンを押すとgcButton_Clickが呼ばれると思ってください。
private Button testButton = null;
private void gcButton_Click(object sender, EventArgs e) {
if (testButton == null) {
testButton = new Button();
testButton.Disposed += new EventHandler(testButton_Disposed);
Controls.Add(testButton);
} else {
Controls.Remove(testButton);
testButton = null;
GC.Collect(); //<- ここでGCしてもtestButton_Disposed()が呼ばれない
}
}
void testButton_Disposed(object sender, EventArgs e) {
Debug.WriteLine("button disposed.");
}
GC.Collect() したら GC されるって保障されてんだっけ?
うっわぁ、ほんとに713降臨しやがった^^; 君うざすぎw C++の方がいいって思うんだったらC++に乗り換えなよ そんでもうC#には関わらないで^^ っていうと、今更乗り換えられないとか、途中で投げ出したくないとか、C#をちゃんと覚えてからとか言うんだろうね そんでここのスレにいつまでもまとわりつくと。
968 :
デフォルトの名無しさん :2006/04/14(金) 00:51:49
1回目はファイナライズキューに入り次のGCで破棄される
>>965 いわゆるデストラクタってのはファイナライザのこと。
ファイナライザはオブジェクトが削除されるときに呼び出される。
で、Disposed イベントは Dispose() メソッドが呼ばれたときに発生する。
Dispose() とファイナライザは直接は関係ないよ。
Disposed を発生させたいなら明示的に Dispose() を呼び出さないと。
っていうかぁ、ファイナライズではイベントハンドラなんて呼ばれないと思うんですけどぉ。
972 :
704 :2006/04/14(金) 01:16:18
>>970 じゃあ
>>391 は嘘なのかな?
IDisposeを実装してるオブジェクトはDispose()はプログラムで明示的に呼び出せと?
ちなみにボタンを動的にControls.Add()したままの状態でFormを閉じるとDisposeが呼ばれます。
確かデストラクタはFinalizeメソッドに変換されるんだよな。 IDisposable実装クラスのファイナライザは、通常Dispose(false)を呼び出すように設計しなければならない。 んで、実際System.Windows.Forms.Buttonクラスの基本クラスであるSystem.ComponentModel.ComponentクラスのFinalizeの中身を 覗いてみると、ちゃんとDispose(false)を呼び出している。 ちなみにDispose(bool disposing)メソッドの中でイベントもちゃんと呼ぶようになってるぞ。 だからGCがButtonクラスの回収をすればイベントは発生するはずということ。 んで、GC.Collectっていうのはガベージコレクタを即実行するわけだが、 ガベージコレクタってのは世代管理を行っていて引数を指定しないでGC.Collectを呼び出した場合は メモリがやばくない限り1世代目の回収しかしない(あとここで世代移動が行われる気がした)。だから必ずしもButtonオブジェクトがGCに回収されるとは限らないわけだ。 つまり、GC.Collect(3)ってやればOKだと思う。
もしかしたら多少違ってるかもしれんから、一度自分でGCについてちゃんと調べることをお勧めしとくよ。
>>972 なんで嘘になるのさ。
Disposed イベントなんて所詮ただのイベント。オブジェクトの掃除とは何の関係もない。
IDisposable は Dispose() が呼ばれなかったら最終的にファイナライザが Dispose(false) を呼び出す。
Dispose(false) は Disposed を発生させないってだけの話。
>>973 Dispose(false) の場合は Disposed を発生させない。
ファイナライザでは参照型のメンバにアクセスしちゃ駄目だから。
もちろんイベントの実体もデリゲートインスタンスなのでファイナライザではさわれない。
さらに、GC.Collect() は全世代のオブジェクトに対して GC を行うとリファレンスに明記されてる。
>>975 すまん、至る所で勘違いが混じってたな。首吊ってくるorz
977 :
970 :2006/04/14(金) 01:27:38
978 :
704 :2006/04/14(金) 01:31:07
>>975 理解しました!
動的ボタンを直接Buttonクラスを使わず以下のように継承してMyButtonを定義し、
overrideしたDisposeメソッドはきちんと呼ばれました。
private class MyButton : Button {
protected override void Dispose(bool disposing) {
Debug.WriteLine("button disposed." + disposing);
base.Dispose(disposing);
}
}
MyButton testButton = null;
>覗いてみると、ちゃんとDispose(false)を呼び出している。 >ちなみにDispose(bool disposing)メソッドの中でイベントもちゃんと呼ぶようになってるぞ。 ここまで見といてなんでその際の条件を見ないw
GC.WaitForPendingFinalizersも呼んでおくと幸せになれそう。 とチラシの裏。
>>962 丁寧な解説どうもありがとう。
LVN_ITEMCHANGEDの定義の
#define LVN_FIRST (0U-100U)
#define LVN_ITEMCHANGED (LVN_FIRST-1)
が0xffffff9bなんだろうということもやっとわかった。
ただ、LVN_ITEMCHANGEDどころかまずWM_NOTIFYが送られてこないような。
if( m.Msg == 0x004e ){ ... } //こんな感じでスタンバってる
フォーカス移動を知りたいだけなのになんでunsafeとか使わにゃいかんのだ、Gates。
>GC.WaitForPendingFinalizersも呼んでおくと幸せになれそう。 なんですと?
MSのコードは適当なタイミングでGC.Collectとか GC.WaitForPendingFinalizersとか呼んでるね
985 :
デフォルトの名無しさん :2006/04/15(土) 01:23:26
968が正解
MenuStripを持つ子ウインドウをそのメニューから this.Close()で閉じるとObjectDisposedExceptionが発生するんですが ただしい娘ウインドウの終了の仕方ってどんなんでしょう?
987 :
986 :2006/04/15(土) 12:42:30
いまテストしてみたんですが、 ToolStripMenuItemの DropDownItemClickedイベントでthis.Close()で閉じると例外、 サブメニューそのもののClickイベントで閉じれば例外が起きません。 こっちでやれってことですかね
微妙に意味が取りづらいが、発生しないよ?
989 :
986 :2006/04/15(土) 13:06:54
えーとですね、 子フォームにMenuStripをくっつけて、最初のアイテムを"ファイル”として、 そのサブアイテムを”閉じる”とします。 ”ファイル”のDropDownItemClickedでthis.Close();を呼ぶと例外、 "閉じる"のClickでthis.Close()なら普通に閉じる。 うちでは100%再現するんですが、(VS2005Express) とりあえず下の方法でお茶を濁しました……
>>989 自分はそういう自分のせいでない(と思いたい)例外が出るときは、めんどくさいのでイレギュラーな手でお茶を濁す。まぁ全体に影響しない範囲でだが。
この場合なら別スレッドにhandleわたしてPostMessageすると思う。
いや、それは当然だろ。 さあサブメニューを表示しようって時にいきなり親が Dispose されるんだから。 なんで DropDownItemClicked で this.Close なんだよ。
>>991 ああ、そういうことですか。
"DropDownした先のItemをClicked"じゃなくて
"DropDownするItemをClicked"って意味だったんですか。
あんまり腑に落ちませんが
ありがとうございました。
うお、1000ギリギリでも埋めに入らねぇ。
つか新スレ立ててくれ新スレ。私は無理だったし。 スレタイの♯は半角だと消えるから全角でな。Shift+3 は別の文字だから「しゃーぷ」を変換するんだ。 ていうかコピーすればいいな。
んじゃ建てるよ?
ksk
乙&梅
Vistaはよせい
1001 :
1001 :
Over 1000 Thread このスレッドは1000を超えました。 もう書けないので、新しいスレッドを立ててくださいです。。。