Out of Memory

ごめん、忘れてた。

目次

Blog 利用状況

ニュース

2008年7月1日
Microsoft MVP for Developer Tools - Visual C++ を再受賞しました。
2008年2月某日
MVPアワードがVisual C++に変更になりました。
2007年10月23日
blogタイトルを変更しました。
2007年7月1日
Microsoft MVP for Windows - SDKを受賞しました!
2007年6月20日
スキル「ニュース欄ハック」を覚えた!
2006年12月14日
記念すべき初エントリ
2006年12月3日
わんくま同盟に加盟しました。

カレンダー

中の人

aetos

顔写真

埼玉を馬鹿にする奴は俺が許さん。

基本的に知ったかぶり。興味を持った技術に手を出して、ちょっと齧りはするものの、それを応用して何か形にするまでは及ばずに飽きて放り出す人。

Microsoft MVP for Windows SDK July 2007 - February 2008, Microsoft MVP for Visual C++ February 2008 - June 2009
Microsoft MVP for Windows SDK
July 2007 - February 2008
Microsoft MVP for Visual C++
February 2008 - June 2009

アクセサリ

あわせて読みたい

e-Words

アフィリエイト

記事カテゴリ

書庫

日記カテゴリ

覚えてないとハマりそうなこと

C# では親クラスが明示的に実装しているインターフェイスのメソッドの実装は呼べない?

投稿日時 : 2008年6月3日 18:58

Feedback

# re: 覚えてないとハマりそうなこと 2008/06/03 19:24 YuO

「親クラス」どころか,「自分が」明示的に実装しているインターフェイスのメソッドですら呼べません。

interface IFoo { void Bar(); }
class Foo : IFoo {
void IFoo.Bar() { }
void Hoge () {
Bar(); // Error CS0103
}
}

# re: 覚えてないとハマりそうなこと 2008/06/03 19:42 かずくん

キャストしたらおkなんだよね。
nterface IFoo { void Bar(); }

class Foo : IFoo {
void IFoo.Bar() { }
void Hoge () {
((IFoo)this).Bar();
}
}

# re: 覚えてないとハマりそうなこと 2008/06/03 21:19 T.Hirase

自分は「((IFoo)this).Bar()」が面倒なので
IFooインタフェースのヘルパークラスを作って、
次のような感じにします。

static class FooHelper
{
static void Bar(IFoo foo)
{
foo.Bar();
}
}

呼び出すときは
「FooHelper.Bar(this)」
とします。

# re: 覚えてないとハマりそうなこと 2008/06/03 22:40 シャノン

(this as IFoo).Bar(); はできますが、
(base as IFoo).Bar(); はコンパイルできないし
((this as Base) as IFoo).Bar(); は (this as Ifoo).Bar(); を呼び出しちゃいます。

# re: 覚えてないとハマりそうなこと 2008/06/04 0:10 YuO

勘違いでした……。

Reflection使えばできますが,C#でできるとはいいませんよね……。
一応,MethodInfo.DeclaringTypeで自分かそうでないかもわかりますが……。

# re: 覚えてないとハマりそうなこと 2008/06/04 0:39 Streetw☆

これって、thisのクラスでもbaseのクラスでも、それぞれで
同じインターフェイスを明示的に実装してる場合の話ですか?
リフレクション使うと何でもできそうって思って試行錯誤したけど
できませんでした;;
BindingFlags.DeclaredOnlyって、インターフェイスには使えなさそうだし。。

という内容をコメントする前にリフレッシュしたら、YuOさんのコメントが~
Reflectionでできるんですか!教えてください。。

# re: 覚えてないとハマりそうなこと 2008/06/04 0:43 シャノン

親クラスがインターフェイスを明示的に実装している場合、子クラスはそのインターフェイス型にキャストできません。
で、もしそれを可能にするんであれば、子クラスでも明示的に実装するしかありません。
が、前述のように親クラスの実装を呼び出せないので、それを呼ぶ必要がある場合は、protected なヘルパーメソッドを設ける必要があるかもしれません。

# re: 覚えてないとハマりそうなこと 2008/06/04 14:22 trapemiya

>C# では親クラスが明示的に実装しているインターフェイスのメソッドの実装は呼べない?

呼べちゃうとインターフェースの意味が無くなっちゃうと思います。いわゆる多重継承ができちゃうんで。

# re: 覚えてないとハマりそうなこと 2008/06/04 14:45 trapemiya

↑意味がなくなるということはないか。ただ、多重継承の問題が勃発するというだけで。

# re: 覚えてないとハマりそうなこと 2008/06/04 15:48 シャノン

> 多重継承の問題が勃発する

よくわからないんですが、どのへんで?

# re: 覚えてないとハマりそうなこと 2008/06/04 23:39 trapemiya

あれれれ? ごめんなさい。何か勘違いしていたようです。何かへんなこと考えてたんだろうなぁ・・・

# re: 覚えてないとハマりそうなこと 2008/06/05 0:18 YuO

