html текст
All interests
  • All interests
  • Design
  • Food
  • Gadgets
  • Humor
  • News
  • Photo
  • Travel
  • Video
Click to see the next recommended page
Like it
Don't like
Add to Favorites

Безопасная работа с исключениями в C# из песочницы

Структурные исключения — один из ключевых механизмов обработки ошибочных (в том числе и собственно исключительных) ситуаций. Ниже перечислены некоторые рекомендации по программированию, повышающие общее качество кода при работе с исключениями на C# и шире — платформе .NET.

Собственный класс. Выбрасывайте исключения на основе собственного класса, унаследованного от Exception, а не напрямую — на основе Exception, потому что это дает возможность определить свой собственный обработчик и отделить отслеживание и обработку исключений, выбрасываемых вашим кодом и кодом фреймворка .NET.

Отдельные поля. Создавайте отдельные поля в собственном классе для передачи существенной информации, вместо сериализации и десериализации данных в поле Message. Несмотря на то, что идея упаковки в Message сложных данных в виде строки типа JSON выглядит соблазнительно, это редко является удачной идеей, поскольку добавляет дополнительный расход ресурсов на кодирование, локализацию, декодирование.

Сообщения в лог. Записывайте в лог сообщение всякий раз, когда обработчик отлавливает Exception, с помощью вызова Exception.ToString(); это упростит отслеживание при отладке исключительных ситуаций.

Точный класс. Используйте наименее общий класс для отлавливания исключений, иначе это может приводить к труднообнаруживаемым ошибкам. Рассмотрим следующий код:

public class SimpleClass
{
    public static string DoSomething()
    {
        try
        {
            return SimpleLibrary.ReportStatus();
        }
        catch (Exception)
        {
            return "Failure 1";
        }
    }
}

public class SimpleLibrary
{
    public static string ReportStatus()
    {
        return String.Format("Success {0}.", 0);
    }
}


Если предположить, что код классов SimpleClass и SimpleLibrary находится в отдельных сборках, то в случае, когда обе сборки установлены правильно, код выполняется правильно, выводя сообщение «Success 0», а если сборка с классом SimpleLibrary не будет установлена, тогда код выполняется неправильно, выводя сообщение «Failure 1», несмотря на то, что никакой ошибки при исполнении функции ReportStatus не происходит. Проблема неочевидна из-за слишком обобщенной обработки ислючений. Код, форматирующий строку, выбрасывает исключения ArgumentNullException и FormatException, поэтому именно эти исключения и должны перехватываться в блоке catch, тогда станет очевидной причина ошибки — это исключение FileNotFoundException из-за отсутствия или неправильной установки сборки, содержащей класс SimpleLibrary.

Содержательная обработка. Всегда обрабатывайте исключения содержательно. Код вида

try
{
    DoSomething();
}
catch (SomeException)
{
    // TODO: ...
}


скрывает проблемы, не позволяя обнаружить их при отладке или выполнении.

Очистка в блоке finally. Удаляйте временные объекты в блоках finally. Рассмотрим операцию записи временного файла.

void WorkWithFile(string filename)
{
    try
    {
        using (StreamWriter sw = new StreamWriter(filename))
        {
            // TODO: Do something with temporary file
        }
        File.Delete(filename);
    }
    catch (Exception)
    {
        File.Delete(filename);
        throw;
    }
}


Как видно, код удаляющий файл, дублируется. Чтобы избежать повтора, нужно удалять временный файл из блока finally.

void WorkWithFile(string filename)
{
    try
    {
        using (StreamWriter sw = new StreamWriter(filename))
        {
            // TODO: Do something with temporary file
        }
    }
    finally
    {
        File.Delete(filename);
    }
}


Оператор using. Используйте оператор using. Он гарантирует вызов метода Dispose, даже если при вызове методов в объекте происходит исключение.

using (Font f = new Font("Times New Roman", 12.0f)) 
{
    byte charset = f.GdiCharSet;
}


Использование оператора using равноценно блоку try/finally, но более компактно и лаконично.

Font f = new Font("Times New Roman", 12.0f);
try
{
    byte charset = f.GdiCharSet;
}
finally
{
    if (f != null)
        ((IDisposable)f).Dispose();
}


Результат функции. Не используйте исключения для возврата результата работы функции и не используйте специальные коды возврата для обработки ошибок. Каждому — свое. Результат функции нужно возращать, а ошибки, которые нельзя пропускать, — обрабатывать с помощью исключений.

