2010-07-27 2 views
2

я пытаюсь воссоздать TypeLoadException для демонстрационных целей, так что я неимоверно тупой настройка библиотеки, которая выглядит следующим образом:TypeLoadException не захватываются Try/уловом

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 интерфейсов TheLibrary «s выглядеть следующим образом:

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, Version = 1.0.0.0, культура = нейтральная, PublicKeyToken = нуль»не есть реализация ..

Так 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() причин это не-catchable TypeLoadException, так что ясно, что проблема возникает, когда .NET пытается загрузить класс на всех, не от какого-либо задания.

Моя единственная идея для смягчения этой проблемы - попытаться загрузить тип в другом домене приложения, чтобы он не мешал, а затем делал некоторые сумасшедшие вещи отражения, чтобы увидеть, совместим ли интерфейс с реализацией, но это кажется как полный и полный избыток.

Вкратце: почему кажется невозможным поймать эту проблему «обычным» способом и как я могу решить такие проблемы во время выполнения?

+1

Не совсем уверен в этом, поэтому только комментируя ... Разве типы для единичного теста не загружаются спереди? Таким образом, TypeLoadException фактически выбрасывается, прежде чем вы даже попадете в блок try/catch. Я не уверен, как вы могли бы проверить это, хотя ... – Jaymz

+0

В классе есть другие модульные тесты, которые проходят отлично. Если вы имеете в виду, что типы, используемые в методах, загружаются при вызове метода, это может быть корень проблемы. –

ответ

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

Работы. Он также работает, делая то же самое с лямбда-функцией. –

+0

@TravisGockel любой образец с функцией lamda? – Kiquenet

+0

@Kiquenet: Как это было 4 года, я точно не помню, но я думаю, что внутри блока 'try' я сказал что-то вроде:« Action f = delegate() {var x = new ProxyForV2.ShrinkingThingImpl() ; }; f(); ' –

 Смежные вопросы

  • Нет связанных вопросов^_^