TypeLoadException说'没有实现',但它被实现

我们的testing机器上有一个非常奇怪的错误。 错误是:

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

我只是不明白为什么。 SetShort存在于DummyItem类中,我甚至重新编译了一个写入事件日志的版本,以确保它不是部署/版本问题。 奇怪的是,调用代码甚至没有调用SetShort方法。

注意 – 如果这个答案对你没有帮助,请抽出时间向下滚动,查看其他答案。

简短的回答

如果将方法添加到一个程序集中的接口,然后再添加到另一个程序集中的实现类中,但是不重新引用接口程序集的新版本,则可以重新生成实现程序集。

在这种情况下,DummyItem实现另一个程序集的接口。 SetShort方法最近被添加到接口和DummyItem – 但包含DummyItem的程序集是重新引用接口程序集的以前的版本。 所以SetShort方法是有效的,但没有魔术酱连接到界面中的等效方法。

长答案

如果您想尝试重现此操作,请尝试以下操作:

  1. 创build一个类库项目:InterfaceDef,只添加一个类,然后构build:

     public interface IInterface { string GetString(string key); //short GetShort(string key); } 
  2. 创build第二个类库项目:实现(使用单独的解决scheme),将InterfaceDef.dll复制到项目目录并添加为文件引用,只添加一个类,然后构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. 创build第三个控制台项目:ClientCode,将两个dll复制到项目目录中,添加文件引用,并将以下代码添加到Main方法中:

      IInterface test = new ImplementingClass(); string s = test.GetString("dummykey"); Console.WriteLine(s); Console.ReadKey(); 
  4. 运行代码一次,控制台说“你好世界”

  5. 取消注释在两个DLL项目中的代码并重build – 将这两个DLL复制回ClientCode项目,重build并再次尝试运行。 尝试实例化ImplementingClass时发生TypeLoadException。

除了提问者自己的回答之外,还可能值得注意以下几点。 发生这种情况的原因是因为类没有实现该方法的情况下可能有一个与接口方法具有相同签名的方法。 以下代码说明:

 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 

我得到这个时,我的应用程序没有引用另一个程序集定义的错误消息中的方法使用的类。 运行PEVerify提供了更多有用的错误:“系统找不到指定的文件”。

我遇到了同样的信息,这里是我们发现的:我们在我们的项目中使用第三方DLL。 在新版本发布之后,我们将项目更改为指向新的dll集并成功编译。

当我试图在运行时安装其中的一个接口类时抛出exception。 我们确保所有其他的参考资料是最新的,但仍然没有运气。 我们需要一段时间(使用对象浏览器)发现错误消息中方法的返回types是来自新的未引用程序集的全新types。

我们添加了对程序集的引用,错误消失了。

  • 错误信息相当具有误导性,但多多lessless指向正确的方向(正确的方法,错误的信息)。
  • 即使我们没有使用有问题的方法,也会发生exception。
  • 这导致了我的问题:如果抛出这个exception,为什么编译器不能捡起来呢?

另一次你可以得到这个错误是如果你有一个签名的程序集版本不正确。 这不是这个原因的正常症状,但是这是我得到它的场景

  • 一个asp.net项目包含程序集A和程序集B,B是强命名的

  • 程序集A使用Activator.CreateInstance来加载程序集C(也就是说没有对C程序单独构build的引用)

  • C是build立在引用比当前版本更旧的程序集B的版本上的

希望能帮助别人 – 花了我好几年才弄明白这一点。

我在以下情况下收到此错误。

  • 组件A和B都引用System.Web.Mvc版本3.0.0.0
  • 程序集引用的程序集B,并具有从程序集B实现的接口与从System.Web.Mvc返回类的方法的类。
  • 程序集A升级到System.Web.Mvc版本4.0.0.0
  • 大会C运行下面的代码(FertPin.Classes.Contact包含在大会A):

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

对我来说,修复程序是将Assembly B中的System.Web.Mvc引用升级到4.0.0.0。 现在看起来很明显!

感谢原始的海报!

我也有这个错误,这是由一个任何CPU exe引用任何CPU程序集,依次引用一个x86程序集引起的。

exception抱怨在MyApp.Implementations(任何CPU),派生MyApp.Interfaces(任何CPU),但在fuslogvw.exe类中的一个类上的方法,我发现一个隐藏的'试图加载程序与一个不正确的格式'exception从MyApp .CommonTypes(x86)由两者使用。

当我重命名一个项目(和程序集名称)时,我遇到了这个问题,这个项目依赖于一个ASP.NET项目。 Web项目中的types实现了从属程序集中的接口。 尽pipe从生成菜单执行清洁解决scheme,具有以前的名字的程序集仍然在bin文件夹,当我的web项目执行

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

上面的exception被抛出,抱怨实现webtypes的接口方法没有被实际实现。 手动删除Web项目的bin文件夹中的程序集解决了这个问题。

我对这个错误信息有另一个深奥的解决scheme。 我把我的目标框架从.Net 4.0升级到了4.6,并且我的unit testing项目在我尝试构build时给了我“System.TypeLoadException …没有实现”的错误。 它还给出了第二个错误消息,说相同的所谓的未实现的方法,说:“'BuildShadowTask'任务意外失败。 这里没有任何build议似乎有帮助,所以我search“BuildShadowTask”,并在MSDN上find一个post ,导致我使用文本编辑器从unit testing项目的csproj文件中删除这些行。

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

之后,这两个错误消失,项目build成。

我得到这个与“菱形”项目依赖项:

  • 项目A使用项目B和项目D.
  • 项目B使用项目D.

我重新编译了项目A,但不是项目B,它允许项目B“注入”旧版本的项目D DLL

当我之前在其中一个程序集的unit testing期间启用了代码覆盖时,我也遇到了这个错误。 出于某种原因,Visual Studio“缓冲”了这个特定DLL的旧版本,即使我已经更新它来实现新版本的接口。 禁用代码覆盖率摆脱了错误。

涉及托pipeC ++的这类问题的另一种解释。

如果尝试对使用托pipeC ++创build的程序集中定义的接口进行存根,那么这个接口将会在创build存根时得到exception。

对Rhino Mocks来说这是真的,也可能是任何使用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 ++typeslong映射到System.Int32 (或简单地在C#中)。 modopt 邮件列表中的Ayende Rahien所述,这是一个有点模糊的modopt

如果使用Assembly.LoadFrom(String)加载程序集并引用已使用Assembly.Load(Byte [])加载的程序集,也会导致此错误。

例如,您已经将主应用程序的引用程序集embedded为资源,但您的应用程序会从特定文件夹加载插件。

而不是使用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; } 

我刚刚从MVC3升级到MVC5的解决scheme,并开始从我的unit testing项目接收相同的exception。

检查了所有的引用寻找旧文件,最终发现我需要做一些绑定的Mvc,在我的unit testing项目。

 <?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> 

在我的情况下,它有助于重置WinForms工具箱。

在devise师中打开一个Form时我得到了exception。 然而,编译和运行代码是可能的,代码的行为如预期。 在本地UserControl实现一个从我的引用库之一的接口发生exception。 这个库更新后出现错误。

UserControl被列在WinForms工具箱中。 可能Visual Studio保留了过时版本库的引用,或者在某处过时了一个过期的版本。

以下是我如何从这种情况中恢复:

  1. 右键单击WinForms工具箱,然后在上下文菜单中单击“ Reset Toolbox ”。 (这将删除工具箱中的自定义项目)。
    在我的情况下,工具箱项目已恢复到默认状态; 但是,工具箱中缺less指针箭头。
  2. closuresVisual Studio。
    在我的情况下,Visual Studio以违例exception终止并中止。
  3. 重新启动Visual Studio。
    现在一切运转顺利。

在我的情况下,我曾经在repo之外的兄弟文件夹中引用了一个mylib项目 – 我们称之为v1.0

 |-- myrepo | |-- consoleApp | |-- submodules | |-- mylib (submoduled v2.0) |-- mylib (stale v1.0) 

后来我做了正确的,并通过一个git子模块使用它 – 让我们打电话给v2.0 。 然而,一个项目consoleApp没有正确更新。 它仍然在我的git项目之外引用旧的v1.0项目。

令人困惑的是 ,即使*.csproj显然是错误的,并指向v1.0 ,Visual Studio IDE显示的path为v2.0项目! F12检查界面和class也去了v2.0版本。

由编译器放入bin文件夹的程序集是v1.0版本,因此令人头疼。

IDE对我说谎的事实使得我们更加难以意识到这个错误。

解决scheme :从ConsoleApp删除项目引用并读取它们。

一般提示:从头开始重新编译所有程序集(可能的话,当然不能用于nuget包),并检查bin\debug文件夹中的date时间标记。 任何旧的date程序集是你的问题。

我也遇到了这个问题,同时运行我的unittests。 应用程序运行良好,没有错误。 在我的情况下,问题的原因是我closures了testing项目的build设。 重新启用我的testing项目的build设解决了这个问题。

我在Visual Studio Pro 2008中看到了这个,当两个项目构build了具有相同名称的程序集,一个是类lib SDF.dll,另一个是使用程序集名称sdf.exe引用了lib。 当我更改引用程序集的名称时,exception消失了

FWIW,当有一个configuration文件被redirect到一个不存在的引用程序集的版本时,我得到了这个。 融合日志的胜利!

这是我的错误。

添加了一个extern方法,但是我的粘贴错误。 DllImportAttribute被放在一个注释掉的线上。

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

确保该属性实际上包含在源代码中解决了这个问题。

我一直在回答这个问题……这里的许多答案在解释问题是什么而不是解决问题方面做得很好。

解决方法是手动删除项目发布目录中的bin文件。 它将清理所有的引用,并强制项目使用最新的DLL。

我不build议使用发布工具删除function,因为这往往会抛出IIS。

我得到了这个错误,因为我有一个在程序集“C”的4.5版框架中的类,在框架的4.5.1版本中实现了一个组件“A”中的接口,并且作为组装的基类'B'也在框架的4.5.1版上。 试图加载程序集“B”时,系统抛出exception。 另外,我已经在所有三个程序集上安装了一些针对.net 4.5.1的nuget软件包。 出于某种原因,尽pipenuget引用没有在程序集“B”中显示,但它正在成功build立。

事实certificate,真正的问题是程序集引用了包含接口的不同版本的Nuget包,并且接口签名在版本之间改变了。

由于select了x86构buildtypes,我在WCF服务中得到了这个,导致bisn在bin \ x86而不是bin下。 select任何CPU导致重新编译的DLL到正确的位置(我不会详细了解如何发生这种情况)。

这只是意味着实施项目已经过时了。 包含该接口的DLL被重build,但实现DLL已经陈旧了。

我有同样的问题。 我发现我的程序集,由主程序加载,有一些引用“复制本地”设置为true。 这些引用的本地副本在同一个文件夹中查找其他引用,因为其他引用的“Copy Local”被设置为false,所以不存在。 删除“意外”复制的引用之后,错误消失了,因为主程序被设置为查找引用的正确位置。 显然,引用的本地副本搞砸了调用的顺序,因为这些本地副本被用来代替主程序中存在的原始副本。

带回家的消息是由于缺less加载所需程序集的链接而出现此错误。

作为附录:如果更新用于生成伪造程序集的nuget包,也会发生这种情况。 假设你安装了一个nuget软件包的V1.0,并创build了一个伪造程序集“fakeLibrary.1.0.0.0.Fakes”。 接下来,您将更新到nuget包的最新版本,比如v1.1,它为接口添加了一个新的方法。 假货图书馆仍然在寻找图书馆的v1.0。 只需删除假assembly,并重新生成它。 如果这是问题,这可能会解决它。

我面临几乎相同的问题。 我正在抓我的头是什么导致这个错误。 我交叉检查,所有的方法都实现了。

在谷歌search我得到了其他链接。 根据@Paul McLink评论,这两个步骤解决了这个问题。

  1. 重新启动Visual Studio
  2. 清洁,build造(重build)

错误消失了

重新启动VS插件

谢谢保罗:)

