2010-07-27 48 views
2

我試圖重新創建演示目的TypeLoadException抓住了,所以我有一個可笑的愚蠢庫設置,看起來像這樣:TypeLoadException不是由try/catch語句

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:方法get_RemovedProperty'型 'ProxyForV2.ShrinkingThingImpl' 從組件「ProxyForV2,版本= 1.0.0.0,文化=中性,公鑰=空」沒有實現..

所以一個TypeLoadException被拋出,儘管它可能可能拋出的唯一地點是在try塊用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便嘗試在所有加載類的問題起源,不是來自任何任務。

我對緩解這個問題的唯一想法是嘗試在不同的應用程序域中加載類型,以便它不會干涉,然後做一些瘋狂的反射,以查看接口是否與實現兼容,但似乎像徹底和徹底的矯枉過正。

總結:爲什麼看起來不可能以「正常」的方式捕捉這個問題,以及如何在運行時解決這樣的問題?

+1

不完全確定在這一個,所以只有評論...不要單元測試的類型都得到加載前?所以TypeLoadException實際上在你進入你的try/catch塊之前拋出。我不知道你怎麼可以測試這個,雖然... – Jaymz 2010-07-27 18:45:58

+0

類還有其他的單元測試,通過完美罰款。如果您的意思是在方法調用中加載方法中使用的類型,那可能是問題的根源。 – 2010-07-27 19:01:30

回答

5

在使用它們的方法開始執行之前,類型會被加載。要做到這一點,你需要:

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

作品。它也可以通過使用lambda函數來做同樣的事情。 – 2010-07-27 19:14:49

+0

@TravisGockel lamda函數的任何示例? – Kiquenet 2014-03-27 09:58:28

+0

@Kiquenet:因爲它已經4年了,我不記得確切的,但我認爲在'try'塊裏面,我說了類似於:Action f = delegate(){var x = new ProxyForV2.ShrinkingThingImpl() ; }; f();' – 2014-03-31 23:32:06