我们的测试机器上有个很奇怪的bug。错误是:

系统。来自程序集“activeviewer(…)”的类型“DummyItem”中的方法“SetShort”没有实现。

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


当前回答

我在以下场景中收到此错误。

程序集A和程序集B都引用了System.Web.Mvc Version 3.0.0.0 程序集A引用程序集B,并拥有实现程序集B接口的类,这些类的方法返回来自System.Web.Mvc的类。 程序集A升级到System.Web.Mvc版本4.0.0.0 程序集C运行下面的代码(FertPin.Classes。Contact包含在Assembly A):

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

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

感谢原来的海报!

其他回答

我在使用Autofac和大量动态程序集加载时遇到了这个错误。

在执行Autofac解析操作时,运行库将无法加载其中一个程序集。错误消息抱怨程序集'ImplementationAssembly'中的'MyType'类型的方法'MyMethod'没有实现。在Windows Server 2012 R2虚拟机上运行时出现问题,但在Windows 10或Windows Server 2016虚拟机上没有出现问题。

ImplementationAssembly引用System.Collections.Immutable 1.1.37,并包含IMyInterface<T1,T2>接口的实现,该接口在单独的definentationassembly中定义。defintionassembly引用System.Collections.Immutable 1.1.36。

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

在程序目录中找到的System.Collections.Immutable的实际副本是版本1.1.37。在我的Windows Server 2012 R2虚拟机上,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。不可变,这意味着运行时不考虑实现类与接口定义匹配。

添加以下绑定重定向到我的应用程序配置文件修复了这个问题:

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

注:如果这个答案对你没有帮助,请花点时间向下滚动人们添加的其他答案。

简短的回答

如果将方法添加到一个程序集中的接口,然后再添加到另一个程序集中的实现类,但在没有引用接口程序集中的新版本的情况下重新构建实现程序集中,就会发生这种情况。

在本例中,DummyItem实现了来自另一个程序集的接口。SetShort方法最近被添加到接口和DummyItem中—但是包含DummyItem的程序集是引用先前版本的接口程序集重新构建的。因此SetShort方法有效地存在,但没有将其链接到接口中的等效方法。

长回答

如果你想尝试复制这个,试试下面的方法:

Create a class library project: InterfaceDef, add just one class, and build: public interface IInterface { string GetString(string key); //short GetShort(string key); } 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 } 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(); Run the code once, the console says "hello world" 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.

对我来说,解决方案与实现接口的项目设置了“Register for COM Interop”属性有关。取消勾选这个选项为我解决了这个问题。

除了提问者自己已经说过的答案之外,还有以下几点值得注意。发生这种情况的原因是,类可能拥有与接口方法具有相同签名的方法,而无需实现该方法。下面的代码说明:

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

在最近的一次windows更新后,我收到了这个错误。我设置了一个从接口继承的服务类。该接口包含一个返回ValueTuple的签名,这是c#中的一个相当新的特性。

我所能猜到的是,windows更新安装了一个新的,但即使显式引用它,更新绑定重定向,等等…最终的结果只是将方法的签名更改为“标准”的东西。