Лично я хотел бы использовать Maven surefire JUnit runner для этого.
Я подозреваю, что это - вопрос практичности, а не выполнимости. Я подозреваю, что существует очень, буквально несколько раз, где это ограничение на самом деле проблема, которая не может работаться вокруг - но добавленная сложность в компиляторе была бы очень значительной.
существует несколько вещей как это, что я уже встретился:
В каждом из этих случаев, было бы возможно получить немного больше свободы, за счет дополнительной сложности в компиляторе. Команда сделала прагматический выбор, за который я хвалю их - у меня был бы немного более строгий язык с точным компилятором на 99,9% (да, существуют ошибки; я столкнулся один на ПОЭТОМУ просто на днях), чем более выразительный язык, который не мог скомпилировать правильно.
РЕДАКТИРОВАНИЕ: вот псевдодоказательство того, как это, почему это выполнимо.
Полагают что:
Теперь преобразуйте:
try
{
Console.WriteLine("a");
yield return 10;
Console.WriteLine("b");
}
catch (Something e)
{
Console.WriteLine("Catch block");
}
Console.WriteLine("Post");
в (вид псевдокода):
case just_before_try_state:
try
{
Console.WriteLine("a");
}
catch (Something e)
{
CatchBlock();
goto case post;
}
__current = 10;
return true;
case just_after_yield_return:
try
{
Console.WriteLine("b");
}
catch (Something e)
{
CatchBlock();
}
goto case post;
case post;
Console.WriteLine("Post");
void CatchBlock()
{
Console.WriteLine("Catch block");
}
единственное дублирование находится в установке блоков попытки/выгоды - но это - что-то, что компилятор может, конечно, сделать.
я, возможно, пропустил что-то здесь - если так, сообщите мне!
Весь эти yield
операторы в определении итератора преобразовываются в состояние в конечном автомате, который эффективно использует switch
оператор для усовершенствования состояний. Если бы это сделало , генерируют код для yield
операторы в попытке/выгоде, которую это должно было бы копировать все в try
блок для каждый yield
оператор в то время как, исключая любой yield
оператор для того блока. Это не всегда возможно, особенно если один yield
оператор является иждивенцем на более раннем.
Я размышлял бы, что из-за пути стек вызовов добирается, ранили/раскрутили, когда Вы приводите к возврату из перечислителя, для блока попытки/выгоды становится невозможно на самом деле "поймать" исключение. (потому что блок возврата урожая не находится на стеке, даже при том, что он породил итеративный блок)
Для получения ideea того, что я говорю об установке блок итератора и использование foreach тот итератор. Проверьте то, на что Стек вызовов похож в foreach блоке, и затем проверьте, что это в итераторе пробует/наконец блок.
Я принял ответ НЕУКРОТИМОЙ СТРЕЛЬБЫ ПО ТАРЕЛОЧКАМ, пока кто-то от Microsoft не приезжает для заливки холодной воды на идее. Но я не соглашаюсь с частью дела вкуса - конечно, корректный компилятор более важен, чем полный, но компилятор C# уже очень умен в разбирании в этом преобразовании для нас, насколько это делает. Немного больше полноты в этом случае сделало бы язык легче использовать, преподавать, объяснить, с меньшим количеством пограничных случаев или глюков. Таким образом, я думаю, что это стоило бы дополнительного усилия. Несколько парней в Редмонде царапают головы в течение двух недель, и в результате миллионы кодеров за следующее десятилетие могут ослабиться немного больше.
(я также питаю противное требование там, чтобы быть способом сделать yield return
, выдают исключение, которое было наполнено в конечный автомат "с внешней стороны", кодом, управляющим повторением. Но мои причины желания этого довольно неясны.)
На самом деле один запрос, который я имею об ответе Jon, относится к броску выражения возврата урожая.
, Очевидно, возврат урожая 10 не так плох. Но это было бы плохо:
yield return File.ReadAllText("c:\\missing.txt").Length;
Так не был бы он иметь больше смысла оценивать эту внутреннюю часть предыдущий блок попытки/выгоды:
case just_before_try_state:
try
{
Console.WriteLine("a");
__current = File.ReadAllText("c:\\missing.txt").Length;
}
catch (Something e)
{
CatchBlock();
goto case post;
}
return true;
следующая проблема была бы вложена блоки попытки/выгоды и повторно брошенные исключения:
try
{
Console.WriteLine("x");
try
{
Console.WriteLine("a");
yield return 10;
Console.WriteLine("b");
}
catch (Something e)
{
Console.WriteLine("y");
if ((DateTime.Now.Second % 2) == 0)
throw;
}
}
catch (Something e)
{
Console.WriteLine("Catch block");
}
Console.WriteLine("Post");
, Но я уверен, что это возможно...