27

基本クラス (UserControl) から継承し、インターフェイス (IFrameworkClient) を実装するクラス (TabControlH60) があります。.NET Activator クラスを使用してオブジェクトをインスタンス化します。返されたインスタンスを使用して、UserControl 基本クラスにキャストできますが、インターフェイスにはキャストできません。私が得る例外はコードスニペットの下にあります。インターフェイスにキャストするにはどうすればよいですか?

object obj = Activator.CreateInstance(objType);
Type[] interfaces = obj.GetType().GetInterfaces(); // contains IFrameworkClient

m_Client = (UserControl)obj;                 // base class cast works
IFrameworkClient fc = (IFrameworkClient)obj; // interface cast fails

// Note: The (IFrameworkClient)obj cast works fine in the debugger Watch window.
{"Unable to cast object of type 'FPG.H60.AFF.TabControlH60' to type 
    'FPG.AFF.Interfaces.IFrameworkClient'."}
4

9 に答える 9

45

「プラグイン」機能を提供する私のライブラリと同じ問題が嫌いです...ようやく機能しました...

ここに私の問題がありました: プラグインを使用する 1 つのメイン アセンブリ、プラグイン (Plugin.dll) を含む 1 つのアセンブリ、および (重要) プラグイン機能 (Library.dll) を提供する別のアセンブリがありました。

Plugin.dll は、(拡張できるようにするために) メイン アセンブリを参照し、Library.dll は plugin-func を使用して参照していました。- メイン アセンブリに関連するディレクトリ "./Plugins" に取得されたバイナリです。

メイン アセンブリも plugin-func を参照していました。アセンブリは「PluginManager」を使用するために書きます。この "PluginManager" はパスを取得し、リフレクションを介してすべての *.dll ファイルをロードして、"IPlugin" インターフェイス (Library.dll にも由来する) があるかどうかを分析します。

PluginManager を呼び出してプラグインをロードするたびに、プラグインを「IPlugin」にキャストできませんでしたが、実装されていました。

私はほとんど怒っていました - しかし、私は全体の問題を発見しました. プラグインをコンパイルすると、「./Plugins」ディレクトリに「Plugin.dll」だけでなく「Library.dll」も書き込まれました。PluginManager で毎回誤って「Library.dll」をロードすることで、2 種類の「IPlugin」ができました。それらは互換性がありませんでした!

注意 - 「./Plugins/Library.dll」をロードしない場合でも、問題が発生します。「Library.dll」を参照する「Plugin.dll」をロードすると、同じディレクトリにあるプラグインが使用されるためです。 .. チルト... !! 私の PluginManager は、見つかった "Library.dll" を削除するだけになりました。

手がかりは、異なるコンテキストで 2 つのアセンブリにアクセスしないように注意することです。

于 2011-06-30T08:29:29.727 に答える
13

ここで最も可能性の高い原因はIFrameworkClient、2 つのケースで別のアセンブリからのものであり、したがって別の .NET 型であるということです。同じコードであっても、異なるタイプの場合があります。

を確認してくださいAssemblyQualifiedName。また、このアセンブリをリフレクションでロードしている場合、同じ AssemblyQualifiedNameであっても、ロード コンテキストのおかげで異なる型を取得できることに注意してください。

于 2009-10-20T19:34:50.977 に答える
4

独立したプロジェクト(クラスライブラリ)の独立した名前空間(名前空間が必要)でIFrameworkClientインターフェイスを定義します。次に、コントロールプロジェクトとメインプロジェクトにクラスライブラリの参照を追加します。

于 2011-01-27T10:29:14.100 に答える
3

あなたのサンプルコードがいくつかのものを残していると何かが私に言います...

class Program
{
    static void Main(string[] args)
    {
        var type = typeof(MyClass);
        object obj = Activator.CreateInstance(type);
        Type[] interfaces = obj.GetType().GetInterfaces();

        var m_Client = (UserControl)obj;          
        IFrameworkClient fc = (IFrameworkClient)obj;
    }
}

public interface IFrameworkClient { }

public class UserControl { }

public class MyClass : UserControl, IFrameworkClient { }

これはコンパイルして実行します。

キャストしようとする前に、IFrameworkClient の定義を含む DLL がまだロードされていないに違いありません。これは、Activator.CreateInstance を使用しているときに発生する可能性があります。

var forceLoad = typeof(IFrameworkClient);キャストの前に挿入してみてください。

于 2009-10-20T19:36:46.470 に答える
0

クラスFPG.H60​​.AFF.TabControlH60が実際に IFrameworkClient を実装している場合、これが失敗する理由はありません。この例外の原因として考えられる唯一のことは、IFrameworkClient を含むアセンブリに厳密な名前が付けられていて、Tab Control オブジェクトがたまたま含まれているアセンブリの別のバージョンを参照している場合、または IFrameworkClient という名前の別のインターフェイスを使用している場合です。

于 2009-10-20T19:36:42.633 に答える
-1

object型からインターフェイスにキャストしようとしているため、キャストが機能していません。インターフェイス キャスト行を次のように置き換えた場合:

IFrameworkClient fc = (IFrameworkClient)m_Client;

それが動作します。

あるいは、オペレーターを使用して、オブジェクトからインターフェースへのキャストを行うことができると少し確信していますas

詳細については、次の記事を参照してください。

パズルのピースがもう 1 つ。インターフェイスは次から派生しませんobject: http://blogs.msdn.com/ericlippert/archive/2009/08/06/not-everything-derives-from-object.aspx

于 2009-10-20T19:34:01.297 に答える