ブログ「サイバー少年」

ブログ「サイバー少年」へようこそ!
小学六年生ごろからプログラミングを趣味にしている高校生のブログです。
勉強したことについての記事などを書いています。フリーソフトも制作、公開しています。
(当ブログについて詳しくは「ブログ概要紹介」を参照)

サイバー少年が作ったフリーソフトは「サイバー少年の作品展示場」へ

Type.IsAssignableFromメソッドが変になる件について考える。

記事「[C#] プラグインを追加できるようにするための設計を考える」で考えた、汎用的DLLを作っている、
と姉妹ブログのほうで書きましたが、

もう使用できるレベルまで完成しました!

XMLコメントを付けて公開しようかなと思います。



さて、今回の本題は別のものです。

このライブラリの制作中にあった事なのですが、


Type.IsAssignableFromメソッドが正常に動かない。


同じインターフェースを実装しているのですが、Type.IsAssignableFromメソッドではFalseになってしまうようです。

まぁ、キャストは正常に出来ますから、やむを得ず
(obj is Type)からの(Type)objという書き方でやりました。

ただ、このやり方だと、インスタンスを作ってからじゃないと出来ないんですよね。

無駄です。
そのクラスのコンストラクタに重い処理があったりしたら、もっと無駄です。





なぜType.IsAssignableFromでは正常に動かないのか、自分なりに考えてみました。

(obj is Type)というように、isを使用した方法は、単純にオブジェクトがTypeにキャスト出来るかどうかを調べます。

それに対して、IsAssignableFromはインスタンスなど作りません。

アセンブリに書いてあるタグみたいなもので調べます。

この「アセンブリ」が鍵です。

説明が難しいですが、
今回、私が作っているライブラリのやり方では、
プラグイン対応アプリケーションと、プラグインとが参照しているインターフェースは違うアセンブリになってしまうんだと、

だからIsAssignableFromでは無理なんじゃないかと思います。

…意味不明。



つまり、図にすると、本来はこういう状況を想定しているメソッドなわけです。


同じアセンブリ(DLL)を、2つのアセンブリが参照する。
同じアセンブリ(DLL)を、2つのアセンブリが参照する。


しかし、プラグインとなると、こうはいかないわけです。

プラグインは、アプリケーションを作った環境と、異なる環境で作る場合があるわけで、
さらに、そのプラグインをユーザーがダウンロードしたりということで、
環境が違いますから、全く同じIPlugin.dllを参照できないのです。

そう、IPlugin.dllのコピーしか参照できないのです。


同じ型だが、違うアセンブリ。
同じ型だが、違うアセンブリ。


すると、アプリケーションとプラグインは、
アセンブリ的には違うものを参照しているということになります。

詳しいことまで分かりませんが、
同じアセンブリ = 同じファイル
という基準で見るんじゃないかと思います。


コピーも違うファイルとして扱われますから、

そのため、これはIPlugin.dllをコピーしちゃっていますから、
アプリケーションとプラグインの二つが参照しているものは、違うアセンブリです。


結果、アセンブリの情報から調べるType.IsAssignableFromメソッドでは判断できないのではないかと。

型には所属するアセンブリの情報も含まれていて、
型が所属するアセンブリが同じかどうかも調べているわけですね。


しかし、アセンブリがどうこうではなく型としては同じものです。

だから、「キャスト出来るかどうか」という単純な方法で調べるisなら正常に動くのだと思います。




インスタンスをいちいち作るのはかなり無駄ですが、
仕組みを考えると、そうする方法でしか判別できないのだと思います。

もっといい方法ないですかね~。

確か、.NETの型の、“型情報”という概念はC++などには存在しません。

Javaは分からん。

型情報とは奥の深い概念ですね。

tag:

コメント

コメントの投稿

トラックバック

トラックバック URL
http://cyberboy6.blog.fc2.com/tb.php/267-6b645807
この記事にトラックバックする(FC2ブログユーザー)

当ブログをご利用(閲覧等)になる場合は必ず「当ブログの利用規定」をお守りください。