воскресенье, 27 октября 2013 г.

Механизм исключений C#.

Не преодолев желания налабать что нибудь в блог, решил написать не большую статейку об исключениях в C#. Я не буду писать много воды и перейду сразу к делу. Логически я разделю статью на две части, обработка и выброс исключений. Собственно больше о них сказать мне не чего.


Не много об исключениях

Для начала определимся что такое исключения, и для чего они вообще нам нужны. На сколько мне известно, в достаточно старых языках таких как Си, для контроля за работай программы использовали примитивные способы, на подобие возврата кода ошибки из функции. Удобного в этом мало, да и попросту забыть проконтролировать код ошибки очень просто из-за чего может начаться не контролируемое поведения программы и бессонная ночь отловки бага :) Конечно в Си с помощью макросов и прочего есть не что подобное. Но в более поздних языках это представлено более лаконично. И так, смоделируем ситуацию, допустим у нас есть некий метод  который принимает пользовательский объект для последующей работы с ним. А теперь представим что мы в эту функции передали выражение со значением null. Что будет? Если метод попробует начать работу с пустышкой, система выбросит NullReferenceException, но по хорошему метод перед работай проверить правильность всех аргументов и сам выбросить нужные исключения. Выброшенная ошибка будет распространятся вверх по цепочки вызовов пока её не отловят или она не достигнет верхней точки и программа не завершится аварийно. Думаю теперь понятно зачем нужен механизм исключений?

Отлов исключений  
Для отлова исключений в C# предусмотрено три ключевых слова, все они относятся к одной системе и работает на подобии оператора if-else. Это try\catch\finaly. В тело оператора try помещается код, за которым нужно будет так сказать проследить. Catch блок обработки определённого исключения а finaly блок который будет вызван после обработки исключения для того что бы освободить ресурсы. Но по меньше лирики перейдём к коду :


....
try
{
    SomeObject _so;
    _so.SomeMethod();
}
catch(NullReferenceExcepetion e)
{
     //Обработка NullReferenceExeption
}
catch(Exception e)
{
    //Обработка вообще всех исключений
}
finaly
{
   //Блок который вызовется после обработки исключения
   // (если исчклюения не было блок не вызовется)
}
....
    
Из комментариев думаю всё ясно. Так же если вызвать некий метод в блоке try, то обработка исключения выполнится. Так же я бы хотел рассказать не много об особенности работы оператора catch. Как вы уже заметили в скобках нужно указывать класс исключения, да-да, все исключения это просто классы унаследованные от класса Exception. И все кто понимает механизм полиморфизма и ковариантности, догадаются что если объявить блок catch отлавливающий исключения Exepetion то он будет срабатывать на ВСЕ ошибки. Но, если мы хотим знать что мы именно поймали, стоит сверху от отловки Exception ловить более узкоспециализированные исключения. Так же из всех операторов catch выбирается один, тот который первый подошел. Так что не стоит указывать выше всех отлов Excepetion так как всё что ниже просто будет игнорироваться.

"Выброс" своих исключений

Для инициирования своих исключений в C# предусмотрен оператор throw. Справа от оператора указывается выражения которое имеет тип производный от System.Exception.
Проще говоря нужно указать ссылку на класс который пронаследован от System.Exception. Так же в .Net Framework пред усмотрена куча классов для этих дел, но при желание вы можете создать свои.  В общем синтаксис примерно такой:

public class ThrowTest2

 {
   static int GetNumber(int index)
   {
      int[] nums = { 300, 600, 900 };
      if(index > nums.Length)
      {
          throw new IndexOutOfRangeException();
      }
     return nums[index];
   }
   static void Main()
   {
      int result = GetNumber(3);
   }
 

Резюмируя

В заключения хочу сказать что можно найти ещё кучу всего интересного об исключениях в C#, я же взялся рассказать базовые возможности. Свои замечания пишите в комментариях, постараюсь поправить статью если что не так :)

Комментариев нет:

Отправить комментарий