290

テスト マシンに非常に奇妙なバグがあります。エラーは次のとおりです。

System.TypeLoadException: Method 'SetShort' in type 'DummyItem' from assembly 'ActiveViewers (...)' does not have an implementation.

理由がわかりません。SetShortクラスにありDummyItem、展開/バージョン管理の問題ではないことを確認するためだけに、イベント ログへの書き込みを含むバージョンを再コンパイルしました。奇妙なことは、呼び出し元のコードがメソッドを呼び出しさえしないことSetShortです。

4

41 に答える 41

261

- この回答が役に立たない場合は、時間をかけて、人々が追加した他の回答を下にスクロールしてください。

簡潔な答え

これは、あるアセンブリのインターフェイスにメソッドを追加し、次に別のアセンブリの実装クラスにメソッドを追加した場合に発生する可能性がありますが、インターフェイス アセンブリの新しいバージョンを参照せずに実装アセンブリを再構築します。

この場合、DummyItem は別のアセンブリからのインターフェイスを実装します。最近、SetShort メソッドがインターフェイスと DummyItem の両方に追加されましたが、DummyItem を含むアセンブリは、以前のバージョンのインターフェイス アセンブリを参照して再構築されました。したがって、SetShort メソッドは事実上そこにありますが、インターフェイス内の同等のメソッドにリンクする魔法のソースはありません。

長い答え

これを再現したい場合は、次のことを試してください。

  1. クラス ライブラリ プロジェクト InterfaceDef を作成し、クラスを 1 つだけ追加してビルドします。

    public interface IInterface
    {
        string GetString(string key);
        //short GetShort(string key);
    }
    
  2. 2 番目のクラス ライブラリ プロジェクトを作成します: 実装 (別のソリューションを使用)、InterfaceDef.dll をプロジェクト ディレクトリにコピーしてファイル参照として追加し、クラスを 1 つだけ追加してビルドします。

    public class ImplementingClass : IInterface
    {
        #region IInterface Members
        public string GetString(string key)
        {
            return "hello world";
        }
    
        //public short GetShort(string key)
        //{
        //    return 1;
        //}
        #endregion
    }
    
  3. 3 番目のコンソール プロジェクト ClientCode を作成し、2 つの dll をプロジェクト ディレクトリにコピーし、ファイル参照を追加して、次のコードを Main メソッドに追加します。

     IInterface test = new ImplementingClass();
     string s = test.GetString("dummykey");
     Console.WriteLine(s);
     Console.ReadKey();
    
  4. コードを 1 回実行すると、コンソールに「hello world」と表示されます

  5. 2 つの dll プロジェクトのコードのコメントを外して再構築します。2 つの dll を ClientCode プロジェクトにコピーし、再構築して、もう一度実行してみます。ImplementingClass をインスタンス化しようとすると、TypeLoadException が発生します。

于 2009-06-04T05:58:26.710 に答える
36

質問者自身の回答がすでに述べたことに加えて、次の点に注意する価値があるかもしれません。これが発生する理由は、そのメソッドを実装せずに、クラスがインターフェイス メソッドと同じシグネチャを持つメソッドを持つ可能性があるためです。次のコードは、次のことを示しています。

public interface IFoo
{
    void DoFoo();
}

public class Foo : IFoo
{
    public void DoFoo() { Console.WriteLine("This is _not_ the interface method."); }
    void IFoo.DoFoo() { Console.WriteLine("This _is_ the interface method."); }
}

Foo foo = new Foo();
foo.DoFoo();               // This calls the non-interface method
IFoo foo2 = foo;
foo2.DoFoo();              // This calls the interface method
于 2009-07-08T18:20:25.620 に答える
23

これは、エラー メッセージのメソッドが使用するクラスを定義する別のアセンブリへの参照がアプリ​​ケーションにないときに発生しました。PEVerify を実行すると、「指定されたファイルが見つかりません」というより役立つエラーが表示されました。

于 2009-09-16T21:31:32.717 に答える
23

私は同じメッセージに出くわし、これが私たちが見つけたものです:私たちはプロジェクトでサードパーティのdllを使用しています. それらの新しいリリースが公開された後、プロジェクトを変更して、新しい DLL のセットを指すようにし、正常にコンパイルしました。

実行時にインターフェイス化されたクラスの 1 つをインスタンス化しようとすると、例外がスローされました。他のすべての参照が最新であることを確認しましたが、それでもうまくいきません. エラー メッセージ内のメソッドの戻り値の型が、参照されていない新しいアセンブリからのまったく新しい型であることを (オブジェクト ブラウザーを使用して) 確認するのにしばらく時間がかかりました。

