[英]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.