Почему C # не поддерживает фильтрацию исключений при первом проходе? - PullRequest
30 голосов
/ 02 марта 2009

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

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

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

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

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

    // recover from x somehow
}

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

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

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

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

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

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

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

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

То, что я хотел бы знать:

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

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

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

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

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

Ответы [ 6 ]

4 голосов
/ 07 марта 2009

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

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

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

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

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

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

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

2 голосов
/ 07 марта 2009

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

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

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

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

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

1 голос
/ 07 марта 2009

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

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

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

0 голосов
/ 22 февраля 2012

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

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

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

0 голосов
/ 03 марта 2009

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

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

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

0 голосов
/ 02 марта 2009

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

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

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

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

...