アセンブリへの参照を追加すると、エラーが消えました。

  • エラー メッセージはかなり誤解を招くものでしたが、多かれ少なかれ正しい方向 (正しい方法、間違ったメッセージ) を示していました。
  • 問題のメソッドを使用していないにもかかわらず、例外が発生しました。
  • どのような場合でもこの例外がスローされた場合、コンパイラはそれを検出しないのはなぜですか?
于 2010-05-05T07:03:02.140 に答える
18

次のシナリオでこのエラーを受け取りました。

  • アセンブリ A と B の両方が System.Web.Mvc バージョン 3.0.0.0 を参照しました
  • アセンブリ A はアセンブリ B を参照し、System.Web.Mvc からクラスを返すメソッドを持つアセンブリ B からのインターフェイスを実装するクラスを持っていました。
  • アセンブリ A を System.Web.Mvc バージョン 4.0.0.0 にアップグレード
  • アセンブリ C は以下のコードを実行しました (FertPin.Classes.Contact はアセンブリ A に含まれていました)。

var target = Assembly.GetAssembly(typeof(FertPin.Classes.Contact));

私にとっての修正は、アセンブリ B の System.Web.Mvc 参照を 4.0.0.0 にアップグレードすることでした。今明らかに見える!

オリジナルポスターありがとうございます!

于 2012-11-01T12:31:13.217 に答える
14

このエラーが発生する可能性があるのは、署名されたアセンブリのバージョンが正しくない場合です。これは、この原因の通常の症状ではありませんが、これが発生したシナリオです

  • asp.net プロジェクトにはアセンブリ A とアセンブリ B が含まれており、B には厳密な名前が付けられています

  • アセンブリ A は Activator.CreateInstance を使用してアセンブリ C を読み込みます (つまり、個別にビルドされた C への参照はありません)。

  • C は、現在存在するものより古いバージョンのアセンブリ B を参照してビルドされました

それが誰かを助けることを願っています-これを理解するのに何年もかかりました。

于 2009-11-30T16:17:45.697 に答える
10

このエラーも発生しました。これは、x86 アセンブリを参照する Any CPU アセンブリを参照する Any CPU exe が原因でした。

例外は、MyApp.Interfaces (任意の CPU) を派生させた MyApp.Implementations (任意の CPU) のクラスのメソッドについて不平を言いましたが、fuslogvw.exe で、MyApp からの非表示の「不正な形式でプログラムをロードしようとする」例外を見つけました。両方で使用される .CommonTypes (x86)。

于 2010-08-18T15:13:16.977 に答える
7

私はこれに戻ってきます...ここでの回答の多くは、問題が何であるかを説明する素晴らしい仕事をしますが、それを修正する方法は説明しません.

これを解決するには、プロジェクトの公開ディレクトリにある bin ファイルを手動で削除します。すべての参照がクリーンアップされ、プロジェクトが最新の DLL を使用するように強制されます。

パブリッシュ ツールの [削除] 機能の使用はお勧めしません。

于 2015-05-01T14:45:20.970 に答える
6

このエラー メッセージに対する難解な解決策がもう 1 つあります。ターゲット フレームワークを .Net 4.0 から 4.6 にアップグレードしましたが、ビルドしようとすると、単体テスト プロジェクトで "System.TypeLoadException...実装がありません" というエラーが表示されました。また、「「BuildShadowTask」タスクが予期せず失敗しました」という、実装されていないと思われる同じメソッドに関する 2 番目のエラー メッセージも表示されました。ここでのアドバイスはどれも役に立たないようだったので、「BuildShadowTask」を検索し、MSDNで投稿を見つけたので、テキスト エディターを使用して単体テスト プロジェクトの csproj ファイルからこれらの行を削除しました。

<ItemGroup>
  <Shadow Include="Test References\MyProject.accessor" />
</ItemGroup>

その後、両方のエラーがなくなり、プロジェクトがビルドされました。

于 2015-11-13T23:42:27.223 に答える
5

「ひし形」の形をしたプロジェクトの依存関係でこれを取得しました。

  • プロジェクト A はプロジェクト B とプロジェクト D を使用します
  • プロジェクト B はプロジェクト D を使用します

プロジェクト A を再コンパイルしましたが、プロジェクト B は再コンパイルしなかったため、プロジェクト B は古いバージョンのプロジェクト D dll を「注入」できました。

