C# - Как создать необнаруживаемый бесконечный цикл?

Это просто, "Я - Любопытный" вопрос.

В Jon Skeet C#-in-depth говорит о лямбда-выражениях:
"если существует непустой тип возврата, каждый путь выполнения кода должен возвратить совместимое значение". (Страница 233)

В сноске тогда говорится:
"Выдающие исключения пути выполнения кода не должны возвращать значение, конечно, и ни один не делает обнаруживаемые бесконечные циклы". (Страница 233)

Я задаюсь вопросом, что составляет необнаруживаемый бесконечный цикл?

Это может быть сделано только логикой? или это сделано при помощи внешних факторов как система баз данных или файловая система?

13
задан Vaccano 22 February 2010 в 19:05
поделиться

2 ответа

То, на что ссылается Джон, описано в разделе 8.1 спецификации. Компилятор может обнаружить только очень простые бесконечные циклы, например:

while(true) { if (0 != 0) return 123; }

Компилятор достаточно умен, чтобы увидеть, что возврат никогда не будет достигнут, и поэтому цикл будет выполняться вечно. Законно, хотя и безумно, сказать:

int M() { while(true) { } }

потому что, хотя нет пути, который возвращает int, нет также пути, который возвращает без возвращения int!

Компилятор недостаточно умен, чтобы найти другие виды бесконечных циклов. Например:

int x = 123;
while(true) { if (x * 0 != 0) break; }

Это явно бесконечный цикл. Но компилятор этого не знает. Компилятор говорит: "Ну, может быть, есть какое-то значение x, при котором x * 0 не равно нулю, тогда прерывание достижимо, и это не бесконечный цикл". Мы с вами знаем, что это невозможно, потому что знаем математику, а компилятор - нет.

Прочитайте раздел 8.1, если вам нужны подробности.

21
ответ дан 1 December 2019 в 21:52
поделиться

Довольно тривиально создать бесконечный цикл с использованием внешних источников или даже с использованием таких инструментов, как интерфейсы.

Например:

  public interface INumbers
    {
        int GetNumber(int arg);
    }
    public class StaticNumber : INumbers
    {
        public int GetNumber(int arg)
        {
            return 1;
        }
    }
    public void DoStuff(INumbers num)
    {
        int i = 42;
        while ((i = num.GetNumber(i)) != 0)
        {
            ;
        }
    }

, а затем простой

Action action = () => DoStuff(new StaticNumber());
3
ответ дан 1 December 2019 в 21:52
поделиться
Другие вопросы по тегам:

Похожие вопросы: