Я пытаюсь воссоздать 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: метод 'get_RemovedProperty' в типе 'ProxyForV2.ShrinkingThingImpl' из сборки 'ProxyForV2, Version = 1.0.0.0, Culture = нейтральный, PublicKeyToken = null 'не имеет реализации ..
Таким образом, 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 пытается загрузить класс вообще, а не из какого-либо назначения.
Моя единственная идея для смягчения этой проблемы - попытаться загрузить тип вдругой домен приложения, чтобы он не вмешивался, а затем делал какие-то безумные размышления, чтобы увидеть, совместим ли интерфейс с реализацией, но это выглядит как полное и полное излишество.
В заключение: почему это кажется невозможнымпоймать эту проблему "нормальным" способом и как я могу решить такие проблемы во время выполнения?