Подтвердить что ты не робот

Почему С# не поддерживает фильтрацию исключений первого шага?

Примечание: это не дубликат вопроса Джеффа.

Этот вопрос спросил: "Это эквивалент?" Я знаю, что нет, и я хочу знать, почему!

Причина, по которой я спрашиваю, это то, что я только что понял, насколько это важно, и вывод кажется мне очень странным.

Блок обработки исключений Microsoft Enterprise Library рекомендует использовать этот шаблон:

catch (Exception x)
{
    if (ExceptionPolicy.HandleException(x, ExceptionPolicies.MyPolicy))
        throw;

    // recover from x somehow
}

Политика определяется в XML файле, поэтому это означает, что если у клиента возникла проблема, мы можем изменить политику, чтобы помочь с отслеживанием (или, возможно, скреплением) проблемы, чтобы дать им быстрое разрешение, пока мы не справимся с ним должным образом - что может включать в себя споры с третьими сторонами, о чьей вине это все.

Это в основном признание простого факта, что в реальных приложениях количество исключений и их статус "восстановления" практически невозможно обойти без такого объекта.

Между тем команда CLR в MS говорит, что это не вариант, и, оказывается, эти ребята знают, о чем они говорят! Проблема заключается в том, что перед запуском блока catch выполняется выполнение любых блоков finally, вложенных в блок try. Таким образом, эти блоки finally могут выполнять любое из следующих действий:

  • Безвредно изменить состояние программы (phew, lucky).
  • Извлеките что-то важное в данных клиента, потому что состояние программы прикручено до неизвестной степени.
  • Замаскируйте или уничтожьте важные доказательства того, что нам нужно диагностировать проблему, особенно если мы говорим о вызовах в собственный код.
  • Бросьте еще одно исключение, добавив к общей путанице и страданиям.

Обратите внимание, что дескрипторы using и деструкторы С++/CLI построены на try/finally, поэтому они также затронуты.

Таким образом, шаблон catch/throw для фильтрации исключений не является хорошим. Фактически необходим способ фильтрации исключений посредством политики без их улавливания и, таким образом, запуска выполнения блоков finally, если мы не найдем политику, которая говорит нам, что исключение безопасно восстанавливать.

Команда CLR сообщила об этом недавно:

В результате мы должны написать вспомогательную функцию в VB.NET, чтобы позволить нам получить доступ к этой жизненно важной возможности из С#. Большая проблема в том, что есть проблема в том, что в BCL есть код, который делает это. Многие люди писали об этом, но редко упоминают о блоках try/finally, которые являются убийцами.

Что я хотел бы знать:

  • Есть ли публичные заявления или прямые письма, которые люди получили от команды С# по этому вопросу?
  • Есть ли какие-либо предложения Microsoft Connect, требующие этого? Я слышал слухи о них, но ни один из вероятных ключевых слов не появился.

Обновление:, как указано выше, я уже искал в Microsoft Connect, ничего не обнаружив. У меня также (неудивительно) Googled. Я только нашел людей объясняя, зачем им нужна эта функция или указывая преимущества этого в VB.NET или бесплодно надеясь, что он будет добавлен в будущую версию С#, или обходится вокруг, и много вводящие в заблуждение советы, Но никаких утверждений об обосновании отказа от нее из всех текущих версий С#. И причина, по которой я спрашиваю о существующих проблемах Connect, заключается в том, что (а) я не создаю ненужный дубликат и (б) я могу рассказать заинтересованным лицам, если мне нужно его создать.

Обновление 2: найдено интересное старое сообщение в блоге от Эрика Гуннерсона, ранее из команды С#:

"Да, возможность поставить условие на улов несколько более удобен чем писать тест самостоятельно, но это действительно не позволяет вы должны сделать что-нибудь новое".

Это было то же самое предположение, что и у меня, до тех пор, пока оно не было должным образом объяснено мне.

4b9b3361

Ответ 1

Что касается любых существующих ошибок подключения. Следующий вопрос касается исключений fliters. Пользователь явно не заявлял, что хочет, чтобы они были фактическим фильтром в том смысле, когда они выполняются, но ИМХО это подразумевается логикой.

https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=401668

Кроме того, однако, нет никаких проблем, которые я могу найти или знать, которые связаны с тем, что вы ищете. Я думаю, что было бы хорошо иметь отдельную проблему, которая явно вызывает необходимость в фильтрах исключений стиля VB.Net.

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

Что касается части получения официального ответа от команды С#, вы, скорее всего, получите это, когда вы либо 1) зарегистрируете ошибку подключения, либо 2) обманетесь против основной ошибки. Я действительно сомневаюсь, что сейчас есть официальная причина/оправдание.

Вот моя спекуляция по этой проблеме: я предполагаю, что эта функция просто не была установлена ​​на исходном наборе функций С# 1.0, и с тех пор не было достаточного требования, чтобы сделать это в язык. Команда С# и VB тратят невероятное количество языковых функций ранжирования в начале каждого цикла корабля. Мы должны иногда выполнять некоторые очень сложные сокращения. Без достаточного спроса очень мало шансов, что функция перейдет на язык.

