1. ホーム
  2. c#

[解決済み】TypeLoadExceptionが「実装がない」というが、実装はされている

2022-04-19 19:39:53

質問

テストマシンで非常に奇妙なバグが発生しました。エラーの内容は

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

どうしても理解できない。 SetShort があるのは DummyItem また、デプロイやバージョン管理の問題でないことを確認するために、イベントログへの書き込みがあるバージョンを再コンパイルしました。 奇妙なことに、呼び出し側のコードでは SetShort メソッドを使用します。

どのように解決するのですか?

注意事項 - この回答がお役に立たなかった場合は、他の回答が追加されていますので、スクロールダウンしてご覧ください。

短い回答

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

この場合、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. コードを一度実行すると、コンソールに "hello world" と表示されます。

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