代码之家  ›  专栏  ›  技术社区  ›  Travis Gockel

try/catch未捕获TypeLoadException

  •  3
  • Travis Gockel  · 技术社区  · 15 年前

    我想重新创造一个 TypeLoadException

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

    TheLibrary 版本1具有以下相关接口:

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

    而版本2 图书馆 的接口如下所示:

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

    ProxyForV2 具有实现版本2.0的类 IShrinkingThing

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

    所以,在 TestProject ,我希望引起 如果有人试图分配 ProxyForV2.ShrinkingThingImpl ,因为接口的第一个版本具有第二个版本未实现的属性。为了证明这一点,我有一个单元测试,它看起来像:

    [TestMethod]
    public void ShrinkingThingBreaks()
    {
        try
        {
            IShrinkingThing thing = new ProxyForV2.ShrinkingThingImpl();
    
            Assert.Fail("This should have caused a TypeLoadException");
        }
        catch (TypeLoadException)
        {
            //  valid
        }
    }
    

    Assert.Fail ,正如我所料。测试输出如下所示:

    测试方法TestProject.LoadTester.ShrinkingThingBreaks引发异常:System.TypeLoadException:程序集“ProxyForV2,Version=1.0.0.0,Culture=neutral,PublicKeyToken=null”的类型“ProxyForV2.ShrinkingThingImpl”中的方法“get\RemovedProperty”没有实现。。

    TypeLoadException类型加载异常 被扔到了一个地方 被扔在一个 try 用a挡块 catch (TypeLoadException) ,异常拒绝被捕获。除此之外,即使我使用了catch all,单元测试也会失败,错误与之前相同:

    [TestMethod]
    public void ShrinkingThingBreaks()
    {
        try
        {
            IShrinkingThing thing = new ProxyForV2.ShrinkingThingImpl();
    
            Assert.Fail("This should have caused a TypeLoadException");
        }
        catch
        {
            //  valid
        }
    }
    

    怎么回事?显然,这是一个完全人为的场景,但是我仍然想知道发生了什么,以便在运行时避免这个错误,或者至少在发生错误时处理它(是的,我知道最终的解决方案是确保所有库版本都是相同的)。

    最糟糕的是 任何 访问类,例如 typeof(ProxyForV2.ConsistentThingImpl) ProxyForV2.ConsistentThingImpl.SomeStaticFunction() 导致无法捕捉 ,因此很明显,问题是在.NET尝试加载类时产生的,而不是任何赋值。

    我缓解这个问题的唯一想法是尝试在不同的应用程序域中加载类型,这样它就不会干扰,然后做一些疯狂的反射,看看接口是否与实现兼容,但这似乎是完全的和完全的过度。

    总结:为什么看起来不可能以“正常”的方式捕捉到这个问题,如何在运行时解决这样的问题?

    1 回复  |  直到 15 年前
        1
  •  6
  •   ConsultUtah    15 年前

    这些类型在使用它们的方法开始执行之前被加载。为此,您需要:

    [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();
    }
    
    推荐文章