До недавнего времени я уверен, вам будет трудно найти 1 из 10 человек, которые понимают разницу между VB.Net Try/When и просто используют простой старый оператор if в блоке catch С#. В последнее время это немного больше напоминает людей, поэтому, возможно, это превратит его в будущую версию langauge.

Ответ 2

Использование Включение фильтра исключений может быть проще, чем использование обходного пути делегата.

Для реального ответа на ваш вопрос вам понадобится ответ от Андерса Хейлсберга или того, кто был на оригинальных проектных встречах. Вы можете попытаться посмотреть, сможете ли вы попросить интервьюер канала 9 в следующий раз команда разработчиков С# провела интервью.

Я предполагаю, что когда было принято первоначальное решение, фильтры исключений были рассмотрены как ненужное осложнение, которое могло бы принести больше вреда, чем пользы. Вы наверняка увидите желание оставаться "молчаливым" о недоказанных особенностях этого интервью о решении не поддерживать проверенные исключения: Проблема с проверенными исключениями.

Я думаю, что сценарии диагностики postmoterm аргументируют решимость обеспечить доступ к фильтрам исключений на языке. Однако эти сценарии, возможно, не были сформулированы в то время. Также эти сценарии действительно нуждаются в надлежащей поддержке инструментальных средств, что, безусловно, не было доступно в V1. Наконец, могут быть большие негативы в отношении добавления этой функции, которую мы не рассматриваем.

Если в этом нет ошибки подключения, вы должны ввести ее и побудить других ее проголосовать. [Я бы рекомендовал просить доступ к функции CLR, а не пытаться спроектировать, как он подходит на этом языке.]

Ответ 3

Я не верю, что у Java есть опция фильтра. Угадав, что если это произойдет, мы также увидим его на С#. Вероятно, у VB.net есть случайность, учитывая, что команда VB началась с чистого листа.

Одна вещь, которая может сработать в вашу пользу, если набрать эту опцию в будущей версии С#, - это заявленная цель Microsoft поддерживать паритет между функциями laguage в будущих версиях С# и VB.net. Я бы изложил свои аргументы, основываясь на этом.

http://www.chriseargle.com/post/2009/01/Parity-Between-Languages.aspx

Ответ 4

Что касается первого вопроса, если было публичное выражение, то он, скорее всего, попадал в сеть где-то, и в этом случае Google должен что-то активировать (если он существует).

Если это прямой адрес электронной почты с командой С#, то более чем вероятно, что он находится под NDA, поэтому он не сможет быть опубликован в любом случае.

Во втором вопросе есть возможность поиска в Microsoft Connect, которую они запрашивают перед использованием нового предложения. Если вы не можете найти его, то, вероятно, не один.

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

Ответ 5

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

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

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

Ответ 6

Я могу представить себе как минимум две причины, по которым фильтрация исключений отсутствует в С#

  • Разрешение фильтров исключений может побуждать программистов делать что-то во время обработки исключений в первом проходе, которые в то время были бы небезопасными, хотя они могли бы быть безопасно реализованы в "catch" или "finally". Например, если код в блоке "try" получает блокировку и генерирует исключение при блокировке блокировки, блокировка будет удерживаться во время выполнения внешних фильтров исключений, но будет выпущена до внешнего "catch" или "finally" выполняется блок. Кроме того, по крайней мере, в последний раз, когда я проверял, исключения, которые произошли в фильтрах исключений и не попали в него, были тихо заглушены - что-то вроде уродливой ситуации.
  • У исполнителей С# есть представление о том, как сделать их язык "агностиком". Если С# поддерживала фильтрацию исключений первого прохода .net, программы, которые использовали эту функцию, могут быть непригодными для фреймворков, которые обрабатывают исключения по-разному. Это по той же причине, что С# запрещает программам переопределять `Object.Finalize()`. Хотя аргументация, связанная с `Object.Finalize()`, является ошибочной (правильное использование деструкторов требует использования других специфичных для платформы методов, поэтому требование использования синтаксиса деструктора для объекта Object.Finalize() `ничего не делает, кроме того, что t77o поощряет написание дефектное программное обеспечение), рассуждение действительно имеет смысл в отношении фильтров исключений. С другой стороны, правильный способ решения этой проблемы состоит в том, чтобы выявить некоторые связанные с фильтром функции, связанные с фильтрацией фильтров, даже если они не отображали напрямую фильтры исключений.

Одна из функций, которые мне бы очень хотелось увидеть на С# и vb, которые потребуют использования фильтров исключений для реализации, но которые не требуют непосредственного их отображения, будут необязательным параметром Exception для блока finally, Этот параметр был бы null, если не произошло неперехваченное исключение; в противном случае оно будет содержать рассматриваемое исключение. Это позволило бы ситуации, когда программа захочет что-то делать, когда возникает исключение, но на самом деле не "обрабатывает" ее. В большинстве случаев параметр Exception не использовался ни для чего, кроме как для проверки null (что означает, что функция будет эквивалентна экспонированию блоков fault), но она будет иметь преимущества в случаях, когда исключение возникает во время очистки. В настоящее время, если исключение происходит во время блока finally, необходимо либо заглушить исключение finally -block, либо перезаписать ранее существовавший. Наличие более раннего исключения, доступного блочному коду finally, позволит ему либо обернуть, либо зарегистрировать его.