Я передал бы ArraySegment
в этом случае.
Вы изменили бы Ваш Parse
метод к этому:
// Changed TCPHeader to TcpHeader to adhere to public naming conventions.
TcpHeader Parse(ArraySegment buffer)
И затем Вы изменили бы вызов на это:
// Create the array segment.
ArraySegment seg = new ArraySegment(packet, 20, 20);
// Call parse.
TcpHeader header = Parse(seg);
Используя эти ArraySegment
не скопирует массив, и он сделает проверку границ Вас в конструкторе (так, чтобы Вы не указывали неправильные границы). Затем Вы изменяете Ваш Parse
метод для работы с границами, указанными в сегменте, и необходимо быть в порядке.
можно даже создать перегрузку удобства, которая примет полный массив байтов:
// Accepts full array.
TcpHeader Parse(byte[] buffer)
{
// Call the overload.
return Parse(new ArraySegment(buffer));
}
// Changed TCPHeader to TcpHeader to adhere to public naming conventions.
TcpHeader Parse(ArraySegment buffer)
Мой девиз - обрабатывать то, что вы можете (или нужно), и позволять любым другим исключениям всплывать и перехватывать их в событии UnhandledException.
Вы правы, но блок finally всегда вызывается (даже в случае возникновения исключения в секции try) перед выходом из метода. Так что, хотите ли вы перехватить исключение в методе out или нет, полностью зависит от вас ...
По вопросу №2: Автор имел в виду «Исключения поврежденного государства». Они будут представлены в .NET 4.0 (команда CLR объявила об этом на PDC 2008 в в этом докладе).
Исключения поврежденного состояния не могут быть перехвачены обычным блоком перехвата. Примеры: нарушение прав доступа, недействительная память.
Но вы могли бы перехватить эти исключения:
Для этого вы должны поместить атрибут [HandleProcessCorruptedStateException] в метод, где вы хотите перехватить CorruptedStateException.
Чтобы узнать больше об этих исключениях см. эту статью MSDN.
Как правило, вы не должны перехватывать исключения, если:
У вас нет особого исключения, которое вы можете обработать и с которым что-то сделаете. Однако в этом случае вы всегда должны проверять, не следует ли вам в первую очередь пытаться учитывать и избегать исключения.
Вы находитесь на верхнем уровне приложения (например, пользовательского интерфейса) и не хотите, чтобы поведение по умолчанию, которое будет представлено пользователю. Например, вам может потребоваться диалоговое окно с сообщением об ошибке в стиле «пришлите нам свои журналы».
Вы повторно генерируете исключение после того, как каким-то образом с ним справитесь, например, если вы откатываете транзакцию БД.
Ваш finally
блоки всегда выполняются. Ваш пример кода верен - метод низкого уровня должен иметь только try
и наконец
. Например, неуправляемый вызов может знать, что ему нужно избавиться от неуправляемого ресурса, но это не будет доступно для вызывающих его методов .Net. Этот вызов должен избавить от неуправляемого ресурса в его блоке finally
, а вызов управляемых методов может обрабатывать исключения или просто передавать их.
Если в исключении есть что-то, что вам нужно обработать, вы должны повторно вызовите исключение, например:
try {
conn.BeginTransaction();
//do stuff
conn.CommitTransaction();
}
catch (Exception) {
conn.RollbackTransaction(); //required action on any exception
throw; //re-throw, don't wrap a new ex to keep the stack trace
}
finally {
conn.Dispose(); //always dispose of the resource
}
Просто к вашему третьему вопросу:
Если у вас есть
nastyLowLevel() {
doSomethingWhichMayCorruptSomethingAndThrowsException();
}
MyEvilCatcher() {
try {
nastyLowLevel();
} catch (Exception e) {
MyExceptionHandler(e);
}
}
WiseCatcher() {
try {
MyEvilCatcher();
} catch (LowLevelException e) {
DoSomethingWiseSoFinnalyDontRuinAnything();
} finally {
DoSomethingWhichAssumesLowLevelWentOk();
}
}
, я думаю, что ответ, о котором вы спрашивали, просто означал, что некоторые методы низкого уровня могут использовать исключения для информирования некоторого внешнего метода, который особенно заботится должен быть взят. Если вы забудете об этих исключениях в своем универсальном обработчике и не вызовете их повторно, что-то может пойти не так.
Как правило, я предпочитаю тщательно продумать, какие исключения могут быть сгенерированы, и явно их перехватить. Я использую «общий обработчик» только на самом внешнем уровне в производственных средах, чтобы регистрировать неожиданные исключения и представлять их заказчику в хорошо отформатированном виде (включая подсказку для отправки нам файла журнала).
Я думаю, что приведенный ответ неверен (или, может быть, имелся в виду 2.0 вместо 4.0)? Мне это кажется фальшивкой.