希望这有助于遇到这个错误的人:)

我在使用Autofac和大量dynamic程序集加载的上下文中遇到了这个错误。

执行Autofacparsing操作时,运行时将无法加载其中一个程序集。 该错误消息抱怨, Method 'MyMethod' in type 'MyType' from assembly 'ImplementationAssembly' does not have an implementation 。 在Windows Server 2012 R2虚拟机上运行时出现症状,但在Windows 10或Windows Server 2016虚拟机上出现症状。

ImplementationAssembly引用了System.Collections.Immutable 1.1.37,并包含了在单独的DefinitionAssembly IMyInterface IMyInterface<T1,T2>接口的IMyInterface<T1,T2>DefinitionAssembly引用System.Collections.Immutable 1.1.36。

IMyInterface<T1,T2>中“未实现”的方法具有在System.Collections.Immutable定义的IImmutableDictionary<TKey, TRow>types的参数。

在程序目录中find的System.Collections.Immutable的实际副本是版本1.1.37。 在我的Windows Server 2012 R2 VM上,GAC包含System.Collections.Immutable 1.1.36的副本。 在Windows 10和Windows Server 2016上,GAC包含System.Collections.Immutable 1.1.37的副本。 只有当GAC包含旧版本的DLL时才会出现加载错误。

所以,程序集加载失败的根本原因是对System.Collections.Immutable的不匹配引用。 接口定义和实现具有相同的方法签名,但实际上取决于不同版本的System.Collections.Immutable ,这意味着运行时没有考虑实现类来匹配接口定义。

将以下绑定redirect添加到我的应用程序configuration文件解决了问题:

 <dependentAssembly> <assemblyIdentity name="System.Collections.Immutable" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" /> <bindingRedirect oldVersion="0.0.0.0-1.1.37.0" newVersion="1.1.37.0" /> </dependentAssembly> 

解决问题的办法是CleanRebuild Solution

在我的情况下,我试图使用TypeBuilder创build一个types。 TypeBuilder.CreateType抛出这个exception。 我最终意识到,当调用TypeBuilder.DefineMethod来帮助实现接口的方法时,我需要将MethodAttributes.Virtual添加到属性。 这是因为没有这个标志,该方法不会实现接口,而是一个具有相同签名的新方法(即使没有指定MethodAttributes.NewSlot )。