于 2010-09-23T09:09:16.940 に答える
5

これは、ASP.NET プロジェクトが依存しているプロジェクト (およびアセンブリ名) の名前を変更したときに発生しました。依存アセンブリのインターフェイスを実装した Web プロジェクトの型。[ビルド] メニューから [クリーン ソリューション] を実行したにもかかわらず、以前の名前のアセンブリがbinフォルダーに残り、Web プロジェクトを実行したときに

var types = AppDomain.CurrentDomain.
   GetAssemblies().
   ToList().
   SelectMany( s => s.GetTypes() /* exception thrown in this call */ )
;

上記の例外がスローされ、実装している Web タイプのインターフェイス メソッドが実際には実装されていないことが示されました。Web プロジェクトのbinフォルダー内のアセンブリを手動で削除すると、問題が解決しました。

于 2012-05-27T06:39:06.193 に答える
4

また、アセンブリの1つの単体テスト中に以前にコードカバレッジを有効にしていたときにも、このエラーが発生しました。何らかの理由で、新しいバージョンのインターフェイスを実装するように更新したにもかかわらず、VisualStudioはこの特定のDLLの古いバージョンを「バッファリング」しました。コードカバレッジを無効にすると、エラーがなくなりました。

于 2010-09-26T08:02:57.013 に答える
4

このエラーは、アセンブリが Assembly.LoadFrom(String) を使用して読み込まれ、Assembly.Load(Byte[]) を使用して既に読み込まれたアセンブリを参照している場合にも発生する可能性があります。

たとえば、メイン アプリケーションの参照アセンブリをリソースとして埋め込みましたが、アプリは特定のフォルダーからプラグインを読み込みます。

LoadFrom を使用する代わりに、Load を使用する必要があります。次のコードはその仕事をします:

private static Assembly LoadAssemblyFromFile( String filePath )
{
    using( Stream stream = File.OpenRead( filePath ) )
    {
        if( !ReferenceEquals( stream, null ) )
        {
            Byte[] assemblyData = new Byte[stream.Length];
            stream.Read( assemblyData, 0, assemblyData.Length );
            return Assembly.Load( assemblyData );
        }
    }
    return null;
}
于 2011-11-11T15:45:03.333 に答える
3

私の場合、WinForms ツールボックスをリセットするのに役立ちました。

Formデザイナーで a を開いたときに例外が発生しました。ただし、コードのコンパイルと実行は可能で、コードは期待どおりに動作しました。例外UserControlは、参照したライブラリの 1 つからのインターフェイスを実装するローカルで発生しました。このライブラリが更新された後にエラーが発生しました。

これUserControlは、WinForms ツールボックスにリストされていました。おそらく、Visual Studio が古いバージョンのライブラリの参照を保持しているか、古いバージョンをどこかにキャッシュしていた可能性があります。

この状況から私が回復した方法は次のとおりです。

  1. WinForms ツールボックスを右クリックしReset Toolbox、コンテキスト メニューで をクリックします。(これにより、ツールボックスからカスタム アイテムが削除されます)。
    私の場合、ツールボックスの項目はデフォルトの状態に復元されました。ただし、ポインター矢印がツールボックスにありませんでした。
  2. Visual Studio を閉じます。
    私の場合、Visual Studio は違反例外で終了し、中止されました。
  3. Visual Studio を再起動します。
    今、すべてが順調に進んでいます。
于 2014-09-17T19:30:32.957 に答える
3

ソリューションを MVC3 から MVC5 にアップグレードしたところ、単体テスト プロジェクトから同じ例外が発生し始めました。

古いファイルを探しているすべての参照をチェックし、最終的に、単体テスト プロジェクトで Mvc の bindingRedirects を実行する必要があることを発見しました。

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="System.Web.Helpers" publicKeyToken="31bf3856ad364e35" />
        <bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="System.Web.WebPages" publicKeyToken="31bf3856ad364e35" />
        <bindingRedirect oldVersion="0.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" />
        <bindingRedirect oldVersion="0.0.0.0-5.1.0.0" newVersion="5.1.0.0" />
      </dependentAssembly>
    </assemblyBinding>
  </runtime>
</configuration>
于 2014-03-25T01:21:41.407 に答える
3

マネージ C++ に関連するこの種の問題の別の説明。

マネージ C++ を使用して作成された特別な署名を持つアセンブリで定義されたインターフェイスをスタブしようとすると、スタブの作成時に例外が発生します。

