Я не думаю, что это в настоящее время возможно, или если это даже хорошая идея, но я думал об этом только сейчас. Я использую MSTest для модульного тестирования моего C # проекта. В одном из моих тестов я делаю следующее:
MyClass instance;
try
{
instance = getValue();
}
catch (MyException ex)
{
Assert.Fail("Caught MyException");
}
instance.doStuff(); // Use of unassigned local variable 'instance'
Чтобы этот код компилировался, мне нужно присвоить значение instance
либо в его объявлении, либо в блоке catch
. В качестве альтернативы я мог бы return
после Assert.Fail
, но это все еще обходной путь вместо компилятора, просто зная , что выполнение не может продолжаться после этой точки. Насколько мне известно, Assert.Fail
никогда не позволит выполнить выполнение после него, поэтому instance
никогда не будет использоваться без значения. Почему тогда я должен присвоить ему значение? Если я изменю Assert.Fail
на что-то вроде throw ex
, код скомпилируется нормально, я предполагаю, потому что он знает, что исключение не допустит выполнения до точки, где instance
будет использоваться неинициализированным.
Наоборот, что если я не хочу, чтобы тест провалился, а был помечен как неокончательный? Я мог бы сделать Assert.Inconclusive
вместо Fail
, и было бы неплохо, если бы компилятор знал, что выполнение не будет продолжаться после этого.
Так это случай, когда знания времени выполнения или времени компиляции о том, где будет разрешено выполнение выполнения? Будет ли когда-либо разумным для C # говорить, что член, в данном случае Assert.Fail
, никогда не разрешит выполнение после его возврата? Может быть, это может быть в форме атрибута метода. Будет ли это полезным или ненужной сложностью для компилятора?
Внешние юнит-тесты
Поскольку люди [справедливо] указывают, что это глупый способ написания модульного теста, рассмотрим мой вопрос за пределами области модульного тестирования:
MyClass instance;
if (badThings)
{
someMethodThatWillNeverReturn();
}
else
{
instance = new MyClass();
}
instance.doStuff();
Здесь потенциально я мог бы заменить вызов someMethodThatWillNeverReturn
на выдачу исключения, и, возможно, если бы у меня было что сделать, я мог бы сделать это в конструкторе для исключения.
Решарпер знает
Если я добавлю return
после Assert.Fail
или Assert.Inconclusive
, Resharper окрашивает return
в серый цвет и имеет всплывающую подсказку «Код эвристически недоступен».