Кто-нибудь все еще использует [goto] в С#, и если да, то почему?

Мне было интересно, все еще использует синтаксис ключевых слов "goto" на С# и какие возможные причины для этого.

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

Перейти к определению ключевого слова

Ответ 1

Есть некоторые (редкие) случаи, когда goto может улучшить читаемость. Фактически в документации, к которой вы привязаны, приведены два примера:

Общее использование goto заключается в передаче управления на конкретную метку ключа коммутатора или метку по умолчанию в инструкции switch.

Оператор goto также полезен для выхода из глубоко вложенных циклов.

Вот пример для последнего:

for (...) {
    for (...) {
        ...
        if (something)
            goto end_of_loop;
    }
}

end_of_loop:

Конечно, есть и другие способы решения этой проблемы, такие как рефакторинг кода в функцию, использование фиктивного блока вокруг него и т.д. (см. этот вопрос для деталей). В качестве стороннего примечания разработчики языка Java решили полностью запретить goto и ввести вместо этого выражение с надписью break.

Ответ 2

Я помню эту часть

switch (a)     
{ 
    case 3: 
        b = 7;
        // We want to drop through into case 4, but C# doesn't let us
    case 4: 
        c = 3;
        break; 
    default: 
        b = 2;
        c = 4;
        break; 
}

Что-то вроде этого

switch (a)     
{
    case 3: 
        b = 7;
        goto case 4;    
    case 4: 
        c = 3;
        break;     
    default: 
        b = 2;
        c = 4;
        break;
}

Обратитесь Это

Ответ 3

Я использую его в Eduasync, чтобы показать тип кода, который генерирует компилятор для вас при использовании методов async в С# 5 Вы увидите то же самое в блоках итератора.

В "нормальном" коде, однако, я не могу вспомнить последний раз, когда я его использовал...

Ответ 4

goto отлично подходит для выхода из многих циклов, где перерыв не будет работать хорошо (скажем, при ошибках), и, как сказал Краген, goto используется компилятором для генерации операторов switch и некоторых других вещей.

Ответ 5

Компилятор использует выражения goto в разных частях сгенерированного кода, например, в сгенерированных типах блока итератора (генерируемых при использовании ключевого слова yield return). Я уверен, что сгенерированные типы сериализации XML также имеют несколько goto где-то там.

См. Детали реализации блока Iterator: автогенерированные конечные машины для получения более подробной информации о том, почему и как компилятор С# справляется с этим.

Помимо сгенерированного кода нет веских оснований для использования инструкции goto в нормальном коде - это делает код более сложным для понимания и, как результат, более подверженным ошибкам. С другой стороны, использование операторов goto в сгенерированном коде, таком как это, может упростить процесс генерации и нормально нормально, потому что никто не собирается читать (или изменять) сгенерированный код, и нет никаких шансов на ошибку, поскольку машина делает запись.

См. Утверждение Go-to, считающееся вредным для аргумента против goto, а также классическую часть истории программирования.

Ответ 6

Я не помню когда-либо используя goto. Но, возможно, это улучшает цель непрерывного цикла, который вы действительно никогда не хотите покидать (нет break, но вы все еще можете return или throw):

forever: {
  // ...
  goto forever;
}

Затем снова нужно простое while (true)...

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

Ответ 7

Процессор реализует хотя бы одну , и я уверен, что многие заявления используют их в реализации или интерпретации.

Одна из хороших вещей об использовании 3rd или 4th langauge - это то, что эти физические детали отвлечены от нас. Хотя мы должны помнить закон нечеткой абстракции Я думаю, что мы также должны использовать наш инструменты, поскольку они предназначены (извините). Если бы я писал код, а goto казался хорошей идеей, настало время для рефакторинга. Цель структурированного языка - избегать этих "прыжков" и создавать логический поток в нашей технике.

Мне следует избегать использования break, но я не могу забыть о преимуществах производительности. Однако, если у меня есть вложенные петли, которые взаимно нуждаются в break, пришло время рефакторировать.

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

Надеюсь, я не виновен в том, чтобы спешить с "байковым сараем здесь. Как говорит Краген, достаточно хорошего для Dijkstra для меня достаточно.

Ответ 8

Я смотрел чистый исходный код и нападал на this в свойстве ControlStyle для WebControl

public Style ControlStyle
{
    get
    {
        if (this.controlStyle == null)
        {
            this.controlStyle = this.CreateControlStyle();
            if (base.IsTrackingViewState)
            {
                this.controlStyle.TrackViewState();
            }
            if (!this._webControlFlags[1])
            {
                goto IL_4D;
            }
            this._webControlFlags.Clear(1);
            this.controlStyle.LoadViewState(null);
        }
        IL_4D:
        return this.controlStyle;
    }
}

Таким образом, даже Microsoft использует его

Ответ 9

Это особенно хорошо, когда вам нужно очистить перед возвратом из метода, например.

        while (stream.Read(buffer, 0, 4) == 4)
        {
            // do smth with the 4 bytes read here

            if (stream.Read(buffer, 0, 4) != 4) goto CLOSE_STREAM_AND_RETURN;

            // do more stuff

            if (stream.Read(buffer, 0, 4) != 4) goto CLOSE_STREAM_AND_RETURN;

            // more stuff
        }

        CLOSE_STREAM_AND_RETURN:

        stream.Close();

Вдохновленный: http://eli.thegreenplace.net/2009/04/27/using-goto-for-error-handling-in-c/

Ответ 10

Гото никогда не бывает лучше. И продолжайте, перерыв (за исключением переключателя/случая), (множественный) возврат, а бросок также должен быть сведен к минимальному минимуму. Вы никогда не хотите убегать от середины петлей гнезд. Вы всегда хотите, чтобы операторы управления циклом имели все элементы управления контуром. Отступы имеют информацию, и все эти утверждения отбрасывают эту информацию. Вы могли бы также вынуть все отступы.