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


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

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

Определение Ключевого Слова Goto

9 84

9 ответов:

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

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

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

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

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

end_of_loop:

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

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

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;
}

см. этой

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

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

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

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

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

опять же, простой while (true) должно хватить...

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

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

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

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

посмотреть перейти к рассмотрению заявления вредно за аргумент против goto а также классический кусок истории программирования.

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

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

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

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

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

Я смотрел на.net исходный код и врезался в этой в свойстве 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 использует его

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