c# - TypeLoadException 未被 try/catch 捕获

标签 c# type-safety typeloadexception

我正在尝试重新创建一个 TypeLoadException 用于演示目的,所以我有一个看起来像这样的可笑的愚蠢库设置:

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

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

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

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

TheLibrary 的第 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,我预计会导致 TypeLoadException,因为第一个版本接口(interface)的属性具有第二个版本未实现的属性。为了证明这一点,我有一个如下所示的单元测试:

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

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

这是我的问题:这个单元测试失败了。但不是因为我的 Assert.Fail,正如我所期望的那样。测试输出如下所示:

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

所以一个 TypeLoadException 被抛出,虽然它唯一可以可能被抛出的地方是在一个带有 try block 中catch (TypeLoadException),异常拒绝被捕获。除此之外,即使我使用包罗万象,单元测试也会失败并出现与以前相同的错误:

[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() 导致此无法捕获的 TypeLoadException,因此很明显问题出在 .NET 尝试加载类时,而不是来自任何赋值。

我缓解这个问题的唯一想法是尝试在不同的应用程序域中加载类型,这样它就不会干扰,然后做一些疯狂的反射事情来查看接口(interface)是否与实现兼容,但这看起来像完全和完全矫枉过正。

总结:为什么似乎无法以“正常”方式捕获此问题,我如何在运行时解决此类问题?

最佳答案

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

[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();
}

关于c# - TypeLoadException 未被 try/catch 捕获,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3346740/

相关文章:

dynamics-crm-2011 - 导致TypeLoad异常的CRM 2011在线实例的扩展方法

nhibernate - 带有NHibernate的System.Data.SQLite BadImageFormatException,在独立时可以正常工作

c# - 读写装箱双值线程安全且无锁?

c# - 根据属性名称数组创建对象的子集

c# - 为 iPhone 应用程序抓取 MS SQL Server 数据?

java - 以 "type safe"方式做某事是什么意思?

c# - 使用 XmlSerializer 反序列化具有选择的复杂类型元素

security - 在没有 GeneralizedNewtypeDeriving 的情况下破坏 Data.Set 完整性

Objective-C 方法参数类型安全

.net - 关于 TypeLoadException 的帮助