2007年08月13日

Control.Invokeの書き方

   このエントリーをはてなブックマークに追加 Clip to Evernote
Control.Invokeの書き方について、ちょっと考察。

private delegate void MyDelegate();

private void MyDisplay() {
label1.Text = "ほにゃらら";
}

private void Foo(...) {
this.Invoke(new MyDelegate(MyDisplay));
}

これが、C#1.1の頃の書き方。

これが C#2.0になると、

private delegate void MyDelegate();

private void Foo(...) {
this.Invoke(new MyDelegate(delegate {
label1.Text = "ほにゃらら";
}));
}

と書ける。さらに、 MethodInvoker という delegateが定義済みなので、

private void Foo(...)  {
this.Invoke(new MethodInvoker(delegate {
label1.Text = "ほにゃらら";
}));
}

とさらに簡単になる。
しかし、次の書き方がどうしてOKなのかが、はっきりとは分からない。

private void Foo(...)  {
this.Invoke((MethodInvoker)delegate {
label1.Text = "ほにゃらら";
});
}

たぶん、

button1.Click += new EventHandler(button1_Click);

が、
button1.Click += button1_Click;

って書けるのと関係しているんだと思うけど...
誰か教えてくれないかな。

...
そんなことより、

private void Foo(...)  {
this.Invoke(delegate {
label1.Text = "ほにゃらら";
});
}

で良いと思うんだけど。これだとエラーになってしまう。
  

Posted by gushwell at 21:17Comments(0)TrackBack(1)

2007年07月26日

Dispose(bool disposing) の override

   このエントリーをはてなブックマークに追加 Clip to Evernote
http://msdn2.microsoft.com/en-us/library/fs2xkftw.aspx
のコードをみて、以下のように書いたら、base.Dispose() が呼ばれない可能性があるということで、FxCopの警告が出た。

   protected override void Dispose(bool disposing) {
if(!this.disposed) {
try {
if(disposing) {
addedManaged.Dispose();
}
this.disposed = true;
} finally {
base.Dispose(disposing);
}
}
}


なので、以下のように書き換えた。

   protected override void Dispose(bool disposing) {
try {
if(!this.disposed) {
if(disposing) {
addedManaged.Dispose();
}
this.disposed = true;
}
} finally {
base.Dispose(disposing);
}
}



この場合は、base.Dispose(true)が複数回呼ばれる可能性がある。でも基底クラスのDispose()もパターンに則って書かれているはずだから、問題はでないはず...
僕の好みは、前者なんだけど、まあいいか。

でも、ドキュメントに書かれているコードで、FxCopが警告を出すってのは、どうなんだろう?
  
Posted by gushwell at 22:18Comments(0)TrackBack(0)

2007年07月18日

アセンブリ名でロードする

   このエントリーをはてなブックマークに追加 Clip to Evernote
"TestLib.TestClass, TestLib, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"

という typeネーム に対して、

Type type = Type.GetType(data.Type);
obj = Activator.CreateInstance(type);

としたら、エラーになる。
そうか、CreateInstance()は、勝手にアセンブリをロードしてくれないんだ。

ということで、
Assembly.LoadFrom(asm);
として、ロードしようとしたら、これまたエラーだ。
LoadFromには、ファイルパスを指定しないといけない。
アセンブリ名で、ロードするには、
Assembly.Load(asm);

としないといけないみたいだ。

ところで、記事先頭のタイプ名文字列から、アセンブリ名を取得するって、やはり自力でやらないといけないのかな。
まあ、それほど難しいコードじゃないけど、あっても良さそうなのに。  
Posted by gushwell at 20:24Comments(0)TrackBack(0)