Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/user-interface/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# TypeLoadException表示';没有实现';,但它已经实施了_C#_.net_Fusion_Typeloadexception - Fatal编程技术网

C# TypeLoadException表示';没有实现';,但它已经实施了

C# TypeLoadException表示';没有实现';,但它已经实施了,c#,.net,fusion,typeloadexception,C#,.net,Fusion,Typeloadexception,我在我们的测试机上发现了一个很奇怪的错误。错误是: System.TypeLoadException:程序集“ActiveViewer(…)”的类型“DummyItem”中的方法“SetShort”没有实现。 我就是不明白为什么SetShort在DummyItem类中,我甚至重新编译了一个版本,并写入了事件日志,以确保它不是部署/版本控制问题。奇怪的是,调用代码甚至没有调用SetShort方法。注意-如果这个答案对您没有帮助,请花点时间向下滚动查看人们添加的其他答案 简短回答 如果将方法添加到一

我在我们的测试机上发现了一个很奇怪的错误。错误是:

System.TypeLoadException:程序集“ActiveViewer(…)”的类型“DummyItem”中的方法“SetShort”没有实现。


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

注意-如果这个答案对您没有帮助,请花点时间向下滚动查看人们添加的其他答案

简短回答

如果将方法添加到一个程序集中的接口,然后添加到另一个程序集中的实现类,但在不引用接口程序集的新版本的情况下重新生成实现程序集,则可能会发生这种情况

在本例中,DummyItem实现来自另一个程序集的接口。SetShort方法最近被添加到接口和DummyItem中,但包含DummyItem的程序集是参照接口程序集的早期版本重建的。因此,SetShort方法有效地存在于此,但没有将其与接口中的等效方法联系起来的魔力酱

长答案

如果要尝试复制此内容,请尝试以下操作:

  • 创建类库项目:InterfaceDef,只添加一个类,然后生成:

    public interface IInterface
    {
        string GetString(string key);
        //short GetShort(string key);
    }
    
    public class ImplementingClass : IInterface
    {
        #region IInterface Members
        public string GetString(string key)
        {
            return "hello world";
        }
    
        //public short GetShort(string key)
        //{
        //    return 1;
        //}
        #endregion
    }
    
  • 创建第二个类库项目:实现(使用单独的解决方案),将InterfaceDef.dll复制到项目目录并添加为文件引用,仅添加一个类,然后生成:

    public interface IInterface
    {
        string GetString(string key);
        //short GetShort(string key);
    }
    
    public class ImplementingClass : IInterface
    {
        #region IInterface Members
        public string GetString(string key)
        {
            return "hello world";
        }
    
        //public short GetShort(string key)
        //{
        //    return 1;
        //}
        #endregion
    }
    
  • 创建第三个控制台项目:ClientCode,将两个DLL复制到项目目录中,添加文件引用,并将以下代码添加到Main方法中:

     IInterface test = new ImplementingClass();
     string s = test.GetString("dummykey");
     Console.WriteLine(s);
     Console.ReadKey();
    
  • 运行代码一次,控制台显示“hello world”

  • 取消两个dll项目中的代码注释并重新生成-将两个dll复制回ClientCode项目,重新生成并重试运行。尝试实例化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
    

    我在一个WCF服务中得到了这一点,因为选择了x86构建类型,导致bin位于bin\x86而不是bin下。选择任何CPU都会导致重新编译的DLL转到正确的位置(我不会详细说明这是如何发生的)。

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

    如果您有不正确版本的签名程序集,则会出现此错误。这不是这个原因的正常症状,但这是我得到它的场景

    • asp.net项目包含程序集A和程序集B,程序集B具有强名称

    • 程序集A使用Activator.CreateInstance加载程序集C(即,没有对单独构建的C的引用)

    • C是参照程序集B的旧版本生成的,而不是当前版本


    希望这对某人有所帮助-我花了很长时间才弄明白这一点。

    FWIW,当有一个配置文件重定向到引用程序集的不存在版本时,我得到了这一点。为胜利而融合日志

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

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

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

    • 错误消息很容易引起误解,但或多或少指向了正确的方向(正确的方法,错误的消息)
    • 即使我们没有使用讨论中的方法,也出现了异常
    • 这就引出了一个问题:如果这个异常在任何情况下都被抛出,为什么编译器不把它捡起来

      • 我也有这个错误,它是由引用任何CPU程序集的任何CPU exe引起的,而这些CPU程序集又引用了x86程序集

        异常抱怨MyApp.Implementations(任意CPU)中的类上存在一个方法,该类派生MyApp.Interfaces(任意CPU),但在fuslogvw.exe中,我发现MyApp.CommonTypes(x86)中存在一个隐藏的“试图加载格式不正确的程序”异常,两者都使用该异常。

        我通过一个“菱形”项目依赖关系得到了这个异常:

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

        我重新编译了项目A,但没有编译项目B,这允许项目B“注入”项目D dll的旧版本。当我以前在单元测试期间为其中一个程序集启用代码覆盖率时,我也遇到了这个错误。出于某种原因,VisualStudio“缓冲”了这个特定DLL的旧版本,尽管我已经对它进行了更新以实现接口的新版本。禁用代码覆盖消除了错误。

        < P>对管理C++的问题的另一种解释。 如果您试图存根assem中定义的接口
        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;
        }
        
        var types = AppDomain.CurrentDomain.
           GetAssemblies().
           ToList().
           SelectMany( s => s.GetTypes() /* exception thrown in this call */ )
        ;
        
        <?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>
        
        <ItemGroup>
          <Shadow Include="Test References\MyProject.accessor" />
        </ItemGroup>
        
        |-- myrepo
        |    |-- consoleApp
        |    |-- submodules
        |         |-- mylib (submoduled v2.0)
        |-- mylib (stale v1.0)
        
        <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>