2008年11月22日

IsVirtual と IsFinal

  
MethodInfoには、IsVirtualプロパティがあるけど、これが trueだからって、オーバーライドできるとは限らないみたい。

あるインターフェースを実装したクラスの当該メソッドは、共通言語ランタイムでは、virtual としてマークしなくちゃいけないので、特別に、virtual final としてマークするようです。

なので、IsVirtula == true かつ IsFinal == false
じゃないと、実際にはオーバーライドできないということです。



この記事へのコメント
>あるインターフェースを実装したクラスの当該メソッドは、共通言語ランタイムでは、virtual としてマークしなくちゃいけないので、特別に、virtual final としてマークするようです。

あるインターフェースってのは,「いくつかのインターフェース」の意味でしょうか? それとも「任意のインターフェース」の意味でしょうか?

インターフェース経由のメソッド呼び出し (callvirt IHogehoge.Foo という呼び出し方) を使うには,Foo を実際に実装しているメソッドが IsVirtul == true でなければなりません.
以下でも書きましたが,CLR がンターフェイスメソッドテーブルのルックアップを行っていることを考えれば,実装しているメソッドが callvirt でなければならない意味が分かりやすいかと思います.
http://www.atmarkit.co.jp/fdotnet/dotnetdeepdive/dotnetdeepdive01/dotnetdeepdive01_02.html

一方で,C# にはインターフェースの明示的な実装というのがあります.
明示的な実装に使われたメソッドは,派生クラスでオーバーライドできませんが,これは sealed virtual を同時に設定することで実現されています.
この辺りは『Essential .NET』の表 6-2 周辺でやたら詳しく解説されています.
Posted by NyaRuRu at 2008年11月24日 12:33
一点修正

「実装しているメソッドが callvirt でなければならない意味」→「実装しているメソッドが virtual でなければならない意味」
Posted by NyaRuRu at 2008年11月24日 12:34
NyaRuRuさん
コメントありがとうございます。

あるインターフェース -> 任意のインターフェース
の意味で書きました。
インターフェイスメソッドテーブルのルックアップを行っているから、virtualな必要があるけど、overrideはできないから、finalという特別なマークが必要だってことですよね。

「連載:深入り.NETプログラミング」こんな連載が始まっていたのですね。
かなりDEEPな内容そうですね。あとでじっくり読んでみます。

Posted by Gushwell at 2008年11月24日 20:02
 

この記事へのトラックバックURL