Отсутствие ресурса. Возвращайте null при отсутствии ресурса. Согласно соглашению, общепринятому для API .NET, функции не должны выкидывать исключения при отсутствии ресурса, они должны возвращать null. Так GetManifestResourceStream возращает null, если ресурсы не были указаны при компиляции или не видны для вызывающего кода.

Исходное место. Сохраняйте информацию об исходном месте возникновения исключения. Например,

try
{
    // Do something to throw exception
}
catch (Exception e)
{
    // Do something to handle exception

    throw e; // Wrong way!
    throw;   // Right way
}


В случае вызова throw e; информация о месте генерации исключения будет подменена новой строкой, поскольку создание нового исключения очистит стэк вызовов. Вместо этого нужно сделать вызов throw; который просто перевыбросит исходное исключение.

Добавление смысла. Меняйте исходное исключение, только чтобы добавить смысл, необходимый для пользователя. Например, в случае подключения к базе данных, пользователю может быть безразлична причина сбоя подключения (ошибка сокета), достаточно информации о самом сбое.

Сериализация. Делайте исключения, унаследованные от Exception, сериализуемыми с помощью [Serializable]. Это полезно, так как никогда заранее неизвестно, где будет получено исключение, например, в веб службе.

[Serializable]
public class SampleSerializableException : Exception
{
    public SampleSerializableException()
    {
    }

    public SampleSerializableException(string message) 
        : base(message)
    {
    }

    public SampleSerializableException(string message, Exception innerException) 
        : base(message, innerException)
    {
    }

    protected SampleSerializableException(SerializationInfo info, StreamingContext context) 
        : base(info, context)
    {
    }
}


Стандартные конструкторы. Реализуйте стандартные конструкторы, иначе правильная обработка исключений может быть затруднена. Так для исключения NewException эти конструкторы таковы:

  • public NewException();
  • public NewException(string);
  • public NewException(string, Exception);
  • protected or private NewException(SerializationInfo, StreamingContext);



По материалам MSDN, CodeProject, StackOverflow.
Читать дальше
Twitter
Одноклассники
Мой Мир

материал с habrahabr.ru

1

      Add

      You can create thematic collections and keep, for instance, all recipes in one place so you will never lose them.

      No images found
      Previous Next 0 / 0
      500
      • Advertisement
      • Animals
      • Architecture
      • Art
      • Auto
      • Aviation
      • Books
      • Cartoons
      • Celebrities
      • Children
      • Culture
      • Design
      • Economics
      • Education
      • Entertainment
      • Fashion
      • Fitness
      • Food
      • Gadgets
      • Games
      • Health
      • History
      • Hobby
      • Humor
      • Interior
      • Moto
      • Movies
      • Music
      • Nature
      • News
      • Photo
      • Pictures
      • Politics
      • Psychology
      • Science
      • Society
      • Sport
      • Technology
      • Travel
      • Video
      • Weapons
      • Web
      • Work
        Submit
        Valid formats are JPG, PNG, GIF.
        Not more than 5 Мb, please.
        30
        surfingbird.ru/site/
        RSS format guidelines
        500
        • Advertisement
        • Animals
        • Architecture
        • Art
        • Auto
        • Aviation
        • Books
        • Cartoons
        • Celebrities
        • Children
        • Culture
        • Design
        • Economics
        • Education
        • Entertainment
        • Fashion
        • Fitness
        • Food
        • Gadgets
        • Games
        • Health
        • History
        • Hobby
        • Humor
        • Interior
        • Moto
        • Movies
        • Music
        • Nature
        • News
        • Photo
        • Pictures
        • Politics
        • Psychology
        • Science
        • Society
        • Sport
        • Technology
        • Travel
        • Video
        • Weapons
        • Web
        • Work

          Submit

          Thank you! Wait for moderation.

          Тебе это не нравится?

          You can block the domain, tag, user or channel, and we'll stop recommend it to you. You can always unblock them in your settings.

          • habrahabr.ru
          • домен habrahabr.ru

          Get a link

          Спасибо, твоя жалоба принята.

          Log on to Surfingbird

          Recover
          Sign up

          or

          Welcome to Surfingbird.com!

          You'll find thousands of interesting pages, photos, and videos inside.
          Join!

          • Personal
            recommendations

          • Stash
            interesting and useful stuff

          • Anywhere,
            anytime

          Do we already know you? Login or restore the password.

          Close

          Add to collection

             

            Facebook

            Ваш профиль на рассмотрении, обновите страницу через несколько секунд

            Facebook

            К сожалению, вы не попадаете под условия акции