これは、Rhino モックと、おそらく を使用するすべてのモッキング フレームワークに当てはまりますSystem.Reflection.Emit

public interface class IFoo {
  void F(long bar);
};

public ref class Foo : public IFoo {
public:
  virtual void F(long bar) { ... }
};

インターフェイス定義は次の署名を取得します。

void F(System.Int32 modopt(IsLong) bar)

C++ 型は(または単にC# に)longマップされることに注意してください。Rhino Mocks メーリング リストで Ayende Rahien が述べているように、問題を引き起こしているのはやや不明瞭です 。System.Int32intmodopt

于 2011-05-12T15:07:17.793 に答える
3

FWIW、参照されたアセンブリの存在しないバージョンにリダイレクトされた構成ファイルがあったときにこれを取得しました。勝利のためのフュージョンログ!

于 2009-12-10T17:54:54.047 に答える
2

単体テストの実行中にもこの問題に遭遇しました。アプリケーションは正常に実行され、エラーは発生しませんでした。私の場合の問題の原因は、テスト プロジェクトのビルドをオフにしたことでした。テストプロジェクトのビルドを再度有効にすると、問題が解決しました。

于 2012-09-10T11:38:04.280 に答える
2

これは、Visual Studio Pro 2008 で 2 つのプロジェクトが同じ名前のアセンブリをビルドしたときに見られました。参照アセンブリの名前を変更すると、例外がなくなりました

于 2012-11-09T17:22:15.447 に答える
2

x86ビルドタイプが選択されているため、WCFサービスでこれを取得し、ビンではなくbin \ x86の下にビンを配置しました。Any CPU を選択すると、再コンパイルされた DLL が正しい場所に配置されます (そもそもこれがどのように行われたかについては詳しく説明しません)。

于 2009-07-28T14:16:50.073 に答える
2

これは、私の場合、実装プロジェクトが古くなっていることを意味します。インターフェイスを含む DLL は再構築されましたが、実装 DLL は古くなっています。

于 2013-09-16T04:02:47.260 に答える
2

これがこのエラーに対する私の見解です。

メソッドを追加しましたexternが、貼り付けに問題がありました。DllImportAttributeコメントアウトされた行に入れられました。

/// <returns>(removed for brevity lol)</returns>[DllImport("user32.dll")] 
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool IsWindowVisible(IntPtr hWnd);

属性が実際にソースに含まれていることを確認すると、問題が修正されました。

于 2015-04-01T19:30:32.580 に答える
1

私の場合、TypeBuilderタイプを作成するために使用しようとしていました。TypeBuilder.CreateTypeこの例外をスローしました。最終的に、インターフェイスの実装を支援するメソッドをMethodAttributes.Virtual呼び出すときに属性を追加する必要があることに気付きました。TypeBuilder.DefineMethodこれは、このフラグがないと、メソッドはインターフェイスを実装せず、代わりに同じシグネチャを持つ新しいメソッドを実装するためです ( を指定しなくてもMethodAttributes.NewSlot)。

于 2016-12-21T15:03:16.257 に答える
1

私も同じ問題を抱えていました。メイン プログラムによって読み込まれる私のアセンブリには、「ローカルのコピー」が true に設定された参照がいくつかあることがわかりました。これらの参照のローカル コピーは、同じフォルダー内の他の参照を探していましたが、他の参照の "ローカル コピー" が false に設定されていたため、それらの参照は存在しませんでした。「誤って」コピーされた参照を削除した後、メイン プログラムが参照の正しい場所を探すように設定されていたため、エラーはなくなりました。メインプログラムに存在する元のコピーの代わりにこれらのローカルコピーが使用されたため、参照のローカルコピーが呼び出しのシーケンスを台無しにしたようです。

お持ち帰りのメッセージは、必要なアセンブリをロードするためのリンクが見つからないためにこのエラーが表示されることです。

于 2016-01-04T07:57:01.990 に答える
1

補遺として: これは、フェイク アセンブリの生成に使用された nuget パッケージを更新した場合にも発生する可能性があります。ナゲット パッケージの V1.0 をインストールし、フェイク アセンブリ "fakeLibrary.1.0.0.0.Fakes" を作成するとします。次に、インターフェイスに新しいメソッドを追加した v1.1 など、nuget パッケージの最新バージョンに更新します。Fakes ライブラリはまだ v1.0 のライブラリを探しています。偽のアセンブリを削除して再生成するだけです。それが問題だった場合、これでおそらく修正されます。

于 2017-01-20T21:13:45.273 に答える