ベースクラスのGetType().GetMethodを,
・メソッド名にIFoo.Bar
・フラグにBindingFlags.Instance | BindingFlags.NonPublic
を指定して呼び出すと,
ベースクラスのIFoo.Barを呼び出す為のMethodInfoを取得することができます。

# re: 覚えてないとハマりそうなこと 2008/06/05 9:47 かずくん

もしかして勘違いしてた?
.NET 2.0の場合、Formクラスは、
/ IContainerControl
Form > ContainerControl - ScrollableContro > ...

となってる。
/ IContainerControl
で、Form1 - Form

のように明示的にIContainerControlを実装した場合、
親クラス側のIContainerControlのメソッド/プロパティが呼べないってこと?


ScrollableContro
|
ContainerControl - IContainerControl (A)
|
Form
|
Form1 - IContainerControl (B)

のようなクラス階層で、
((IContainerControl)this).ActivateControl(..)実行すると、

Form1でIContainerControlを明示的実装してなければ、(A)が呼ばれるけど、
派生クラスと、基底クラスで同一のインターフェースを明示的に実装すると、(B)になっちゃうね。

# re: 覚えてないとハマりそうなこと 2008/06/05 9:48 かずくん

/ IContainerControl の表示がずれてるけど、うまく汲み取ってください

# re: 覚えてないとハマりそうなこと 2008/06/05 13:23 シャノン

面倒くせー
http://www.atmarkit.co.jp/fdotnet/onepoint/onepoint01/onepoint01_02.html

# re: 覚えてないとハマりそうなこと 2008/06/05 13:29 シャノン

> ((IContainerControl)this).ActivateControl(..)実行すると、
> Form1でIContainerControlを明示的実装してなければ、(A)が呼ばれるけど、
> 派生クラスと、基底クラスで同一のインターフェースを明示的に実装すると、(B)になっちゃうね。

親クラスが IContainerControl.ActivateControl() を明示的に実装していなければ、単に ActivateControl(); とした場合は親クラスが、(this as IContainerControl).ActivateControl(); とした場合は子クラスのが呼ばれますね。
親クラスが IContainerControl.ActivateControl() を明示的に実装していた場合、親クラスがそれを間接的に呼び出す方法を提供していない限り、子クラスから親クラスの ActivateControl を呼び出すことは出来ません、と。

# re: 覚えてないとハマりそうなこと 2008/06/05 18:05 Streetw☆

間接的に呼び出す方法とか、YuOさんの方法とか、
いろいろ最初に試してたんですが、全部ダメでした。。
YuOさんはできると書かれてるし、私も絶対できそうって思ってます。
おかしいところを教えてください;;

public interface IFoo
{
 void Bar();
}
public class Test1 : IFoo
{
 void IFoo.Bar()
 {
  MessageBox.Show("a");
 }
 protected void Nika()
 {
  ((IFoo)this).Bar();
 }
}
public class Test2 : Test1, IFoo
{
 void IFoo.Bar()
 {
  MessageBox.Show("b");
 }
 public void Hoge()
 {
  MethodInfo mi1 = typeof(IFoo).GetMethod("Bar", BindingFlags.Instance | BindingFlags.Public);
  if (mi1 != null) mi1.Invoke(this, null); else MessageBox.Show("ダメ");
  MethodInfo mi2 = this.GetType().BaseType.GetMethod("IFoo.Bar", BindingFlags.Instance | BindingFlags.NonPublic);
  if (mi2 != null) mi2.Invoke(this, null); else MessageBox.Show("ダメ");
  MethodInfo mi3 = this.GetType().GetMethod("IFoo.Bar", BindingFlags.Instance | BindingFlags.NonPublic);
  if (mi3 != null) mi3.Invoke(this, null); else MessageBox.Show("ダメ");
  Nika();
 }
}

シャノンさんのリンク先ですけど、
>この点VB.NETはC#よりも高い柔軟性を持っている。VB.NETでは、Rockyクラスの1つ目の方式での実装が当然できる。
これってコンパイルエラーになりますよ?
VBは明示的な実装しかできないです。
けど最近、こんな話がありました。
http://www.panopticoncentral.net/archive/2008/04/07/23114.aspx

長くてごめんなさい><

# re: 覚えてないとハマりそうなこと 2008/06/05 18:13 Streetw☆

あ、全部ダメというのは、aが表示されないという意味で、
全部"ダメ"が表示されるという意味じゃないです。
それにしても長すぎでした。。ごめんなさい。

# re: 覚えてないとハマりそうなこと 2008/07/24 17:31 Streetw☆

YuOさんのブログの方に書いていただいたのを見て、
私の間違ってるところがわかりました!
今頃でごめんなさいw

↑のコードが私のところでダメだったのは、
名前空間に入れて実行してたからでした。。
インターフェイス名をフルネームで指定すれば、ちゃんと取得できました。
↓こんな感じで。そりゃそうですね~orz
GetMethod("WindowsFormsApplication1.IFoo.Bar", フラグ)

覚えていないとハマると思いますよ!!w

タイトル  
名前  
Url
コメント