- 01
- 02
- 03
- 04
- 05
- 06
- 07
- 08
- 09
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
private static bool TryDeleteFile(string path)
{
try
{
File.Delete(path);
return true;
}
catch (IOException e)
{
return false;
}
catch (UnauthorizedAccessException e)
{
return false;
}
catch (ArgumentException ae)
{
return false;
}
catch (NotSupportedException e)
{
return false;
}
}
catch (IOException e){
}
catch (UnauthorizedAccessException e) {
}
catch (ArgumentException ae){
}
catch (NotSupportedException e){
}
return false;
(например: Delete(F); Result := (IOResult = 0);) Когда вводили этот механизм (для того, чтобы упростить диагностику ошибок и сделать программы более живучими в случае ошибок), то не предполагали, что быдлокодота будет вхреначивать этот непростой по внутреннему устройству механизм во все щели.
Единственное встретившееся мне место (возможно, если другие, но в данном говнокоде не тот случай), где исключение - именно штатная ситуация - это вычисление некоторых выражений, мне этот вопрос подвернулся при написании калькулятора. Как узнать, сосчитается ли exp(a*b), зная a и b? Только попытавшись вычислить и отловив исключение. Если есть другой способ - подскажите. А то исключение генерирует сопроцессор при попытке извлечения NANа в память, как это убрать - не знаю.
Она изначально предназначена для отлова того, что в нормально работающей программе произойти не может. Кто ж думал, что её будет использовать все, кому не лень?
во всяком случае, еще хуже было до этого, напр. в паскале:
Конечно, я ипользую блок try. Но только для ситуаций, которых по идее быть не должно, и для того, чтобы программа вывела все подробности ошибки.
А тут бац - и ошибка. Как быть в таком случае?
К примеру, функция возращает интовое значение от минус до плюс бесконечности. А внутри произошла ошибка о которой пользователь должен знать однозначно. Назовешь решение с системой флагов без извращений - респект тебе и уважуха.
:3
двачую :)
Это место мне уже непонятно. Вы имели в виду беззнаковое 64-битное? Или длинную арифметику?
Сколько там неявных траев-катчей втыкается в код.
а они там как приглашенные эксперты =)
т.е. сплошное легаси.
можно было бы сделать так в псевдокоде с анонимными типами и паттерн-матчингом:
method GetSomeIntResult(a: String, b: int): [ Success(value: int) | FileNotFound(message: String) | SecurityError(message: String) ] <-- возвращается вариантный анонимный тип
и далее так:
Оверхед только через стек.
record
KindOfRes: (Success, FileNotFound, SecurityEror);
case byte of
0: (Value: integer);
1: (Message: string);
end;
end;
Нет. У исключений есть дополнительная возможность выйти на несколько функций вверх, и даже остаться в текущей.
+ возможность множества обработчиков, получающих исключения по принципу сообщений.
+ автоматическая классификация ошибки, например по типу объекта (для ООП исключений).
Конечно любой из этих возможностей можно не пользоваться, но многообразие выбора увеличивает удобство и лёгкость затачивания кода под конкретную задачу.
Это нахрен не надо. Покажите пример, чтобы это надо было. В говнокодах сойдёт.
> и даже остаться в текущей.
Внезапно предложенный мной вариант (вообще-то не мной, он давно в норомальных языках используется) тоже позволяет остаться в текущем стекфрейме.
> возможность множества обработчиков, получающих исключения по принципу сообщений.
Пример?
> автоматическая классификация ошибки, например по типу объекта (для ООП исключений).
А я привёл вариантный тип, чем не устраивает паттерн-метчинг? То же определение по (под)типу.
> Конечно любой из этих возможностей можно не пользоваться, но многообразие выбора увеличивает удобство и лёгкость затачивания кода под конкретную задачу...
... и возможность для приложения за'crash'иться. Но от этого спасают проверяемые исключения как в яве. Но тогда отличия от предложенной мной схемы нету.
чем же лучше ваши мегакрутые гипотезы уже давно существующего механизма исключений?
мой переписанный пример плох лишь тем, что обработчики идентичны, но можно их вынести в отдельный метод, если код усложнится
ололо, алгебраические типы и паттерн-метчинг существовали задолго до кривого, дорогостоящего костыля под названием "исключения". и это не гипотезы, дорогой мой необразованный друг, подобное вовсю используется в языках высокого уровня (ФЯ, например (сишарпы и с++ это языки среднего уровня)).
> чем же лучше
Производительностью при кидании исключения, например. В исключениях используется туева куча дорогостоящих костылей, а тут только оверхед через стек (причём варианты они пакуются через union'ы внутренне, т.е. в основном это максимум 1 указатель на Message).
Отличий много, хотя бы в том, что мы не имеем лишней сущности "исключение", а имеем лишь одну сущность "результат" (который может быть фейл или не фейл), и можем ad-hoc создавать "исключения" разного типа. В с++ надо писать тонны мусора. В прочем, обезьянкам платят за количество строк кода, поэтому среди них подобное не будет популярно. Вообще идею можно развить и получить большую гибкость, я же уже привёл к примеру параллельный метчинг.
Алсо, тут исключение благодаря анонимному типу становится подтипом результата. Можно всё это упакованно хранить. Можно обработку исключения отложить. И т. д.
в неяве как: из функции несколько выходов, причём явный только один. не функция, а дуршлаг.
Все равно не вижу преимущества в данном контексте. Если мы хотим преимущества - нужно менять контекст (ФП тот же). Механизм исключений, при всей дороговизне, не мусорит мышления и не уводит в сторону от проблемы
а разве бы это помогло? несколько значений можно возвращать массивом, но и это не спасает от необходимости ЯВНОГО возвращения какбе return [a,b,c] из каждого уровня вызова, исключения позволяют уменьшить кол-во необходимых потуг
далее.
вы утверждаете, что "нахрен не надо" возвращаться на несколько уровней вверх. Получается, каждую нештатную ситуацию нужно обрабатывать именно там, где она возникла? Окей. Представьте, что уровней абстракции (и соотв. вложенности вызова) скажем, 10. Значит, я вынужден писать 10 обработчиков нештатных ситуаций, умножить на кол-во таких ситуаций, причем каждый обработчик должен позаботиться не только о своей собственной реакции, но и о том, как отчитаться вышестоящим. Пардон мсье, тогда любой код будет ГК, который трудно читать и сопровождать
По поводу паттерн-метчинга: "зачем делать сложным то, что проще простого"?
приведенный пример при всей простоте, уже сложнее для понимания, и уже логика из "что-то произошло, надо что-то делать" превращается в "ой, а результат хорош или нет?" Метчинг можно опустить, и продолжать с неверным результатом, тогда как исключение просто не даст лопухнуться
и еще по поводу крешинга. Знаете, уж лучше пусть крешится, чем втихомолку и с радостью выдаст неверный результат. Как сказал один мой друг, "лучше пусть громко перднет, что бы было видно откуда говно потекло, чем предательски набздит" :)
Говно такие абстракции, если нештатная ситуация одного слоя спокойно маппится на нештатную ситуацию другого слоя (без "rethrow"ов). Скорей всего, ООП головного мозга (какие-нибудь излюбленные стопицот фабрик для двепицот адаптеров). Если что-то такое нужно, то скорей всего код - говнокод (который валится, допустим, с обобщённым index out of range). вот любят кричать об инкапсуляции данных, а орошо было задуматься об инкапсуляции нештатных ситуаций. что-то подобное было бы полезно для дебуга разве что. что ж, для дебуга существуют куда более продвинутые технологии =\
> Метчинг можно опустить, и продолжать с неверным результатом, тогда как исключение просто не даст лопухнуться
> чем втихомолку и с радостью выдаст неверный результат
Как можно вообще получить результат, не пройдя метчинг? В таких типах результат получается только через метчинг. Если мы идём дальше, значит, мы не "распаковывали" результат, значит, он для текущего кода не нужен (не используется), значит, мы действительно можем продолжать дальше несмотря на ошибку (она для алгоритма нерелевантна).
это что еще за ересь? ООП гойловного мозга?
while (!TryDeleteFile(fielpath)){}
OutOfMemoryException не перехватывается.
еще кажите ArmageddonError x_x
Может просто пользователь большой файл попытался прочитать. Не повод крешить из-за этого борт программу автопилота самолёта. Это повод перехватить исключение и не пытатся читать дальше этот злощасный файл.
хотя единственное, что я знаю, так это то что память под new OutOfMemoryException() предаллоцируется при стартапе.