Он должен быть :
BinaryReader br = new BinaryReader(File.Open("C:\\florida.gdb\\a00000002.gdbtable",
FileMode.Open,
FileAccess.Read,
FileShare.Read | FileShare.Delete),
Encoding.Unicode);
Где Encoding
- System.Text.Encoding
.
По разным историческим причинам Microsoft / Windows относятся к UTF-16 (и, в частности, к малоинтенсивному варианту) как «Unicode», а не UTF-16.
, C++ основан на RAII.
, Если у Вас есть код, который мог бы перестать работать, возвратите или бросьте (то есть, самый нормальный код), затем необходимо перенести указатель в интеллектуальном указателе (предполагающий, что Вы имеете очень хороший причина не создать Ваш объект на стеке).
, Они являются подробными, и имеют тенденцию разрабатывать во что-то как:
if(doSomething())
{
if(doSomethingElse())
{
if(doSomethingElseAgain())
{
// etc.
}
else
{
// react to failure of doSomethingElseAgain
}
}
else
{
// react to failure of doSomethingElse
}
}
else
{
// react to failure of doSomething
}
В конце, Вы кодируете, набор idented инструкций (я видел этот вид кода в производственном коде).
Этот код мог быть переведен в:
try
{
doSomething() ;
doSomethingElse() ;
doSomethingElseAgain() ;
}
catch(const SomethingException & e)
{
// react to failure of doSomething
}
catch(const SomethingElseException & e)
{
// react to failure of doSomethingElse
}
catch(const SomethingElseAgainException & e)
{
// react to failure of doSomethingElseAgain
}
, Которые чисто разделяют код и ошибочную обработку, которая может быть хороша вещь.
Если не некоторое неясное предупреждение из одного компилятора (см. комментарий "phjr"), они могут легко быть проигнорированы.
С вышеупомянутыми примерами, примите, чем кто-то забывает обрабатывать его возможную ошибку (это происходит...). Ошибка проигнорирована при "возвращении" и возможном взрыве позже (т.е. Нулевой указатель). Той же проблемы не произойдет за исключением.
ошибка не будет проигнорирована. Иногда, Вы хотите, чтобы это не взорвалось, хотя... Таким образом, Вы должны, выбрал тщательно.
Скажем, у нас есть следующие функции:
, Каков тип возврата doTryToDoSomethingWithAllThisMess, если одна из его вызванных функций перестала работать?
, Операторы не могут возвратить код ошибки. Конструкторы C++ не могут, также.
заключение вышеупомянутой точки. Что, если я хочу записать:
CMyType o = add(a, multiply(b, c)) ;
я не могу, потому что возвращаемое значение уже используется (и иногда, оно не может быть изменено). Таким образом, возвращаемое значение становится первым параметром, отправленным как ссылка... Или нет.
, можно отправить различные классы за каждым видом исключения. Исключения Ressources (т.е. из памяти) должны быть легкими, но что-либо еще могло быть столь же тяжелым по мере необходимости (мне нравится Исключение Java, дающее мне целый стек).
Каждая выгода может затем быть специализирована.
Обычно, Вы не должны скрывать ошибку. Если Вы не повторно бросаете, по крайней мере, зарегистрируйте ошибку в файле, откройте messagebox, безотносительно...
проблема за исключением состоит в том, что злоупотребление их произведет код, полный попытки/выгод. Но проблема в другом месте: Кто пробует/ловит его код с помощью контейнера STL? Однако, те контейнеры могут отправить исключение.
, Конечно, в C++, никогда не позволяют исключению выйти из деструктора.
убедиться поймать их, прежде чем они произведут Ваш поток на его коленях или распространят в Вашем цикле сообщения Windows.
, Таким образом, я предполагаю, что решение состоит в том, чтобы бросить, когда что-то должно не , происходят. И когда что-то может произойти, затем используйте код возврата или параметр для включения пользователю для реакции на него.
Так, единственный вопрос, "что такое что-то, чего не должно происходить?"
Это зависит от контракта Вашей функции. Если функция принимает указатель, но указывает, что указатель должен быть непустым, то нормально выдавать исключение, когда пользователь отправляет Нулевого указателя (вопрос быть, в C++, когда не сделал функциональных ссылок использования автора вместо указателей, но...)
Иногда, Ваша проблема состоит в том, что Вы не хотите ошибок. Используя исключения или ошибку коды возврата прохладны, но... Вы хотите знать об этом.
В моем задании, мы используем своего рода "Утверждать". Это будет, в зависимости от значений конфигурационного файла, неважно, опции компиляции отладки/выпуска:
И в разработке и в тестировании, это позволяет пользователю точно определить проблему точно, когда это обнаруживается, и не после (когда некоторый код заботится о возвращаемом значении, или в выгоде).
легко добавить к унаследованному коду. Например:
void doSomething(CMyObject * p, int iRandomData)
{
// etc.
}
приводит своего рода код, подобный:
void doSomething(CMyObject * p, int iRandomData)
{
if(iRandomData < 32)
{
MY_RAISE_ERROR("Hey, iRandomData " << iRandomData << " is lesser than 32. Aborting processing") ;
return ;
}
if(p == NULL)
{
MY_RAISE_ERROR("Hey, p is NULL !\niRandomData is equal to " << iRandomData << ". Will throw.") ;
throw std::some_exception() ;
}
if(! p.is Ok())
{
MY_RAISE_ERROR("Hey, p is NOT Ok!\np is equal to " << p->toString() << ". Will try to continue anyway") ;
}
// etc.
}
(у меня есть подобные макросы, которые активны только на отладке).
Примечание, что на производстве, конфигурационный файл не существует, таким образом, клиент никогда не видит результат этого макроса... Но легко активировать его при необходимости.
при кодировании кодов возврата использования Вы готовитесь к отказу и надеетесь, что Ваша крепость тестов достаточно безопасна.
при кодировании исключения использования Вы знаете, что Ваш код может перестать работать, и обычно помещать противоогонь, ухватываются за выбранное стратегическое положение в Вашем коде. Но обычно, Ваш код больше о, "что он должен сделать" затем, "чего я боюсь, произойдет".
, Но когда Вы кодируете вообще, необходимо использовать лучший инструмент в Вашем распоряжении, и иногда, это, "Никогда не скрывают ошибку и показывают его как можно скорее". Макрос, который я говорил выше, следует за этой философией.
Я не нахожу, что коды возврата менее ужасны, чем исключения. За исключением Вы имеете try{} catch() {} finally {}
, где как с кодами возврата Вы имеете if(){}
. Я раньше боялся исключений по причинам, приведенным в сообщении; Вы не знаете, должен ли указатель быть очищен, что имеет Вас. Но я думаю, что у Вас есть те же проблемы когда дело доходит до кодов возврата. Вы не знаете состояние параметров, если Вы не знаете некоторые детали о рассматриваемой функции/методе.
Невнимательный, необходимо обработать ошибку, если это возможно. Можно позволить так легко исключению распространить к верхнему уровню, как игнорируют код возврата и позволяют программе segfault.
мне действительно нравится идея возвратить значение (перечисление?) для результатов и исключения для исключительного случая.
Я предпочитаю использовать исключения для обработки ошибок и возвращаемых значений (или параметры) как нормальный результат функции. Это дает легкую и последовательную схему обработки ошибок, и, если сделано правильно она делает для намного более чисто выглядящего кода.
Исключения не для обработки ошибок, IMO. Исключения - просто это; исключительные события, которые Вы не ожидали. Используйте с осторожностью, я говорю.
Коды ошибок могут быть в порядке, но возврат 404 или 200 из метода плох, IMO. Используйте перечисления (.NET) вместо этого, который делает код более читаемым и легче использовать для других разработчиков. Также Вы не должны поддерживать таблицу по числам и описаниям.
Также; try-catch-finally шаблон является антишаблоном в моей книге. Попытка наконец может быть хорошей, выгода попытки может также быть хорошей, но try-catch-finally никогда не хорош. попытка наконец часто может времена быть замененной оператором "использования" (шаблон IDispose), который является лучшим IMO. И выгода Попытки, где Вы на самом деле ловите исключение, Вы можете обработать, хорошо, или если Вы делаете это:
try{
db.UpdateAll(somevalue);
}
catch (Exception ex) {
logger.Exception(ex, "UpdateAll method failed");
throw;
}
Поэтому, пока Вы позволяете исключению продолжить пузыриться, оно в порядке. Другой пример - это:
try{
dbHasBeenUpdated = db.UpdateAll(somevalue); // true/false
}
catch (ConnectionException ex) {
logger.Exception(ex, "Connection failed");
dbHasBeenUpdated = false;
}
Здесь я на самом деле обрабатываю исключение; то, что я делаю за пределами выгоды попытки, когда метод обновления перестал работать, является другой историей, но я думаю, что мое мнение было высказано. :)
, Почему затем try-catch-finally антишаблон? Вот то, почему:
try{
db.UpdateAll(somevalue);
}
catch (Exception ex) {
logger.Exception(ex, "UpdateAll method failed");
throw;
}
finally {
db.Close();
}
, Что происходит, если объект дб был уже закрыт? Новое исключение выдается, и оно должно быть обработано! Это лучше:
try{
using(IDatabase db = DatabaseFactory.CreateDatabase()) {
db.UpdateAll(somevalue);
}
}
catch (Exception ex) {
logger.Exception(ex, "UpdateAll method failed");
throw;
}
Или, если объект дб не реализует IDisposable, делают это:
try{
try {
IDatabase db = DatabaseFactory.CreateDatabase();
db.UpdateAll(somevalue);
}
finally{
db.Close();
}
}
catch (DatabaseAlreadyClosedException dbClosedEx) {
logger.Exception(dbClosedEx, "Database connection was closed already.");
}
catch (Exception ex) {
logger.Exception(ex, "UpdateAll method failed");
throw;
}
Это составляет мои 2 цента так или иначе! :)
Я только использую исключения, никакие коды возврата. Я говорю о Java здесь.
общее правило, за которым я следую, состоит в том, если у меня есть метод, названный doFoo()
затем из этого следует, что, если оно "не делает нечто", на самом деле, затем, что-то исключительное произошло, и Исключение должно быть выдано.
Мое общее правило в исключении по сравнению с аргументом кода возврата:
С любым достойным компилятором или средой выполнения исключения не подвергаются значительному штрафу. Это более или менее похоже на Оператор перехода, который переходит к обработчику исключений. Кроме того, ловление исключения средой выполнения (как JVM) помогает изоляции и исправлению намного легче ошибки. Я возьму NullPointerException в Java по segfault в C любой день.
У меня есть простой подшипник:
1) коды возврата Использования для вещей Вы ожидаете, что Ваша непосредственная вызывающая сторона будет реагировать на.
2) исключения Использования для ошибок, которые более широки в объеме и могут разумный, как ожидать, будут обработаны чем-то много уровней выше вызывающей стороны так, чтобы осведомленность об ошибке не проникала через многие слои, делая код более сложным.
В Java я только когда-либо использовал неконтролируемые исключения, контролируемые исключительные ситуации заканчивают тем просто, что были другой формой кода возврата и по моему опыту дуальности того, что могло бы быть "возвращено" вызовом метода, обычно было больше помехи, чем справка.
self.tableView
) для отображения результатов поиска?
– thesummersign
2 May 2012 в 16:48
Большой совет, который я получил от Прагматически настроенный Программист , был чем-то вроде "Вашей программы, должен смочь выполнить всю ее основную функциональность, не используя исключения вообще".
registerClass: forCellReuseIdentifier:
, если Ваши ячейки определяются в коде, а не Интерфейсном Разработчике.
– Nick
2 November 2013 в 18:56
Одни из больших различий - то, что исключения вынуждают Вас обработать ошибку, тогда как ошибочные коды возврата могут пойти неконтролируемые.
Ошибочные коды возврата, если используется в большой степени, могут также вызвать очень ужасный код с большим количеством из если тесты, подобные этой форме:
if(function(call) != ERROR_CODE) {
do_right_thing();
}
else {
handle_error();
}
Лично я предпочитаю использовать исключения для ошибок, которые ДОЛЖНЫ или ДОЛЖНЫ реагироваться кодом вызова и только использовать коды ошибок для "ожидаемых сбоев", где возврат чего-то на самом деле допустим и возможен.
Одна вещь, которой я боюсь об исключениях, состоит в том, что выдача исключения завинтит поток кода. Например, если Вы делаете
void foo()
{
MyPointer* p = NULL;
try{
p = new PointedStuff();
//I'm a module user and I'm doing stuff that might throw or not
}
catch(...)
{
//should I delete the pointer?
}
}
Или еще хуже, что, если я удалил что-то, которое я не должен иметь, но был брошен для ловли, прежде чем я сделал остальную часть очистки. Бросок поместил большой вес на бедном пользователе, по моему скромному мнению.
Я полагаю, что коды возврата добавляют к шуму кода. Например, я всегда ненавидел вид кода COM/ATL из-за кодов возврата. Должна была быть проверка HRESULT на каждую строку кода. Я полагаю, что ошибочный код возврата является одним из плохих решений, принятых архитекторами COM. Это мешает делать, логическая группировка кода, таким образом для кодирования обзора становится трудной.
я не уверен в сравнении производительности, когда существует явная проверка на код возврата каждая строка.
В Java я использую (в следующем порядке):
Дизайн контракта (гарантирующий предварительные условия встречены прежде, чем попробовать что-либо , который мог бы перестать работать). Это ловит большинство вещей, и я возвращаю код ошибки для этого.
коды ошибок Возврата при обработке работы (и выполнении отката в случае необходимости).
Исключения, но они используются только для неожиданных вещей.
Мое предпочтение (в C++ и Python) состоит в том, чтобы использовать исключения. Обеспеченные языком средства делают это четко определенным процессом, чтобы и повысить, поймать и (при необходимости) повторно выдать исключения, делая модель легкой видеть и использовать. Концептуально, это более чисто, чем коды возврата, в которых определенные исключения могут быть определены их именами и иметь дополнительную информацию, сопровождающую их. С кодом возврата Вы ограничены просто ошибочным значением (если Вы не хотите определить объект ReturnStatus или что-то).
, Если код Вы не пишете, строго ограничено во времени, издержки, связанные с раскручиванием стека, не являются достаточно значительными для волнения о.
Я записал сообщение в блоге об этом только что.
производительность наверху выдачи исключения не должна играть роль в Вашем решении. Если Вы делаете его правильно, в конце концов, исключение исключительно .
Я использую обоих на самом деле.
я использую коды возврата, если это - известная, возможная ошибка. Если это - сценарий, который я знаю, может, и происходить, то существует код, который передают обратно.
Исключения используются только для вещей, которые я НЕ ожидаю.
Исключения должны только быть возвращены, где что-то происходит, который Вы не ожидали.
другая точка исключений, исторически, то, что коды возврата являются по сути собственными, иногда 0 мог быть возвращен из функции C для указания на успех, иногда-1, или любого из них для сбоя с 1 для успеха. Даже когда они перечисляются, перечисления могут быть неоднозначными.
Исключения могут также предоставить намного больше информации и конкретно обстоятельно объяснить хорошо, 'Что-то Пошло не так, как надо, вот то, что, отслеживание стека и некоторая информация о поддержке для контекста'
Однако хорошо перечислимый код возврата может быть полезен для известного набора результатов, простые 'наймы n результаты функции, и это просто выполнило этот путь'
Мне не нравятся коды возврата, потому что они заставляют следующий шаблон распространиться всюду по Вашему коду
CRetType obReturn = CODE_SUCCESS;
obReturn = CallMyFunctionWhichReturnsCodes();
if (obReturn == CODE_BLOW_UP)
{
// bail out
goto FunctionExit;
}
Скоро вызов метода, состоящий из 4 чрезмерных увеличений размера вызовов функции с 12 строками обработки ошибок.. Некоторых из которых никогда не будет происходить. Если и переключатель случаи имеются в большом количестве.
Исключения являются более чистыми при использовании их хорошо... для передачи сигналов об исключительных событиях.. после которого не может продолжиться путь выполнения. Они являются часто более описательными и информационными, чем коды ошибок.
, Если у Вас есть несколько состояний после вызова метода, который должен быть обработан по-другому (и не исключительные случаи), используйте коды ошибок или параметрические усилители. Хотя Personaly я нашел, что это редко..
я искал немного о контрдоводе 'потери производительности'.. больше в C++ / мир COM, но на более новых языках, я думаю, что различие не так очень. В любом случае, когда что-то аварийно завершается, проблемы производительности понижены к неосновному :)
Я использую Исключения в Python и при Исключительных, и при неисключительных обстоятельствах.
часто хорошо смочь использовать Исключение, чтобы указать, что "запрос не мог быть выполнен", в противоположность возвращению Ошибочного значения. Это означает, что Вы,/always/знают, что возвращаемое значение является правильным типом, вместо arbitarily Ни одного или NotFoundSingleton или чего-то. Вот хороший пример того, где я предпочитаю использовать обработчик исключений вместо условного выражения на возвращаемом значении.
try:
dataobj = datastore.fetch(obj_id)
except LookupError:
# could not find object, create it.
dataobj = datastore.create(....)
побочный эффект состоит в том, что, когда datastore.fetch (obj_id) выполняется, Вы никогда не должны проверять, не является ли его возвращаемое значение Ни одним, Вы получаете ту ошибку сразу бесплатно. Это в противоречии с аргументом, "Ваша программа должна смочь выполнить всю свою основную функциональность, не используя исключения вообще".
Вот другой пример того, где исключения 'исключительно' полезны для написания кода для контакта с файловой системой, которая не подвергается условиям состязания.
# wrong way:
if os.path.exists(directory_to_remove):
# race condition is here.
os.path.rmdir(directory_to_remove)
# right way:
try:
os.path.rmdir(directory_to_remove)
except OSError:
# directory didn't exist, good.
pass
Один системный вызов вместо два, никакое состояние состязания. Это - плохой пример, потому что, очевидно, это перестанет работать с OSError при большем количестве обстоятельств, чем каталог не существует, но это - 'достаточно хорошее' решение для многих плотно управляемых ситуаций.
Существует, многие рассуждают для предпочтения Исключений по коду возврата:
Согласно Главе 7 назвал "Исключения" в Руководство по проектированию Платформы: Конвенции, Идиомы и Шаблоны для Допускающих повторное использование Библиотек.NET , многочисленные объяснения даны для того, почему использование исключений по возвращаемым значениям необходимо для платформ OO, таких как C#.
, Возможно, это - наиболее неопровержимый довод (страница 179):
"Исключения интегрируются хорошо с объектно-ориентированными языками. Объектно-ориентированные языки имеют тенденцию налагать ограничения на членские подписи, которые не наложены функциями на языках неOO. , Например, в случае конструкторов, перегрузок оператора и свойств, у разработчика нет выбора в возвращаемом значении. поэтому не возможно стандартизировать на основанном на возвращаемом значении сообщении об ошибке для объектно-ориентированных платформ. метод сообщения об ошибке, такой как исключения, который является вне полосы сигнатуры метода, является единственной опцией. "