C# TypeLoadException 表示“未实现”,但已实现
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/948785/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
TypeLoadException says 'no implementation', but it is implemented
提问by Benjol
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.
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.
我就是不明白为什么。SetShort
在DummyItem
课堂上,我什至重新编译了一个写入事件日志的版本,以确保它不是部署/版本问题。奇怪的是,调用代码甚至没有调用SetShort
方法。
采纳答案by Benjol
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.
在这种情况下,DummyItem 实现了另一个程序集的接口。SetShort 方法最近被添加到接口和 DummyItem 中 - 但包含 DummyItem 的程序集是参考接口程序集的先前版本重建的。所以 SetShort 方法是有效的,但没有魔法酱将它链接到接口中的等效方法。
Long answer
长答案
If you want to try reproducing this, try the following:
如果您想尝试重现此内容,请尝试以下操作:
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.
创建一个类库项目:InterfaceDef,只添加一个类,然后构建:
public interface IInterface { string GetString(string key); //short GetShort(string key); }
创建第二个类库项目:实现(单独解决),将InterfaceDef.dll复制到项目目录并添加为文件引用,只添加一个类,然后构建:
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。
回答by Timwi
In addition to what the asker's own answer already stated, it may be worth noting the following. The reason this happens is because it is possible for a class to have a method with the same signature as an interface method without implementing that method. The following code illustrates that:
除了提问者自己的答案已经陈述的内容之外,以下内容可能值得注意。发生这种情况的原因是,一个类可能有一个与接口方法具有相同签名的方法,而无需实现该方法。以下代码说明了这一点:
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
回答by Ruben Bartelink
I got this in a WCF service due to having an x86 build type selected, causing the bins to live under bin\x86 instead of bin. Selecting Any CPU caused the recompiled DLLs to go to the correct locations (I wont go into detail as to how this happened in the first place).
由于选择了 x86 构建类型,我在 WCF 服务中得到了这个,导致垃圾箱位于 bin\x86 而不是 bin。选择 Any CPU 会导致重新编译的 DLL 转到正确的位置(我不会首先详细说明这是如何发生的)。
回答by silent tone
I got this when my application didn't have a reference to another assembly defining a class that the method in the error message used. Running PEVerify gave more helpful error: "The system cannot find the file specified."
当我的应用程序没有引用另一个定义错误消息中方法使用的类的程序集时,我得到了这个。运行 PEVerify 给出了更多有用的错误:“系统找不到指定的文件。”
回答by Tim
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
一个 asp.net 项目包含程序集 A 和程序集 B,B 是强命名的
程序集 A 使用 Activator.CreateInstance 加载程序集 C(即没有对单独构建的 C 的引用)
C 是参考比当前存在的旧版本的程序集 B 构建的
hope that helps someone - it took me ages to figure this out.
希望对某人有所帮助-我花了很长时间才弄清楚这一点。
回答by Tilman
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!
FWIW,当有一个配置文件重定向到引用程序集的不存在版本时,我得到了这个。融合日志为胜利!
回答by Ben
I came across the same message and here is what we have found: We use third party dlls in our project. After a new release of those was out we changed our project to point to the new set of dlls and compiled successfully.
我遇到了同样的消息,这是我们发现的:我们在项目中使用第三方 dll。在这些新版本发布后,我们将项目更改为指向新的 dll 集并成功编译。
The exception was thrown when I tried to instatiate one of the their interfaced classes during run time. We made sure that all the other references were up to date, but still no luck. We needed a while to spot (using the Object Browser) that the return type of the method in the error message was a completely new type from a new, unreferenced assembly.
当我尝试在运行时实例化它们的接口类之一时抛出异常。我们确保所有其他参考资料都是最新的,但仍然没有运气。我们需要一段时间(使用对象浏览器)发现错误消息中方法的返回类型是来自新的未引用程序集的全新类型。
We added a reference to the assembly and the error disappeared.
我们添加了对程序集的引用,错误消失了。
- The error message was quite misleading, but pointed more or less to the right direction (right method, wrong message).
- The exception ocurred even though we did not use the method in question.
- Which leads me to the question: If this exception is thrown in any case, why does the compiler not pick it up?
- 错误信息相当具有误导性,但或多或少指向了正确的方向(正确的方法,错误的信息)。
- 即使我们没有使用有问题的方法,也发生了异常。
- 这让我产生了一个问题:如果在任何情况下都抛出这个异常,为什么编译器不接收它?
回答by Richard Dingwall
I had this error too, it was caused by an Any CPU exe referencing Any CPU assemblies that in turn referenced an x86 assembly.
我也有这个错误,它是由引用 Any CPU 程序集的 Any CPU exe 引起的,而该程序集又引用了 x86 程序集。
The exception complained about a method on a class in MyApp.Implementations (Any CPU), which derived MyApp.Interfaces (Any CPU), but in fuslogvw.exe I found a hidden 'attempt to load program with an incorrect format' exception from MyApp.CommonTypes (x86) which is used by both.
该异常抱怨 MyApp.Implementations (Any CPU) 中某个类的方法,该方法派生 MyApp.Interfaces (Any CPU),但在 fuslogvw.exe 中,我发现了一个隐藏的“尝试加载格式不正确的程序”异常来自 MyApp .CommonTypes (x86) 两者都使用。
回答by Serge Desmedt
I got this with a "diamond" shaped project dependency:
我用“钻石”形状的项目依赖项得到了这个:
- Project A uses Project B and Project D
- Project B uses Project D
- 项目 A 使用项目 B 和项目 D
- 项目 B 使用项目 D
I recompiled project A but not Project B, which allowed Project B to "inject" the old version of the Project D dll
我重新编译了项目 A 但没有重新编译项目 B,这使得项目 B 可以“注入”项目 D dll 的旧版本
回答by Kyberias
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.
当我之前在对其中一个程序集进行单元测试期间启用了代码覆盖率时,我也遇到了这个错误。出于某种原因,即使我已经更新它以实现新版本的接口,Visual Studio 还是“缓冲”了这个特定 DLL 的旧版本。禁用代码覆盖消除了错误。