TypeLoadException says 'no implementation'

2019-01-01 10:26发布

I've got a very weird bug on our test machine. The error is:

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

I just can't understand why. SetShort is there in the DummyItem class, and I've even recompiled a version with writes to the event log just to make sure that it's not a deployment/versioning issue. The weird thing is that the calling code doesn't even call the SetShort method.

30条回答
余生请多指教
2楼-- · 2019-01-01 10:45

The other time you can get this error is if you have an incorrect version of a signed assembly. It's not the normal symptom for this cause, but here was the scenario where I got it

  • an asp.net project contains assembly A and assembly B, B is strongly named

  • assembly A uses Activator.CreateInstance to load assembly C (i.e. there is no reference to C which is built separately)

  • C was built referencing an older version of assembly B than is currently present

hope that helps someone - it took me ages to figure this out.

查看更多
大哥的爱人
3楼-- · 2019-01-01 10:45

I have yet another esoteric solution to this error message. I upgraded my target framework from .Net 4.0 to 4.6, and my unit test project was giving me the "System.TypeLoadException...does not have an implementation" error when I tried to build. It also gave a second error message about the same supposedly non-implemented method that said "The 'BuildShadowTask' task failed unexpectedly." None of the advice here seemed to help, so I searched for "BuildShadowTask", and found a post on MSDN which led me to use a text editor to delete these lines from the unit test project's csproj file.

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

After that, both errors went away and the project built.

查看更多
与君花间醉酒
4楼-- · 2019-01-01 10:46

I also got this error when I had previously enabled Code Coverage during unit testing for one of the assemblies. For some reason Visual Studio "buffered" the old version of this particular DLL even though I had updated it to implement a new version of the interface. Disabling Code Coverage got rid of the error.

查看更多
与君花间醉酒
5楼-- · 2019-01-01 10:50

NOTE - If this answer doesn't help you, please take the time to scroll down through the other answers that people have added since.

Short answer

This can happen if you add a method to an interface in one assembly, and then to an implementing class in another assembly, but you rebuild the implementing assembly without referencing the new version of the interface assembly.

In this case, DummyItem implements an interface from another assembly. The SetShort method was recently added to both the interface and the DummyItem - but the assembly containing DummyItem was rebuilt referencing the previous version of the interface assembly. So the SetShort method is effectively there, but without the magic sauce linking it to the equivalent method in the interface.

Long answer

If you want to try reproducing this, try the following:

  1. Create a class library project: InterfaceDef, add just one class, and build:

    public interface IInterface
    {
        string GetString(string key);
        //short GetShort(string key);
    }
    
  2. Create a second class library project: Implementation (with separate solution), copy InterfaceDef.dll into project directory and add as file reference, add just one class, and build:

    public class ImplementingClass : IInterface
    {
        #region IInterface Members
        public string GetString(string key)
        {
            return "hello world";
        }
    
        //public short GetShort(string key)
        //{
        //    return 1;
        //}
        #endregion
    }
    
  3. Create a third, console project: ClientCode, copy the two dlls into the project directory, add file references, and add the following code into the Main method:

     IInterface test = new ImplementingClass();
     string s = test.GetString("dummykey");
     Console.WriteLine(s);
     Console.ReadKey();
    
  4. Run the code once, the console says "hello world"

  5. Uncomment the code in the two dll projects and rebuild - copy the two dlls back into the ClientCode project, rebuild and try running again. TypeLoadException occurs when trying to instantiate the ImplementingClass.

查看更多
看风景的人
6楼-- · 2019-01-01 10:50

FWIW, I got this when there was a config file that redirected to a non-existent version of a referenced assembly. Fusion logs for the win!

查看更多
谁念西风独自凉
7楼-- · 2019-01-01 10:51

I keep coming back to this... Many of the answers here do a great job of explaining what the problem is but not how to fix it.

The solution to this is to manually delete the bin files in your projects published directory. It will clean up all the references and force the project to use the latest DLLs.

I don't suggest using the publish tools Delete function because this tends to throw off IIS.

查看更多
登录 后发表回答