При использовании кодов возврата вызываемый метод возвращает код ошибки, и причина ошибки обрабатывается вызывающим методом. Поскольку обработка происходит вне области видимости вызываемого метода, нет гарантии, что вызывающий метод проверит возвращенный код ошибки. Скажем, вы пишете класс
CommaDelimitedFile,
реализующий чтение и запись стандартных файлов с разделителями. Ваш класс, в частности, должен иметь методы для открытия и чтения данных из файла. При старом подходе уведомления об ошибках эти методы должны возвращать переменные, которые должны проверяться вызывающим методом, чтобы определить, успешно ли выполнился вызов. Если пользователь вашего класса вызвал метод
CommaDelimitedFile.Open,
а затем пытается вызвать метод
CommaDelimitedFile.Read,
не проверив, успешно ли завершился
Open,
это может привести к очень неприглядным результатам (и скорей всего это случится, когда вы демонстрируете свою программу очень важному заказчику). Но если метод
Open
этого класса передаст исключение, вызывающий метод будет поставлен перед фактом, что в методе
Open
произошел сбой. Дело в том, что при каждой передаче исключения управление передается наверх, пока исключение не улавливается. Такой код может выглядеть следующим образом:
using System;
class ThrowException2App
{
class CommaOelimitedFile
{
protected string fileName;
public void Open(strlng fileName)
{
this.fileName = fileName;
// Пытаемся открыть файл
// и передаем исключение при возникновении ошибки, throw new Exception("Открыть файл не удалось"); }
public bool Read(string record) {
// Код для чтения файла, return false; // EOF } }
public static void Maln() {
try
{
Console.WriteLlne("Пытаемся открыть файл");
CommaDelimltedFlle file = new CommaDelimltedFileO; file.Open("c:\\test.csv");
string record = "";
Console.WrlteLine("Читаем файл");
while (file.Read(record) == true) {
Console.Writeline(record); }
Console.WriteLine("Чтение файла закончено"); }
catch (Exception e) {
Console.WrlteLine(e.Message); } } }
Здесь, если метод
CommaDelimitedFile.Open
или
CommaDelimited-File.Read
передаст исключение, вызывающий метод вынужден будет на него прореагировать. Если ни вызывающий, ни другие методы в текущем кодовом сегменте не уловят исключение данного типа, приложение прервется. Заметьте: обращение к методу
Open
находится в блоке и, следовательно, попытка недопустимого чтения (если
Open
передаст исключение) производиться не будет. Это объясняется тем, что управление будет передано из блока
try,
в котором производится обращение к
Open,
к первой строке блока
catch.
Таким образом, одно из самых больших преимуществ обработки исключений над кодами возврата в том, что исключения гораздо труднее проигнорировать.