简体   繁体   English

Try / catch没有捕获TypeLoadException

[英]TypeLoadException is Not Caught by try/catch

I am trying to re-create a TypeLoadException for demonstration purposes, so I have a ridiculously goofy library setup that looks like this: 我试图重新创建一个TypeLoadException用于演示目的,所以我有一个荒谬的愚蠢的库设置,如下所示:

TestProject --> TheLibrary [1.0]
            \-> ProxyForV2 -> TheLibrary [2.0]

TheLibrary version 1 has these relevant interfaces: TheLibrary版本1具有以下相关接口:

public interface IConsistentThing
{
    int ConsistentProperty { get; set; }
}

public interface IShrinkingThing
{
    int RemovedProperty { get; set; }
}

While version 2 of TheLibrary 's interfaces look like: 虽然TheLibrary的界面版本2看起来像:

public interface IConsistentThing
{
    int ConsistentProperty { get; set; }
}

public interface IShrinkingThing
{ }

ProxyForV2 has this class which implements the version 2.0 IShrinkingThing : ProxyForV2有这个实现版本2.0 IShrinkingThing

public class ShrinkingThingImpl : IShrinkingThing
{
    public int ConsistentProperty { get; set; }
}

So, in TestProject , I am expecting to cause a TypeLoadException if someone tries to assign a ProxyForV2.ShrinkingThingImpl , since the first version of the interface has a property that is not implemented by the second version. 所以,在TestProject ,我期待导致TypeLoadException如果有人试图分配ProxyForV2.ShrinkingThingImpl ,因为界面的第一个版本具有不通过的第二个版本中实现的属性。 To prove this, I have a unit test which looks like: 为了证明这一点,我有一个单元测试,看起来像:

[TestMethod]
public void ShrinkingThingBreaks()
{
    try
    {
        IShrinkingThing thing = new ProxyForV2.ShrinkingThingImpl();

        Assert.Fail("This should have caused a TypeLoadException");
    }
    catch (TypeLoadException)
    {
        //  valid
    }
}

Here's my problem: this unit test fails. 这是我的问题:这个单元测试失败了。 But not due to the my Assert.Fail , as I would expect it to. 但不是因为我的Assert.Fail ,正如我所期望的那样。 The test output looks like this: 测试输出如下所示:

Test method TestProject.LoadTester.ShrinkingThingBreaks threw exception: System.TypeLoadException: Method 'get_RemovedProperty' in type 'ProxyForV2.ShrinkingThingImpl' from assembly 'ProxyForV2, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' does not have an implementation.. 测试方法TestProject.LoadTester.ShrinkingThingBreaks抛出异常:System.TypeLoadException:程序集'ProxyForV2.ShrinkingThingImpl'中的方法'get_RemovedProperty'来自程序集'ProxyForV2,Version = 1.0.0.0,Culture = neutral,PublicKeyToken = null'没有实现。 。

So a TypeLoadException is being thrown and although the only place it could possibly be thrown is in a try block with a catch (TypeLoadException) , the exception refuses to be caught. 因此抛出了一个TypeLoadException ,虽然它可能被抛出的唯一地方是带有catch (TypeLoadException)try块,但是异常拒绝被捕获。 Beyond that, even if I use a catch-all, the unit test fails with the same error as before: 除此之外,即使我使用了catch-all,单元测试也会失败并出现与之前相同的错误:

[TestMethod]
public void ShrinkingThingBreaks()
{
    try
    {
        IShrinkingThing thing = new ProxyForV2.ShrinkingThingImpl();

        Assert.Fail("This should have caused a TypeLoadException");
    }
    catch
    {
        //  valid
    }
}

What is going on? 到底是怎么回事? Obviously, this is a completely contrived scenario, but I would still like to know what is going on so that this error can be avoided at run time or at least dealt with if it happens (yes, I'm aware the ultimate solution is to make sure all your library versions are the same). 显然,这是一个完全做作的场景,但我仍然想知道发生了什么,以便在运行时可以避免这个错误,或者至少在发生时处理(是的,我知道最终的解决方案是确保所有库版本都相同)。

The worst part is that any access to the class at all, such as typeof(ProxyForV2.ConsistentThingImpl) or ProxyForV2.ConsistentThingImpl.SomeStaticFunction() causes this un-catchable TypeLoadException , so it is clear that the problem originates when .NET tries to load the class at all, not from any assignment. 最糟糕的是,对类的任何访问,例如typeof(ProxyForV2.ConsistentThingImpl)ProxyForV2.ConsistentThingImpl.SomeStaticFunction()都会导致此无法捕获的TypeLoadException ,因此很明显,当.NET尝试加载时,问题就会产生班级,而不是任何作业。

My only idea for mitigating this issue is to try to load the type in a different application domain so that it does not interfere and then do some crazy reflection stuff to see if the interface is compatible with the implementation, but that seems like complete and total overkill. 我唯一想要缓解此问题的方法是尝试在不同的应用程序域中加载该类型,以便它不会干扰,然后做一些疯狂的反射,看看界面是否与实现兼容,但这似乎是完整的和总的矫枉过正。

In summary: Why does it seem impossible to catch this problem in the "normal" way and how can I resolve issues like this at runtime? 总结:为什么似乎不可能以“正常”方式捕获此问题,如何在运行时解决此类问题?

The types get loaded before execution begins on the method that uses them. 在使用它们的方法执行开始之前加载类型。 To do this, you need to: 为此,您需要:

[TestMethod]
public void ShrinkingThingBreaks()
{
    try
    {
        InnerShrinkingThingBreaks();

        Assert.Fail("This should have caused a TypeLoadException");
    }
    catch
    {
        //  valid
    }
}

[MethodImpl(MethodImplAttributes.NoInlining)]
private void InnerShrinkingThingBreaks()
{
        IShrinkingThing thing = new ProxyForV2.ShrinkingThingImpl();
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM