Конечно, "это зависит" от ситуации. Иногда DataSets или DataTables больше подходят, как то, если это действительно - довольно легкая бизнес-логика, плоская иерархия объектов/записей, или показывающий некоторые возможности управления версиями.
наборы Пользовательского объекта сияют, когда Вы хотите реализовать глубокая иерархия/график из объектов, которые не могут быть эффективно представлены в плоских 2D таблицах. То, что можно продемонстрировать, является большим графиком объектов и того, чтобы заставлять определенные события распространить вниз корректные ответвления, не вызывая несоответствующие объекты в других ответвлениях. Тем путем не необходимо циклично выполнить или Выбрать через каждый DataTable только для получения дочерних записей.
, Например, в проекте я связался два и половина несколько лет назад, был модуль UI, который, как предполагается, отображает вопросы и средства управления ответом в единственном WinForms DataGrid (чтобы быть более конкретным, это был UltraGrid Infragistics). Некоторые более хитрые требования
исходная реализация была записана полностью в DataSets, DataTables и массивах. Объем цикличного выполнения через сотни строк для нескольких таблиц чисто изогнул ум. Не помогло, что программист произошел из среды C++, пытающейся к касательно все (привет, объекты, живущие в использовании "кучи" ссылочные переменные , как указатели!). Никто, даже первоначально программист, не мог объяснить, почему код делает то, что он делает. Я въехал в сцену больше чем шесть месяцев после этого и она все еще лавинно рассылалась ошибками. Неудивительный разработчик второго поколения я вступил во владение от решительного для выхода.
Два месяца связи для фиксации хаотической путаницы я взял его на меня для перепроектирования всего модуля в объектно-ориентированный график для решения этой проблемы . yeap, вместе с абстрактными классами (для рендеринга различного управления ответом на ячейке сетки в зависимости от типа вопроса), делегаты и обработка событий. Конечным результатом был 2D dataGrid binded к глубокой иерархии вопросов, естественно отсортированных согласно родительско-дочернему расположению. Когда ответ родительского вопроса изменился, он сгенерировал бы событие к вопросам о детях, и они автоматически покажут/скроют свои строки в сетке согласно ответу родителя. Только вопрос возражает вниз, что путь был затронут. Скорость отклика UI этого решения по сравнению со старым методом была порядками величины.
Это повторно вызывает точное исключение:
catch (Exception)
{
throw;
}
В то время как это повторно вызывает исключение без исходной трассировки стека:
catch (Exception e)
{
throw e;
}
Часто для есть веская причина throw;
, поскольку вы можете регистрировать исключение или выполнять другие действия до повторного создания исключения. Я не знаю каких-либо веских причин для throw e;
, поскольку вы уничтожите ценную информацию трассировки стека.
Я использую эту технику, чтобы поставить точку останова на переход при отладке. Иногда удаляю после того, как закончу ...
Основное отличие состоит в том, что трассировка стека исключения будет изменена, чтобы показать, что оно возникло из местоположения try-catch в первом примере.
Второй пример поддерживает трассировка стека.
1 - Я вообще не вижу преимуществ. Если вы не обрабатываете исключение, не включайте try / catch. Другая проблема с этим примером заключается в том, что вы генерируете не фактическое исключение, а новое.
2 - да - но если это не находится в большом цикле повторяющегося кода, вы, вероятно, не заметите разницы .
3 - Да. В первом примере вы возитесь со своим стеком вызовов. В этом примере стек остается нетронутым за счет всплытия исключения вместо создания нового.
Если вы действительно ничего не делаете, я обнаружил только одно преимущество: вы можете установить точку останова на строка throw
. Это делает его очень специфичным (вместо того, чтобы просто ломаться всякий раз, когда возникает этот тип исключения).
Я бы сделал это только во время отладки, а затем вернул код обратно.
Вот так, нет. Однако вы можете захотеть сделать следующее:
catch (Exception ex)
{
LogException(ex);
throw;
}
Где LogException () - это настраиваемый класс, который, например, регистрирует исключение или отправляет по электронной почте предупреждение или что-то в этом роде.
Конечно.
Чаще всего вы хотите зарегистрировать исключение перед его выдачей и, возможно, записать некоторые значения переменных из метода.
Однако просто поймать его, чтобы выбросить, не мало что даст.
Я думаю, что суть в том, чтобы генерировать только один ТИП исключения. IMHO
, это довольно плохой анти-шаблон, например
try
{
throw XYZ();
}
catch(Exception e)
{
throw e;
}
Часто это удобно для регистрации. Кроме того, если вы оставите аргумент в повторном вызове, это не изменит трассировку стека e.
Иногда вы хотите разрешить определенные типы, например, здесь специальная обработка для всего, кроме FooException:
try
{
// ...
}
catch (FooException)
{
throw;
}
catch (Exception ex)
{
// handle differently, like wrap with a FooException
throw new FooException("I pitty the Foo.", ex);
}
Я написал быстрый тест, чтобы показать различия. Вот тестовый код:
try
{
var broken = int.Parse("null");
}
catch (Exception ex1)
{
System.Diagnostics.Trace.WriteLine(ex1.ToString());
}
try
{
try
{
var broken = int.Parse("null");
}
catch (Exception)
{
throw;
}
}
catch (Exception ex2)
{
System.Diagnostics.Trace.WriteLine(ex2.ToString());
}
try
{
try
{
var broken = int.Parse("null");
}
catch (Exception ex3)
{
throw ex3;
}
}
catch (Exception ex4)
{
System.Diagnostics.Trace.WriteLine(ex4.ToString());
}
Запустив это, я получаю следующий результат:
A first chance exception of type 'System.FormatException' occurred in mscorlib.dll
System.FormatException: Input string was not in a correct format.
at System.Number.StringToNumber(String str, NumberStyles options, NumberBuffer& number, NumberFormatInfo info, Boolean parseDecimal)
at System.Number.ParseInt32(String s, NumberStyles style, NumberFormatInfo info)
at System.Int32.Parse(String s)
at QuickTests.Program.Main(String[] args) in C:\Projects\Test\QuickTests\Program.cs:line 18
A first chance exception of type 'System.FormatException' occurred in mscorlib.dll
A first chance exception of type 'System.FormatException' occurred in QuickTests.exe
System.FormatException: Input string was not in a correct format.
at System.Number.StringToNumber(String str, NumberStyles options, NumberBuffer& number, NumberFormatInfo info, Boolean parseDecimal)
at System.Number.ParseInt32(String s, NumberStyles style, NumberFormatInfo info)
at System.Int32.Parse(String s)
at QuickTests.Program.Main(String[] args) in C:\Projects\Test\QuickTests\Program.cs:line 33
A first chance exception of type 'System.FormatException' occurred in mscorlib.dll
A first chance exception of type 'System.FormatException' occurred in QuickTests.exe
System.FormatException: Input string was not in a correct format.
at QuickTests.Program.Main(String[] args) in C:\Projects\Test\QuickTests\Program.cs:line 49
Вы заметите, что первые два исключения работают одинаково. Итак, «бросить»; ничего не меняет до исключения, которое перемещается вверх по стеку. Однако "выбросить ex3;" заставляет указанное исключение отличаться, изменяя трассировку стека для исключения.
Вообще говоря, нет. Все, что будет делать этот шаблон, - это сбросить трассировку стека до точки нового броска. Это только усложнит разработчикам поиск источника проблемы
Вообще? Возможно. Замедлить его какой-нибудь измеримой разницей? Нет.
Да, этот перехват практически полностью избыточен. Он повторно вызовет исключение, которое сохранит исходную трассировку стека и не окажет заметного влияния на ваше приложение.
Нет, если вы ничего не делаете в ловушке ... Но это часто используется для других вещи в перехвате, такие как ведение журнала или другие виды обработки исключений, перед его повторным вызовом.