[英]TypeLoadException is Not Caught by try/catch
我试图重新创建一个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; }
}
虽然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
,我期待导致TypeLoadException
如果有人试图分配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.ShrinkingThingImpl'中的方法'get_RemovedProperty'来自程序集'ProxyForV2,Version = 1.0.0.0,Culture = neutral,PublicKeyToken = null'没有实现。 。
因此抛出了一个TypeLoadException
,虽然它可能被抛出的唯一地方是带有catch (TypeLoadException)
的try
块,但是异常拒绝被捕获。 除此之外,即使我使用了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()
都会导致此无法捕获的TypeLoadException
,因此很明显,当.NET尝试加载时,问题就会产生班级,而不是任何作业。
我唯一想要缓解此问题的方法是尝试在不同的应用程序域中加载该类型,以便它不会干扰,然后做一些疯狂的反射,看看界面是否与实现兼容,但这似乎是完整的和总的矫枉过正。
总结:为什么似乎不可能以“正常”方式捕获此问题,如何在运行时解决此类问题?
在使用它们的方法执行开始之前加载类型。 为此,您需要:
[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.