Обработка исключений в конструкторе класса

#c# #exception #exception-handling

#c# #исключение

Вопрос:

этот случай беспокоит меня с утра. Хорошая ли практика вызывать сборщик мусора в конструкторе класса, если он выдает исключение? У меня есть что-то вроде этого:

 public MyClass(/* some arguments */)
{
    try 
    {
      //do stuff...
    } catch(Exception e) {
      //do stuff, save logfile
      GC.SuppressFinalize(this);
    }

}
  

Причина, по которой я сделал это таким образом, заключается в том, что если он вызвал исключение (обычно NullReferenceException) Я хочу записать это в текстовый файл, и мне больше не нужен этот объект. но хорошая ли это практика? Если нет, то как это сделать правильно?

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

1. Есть ли у вашего класса вообще финализатор? Если нет, то вызов GC.SuppressFinalize совершенно бессмыслен.

Ответ №1:

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

Достаточно справедливо регистрировать исключение, но в настоящее время вы просто перехватываете его, что означает, что конструктор вернется без ошибок. Это почти наверняка не очень хорошая идея. Я предполагаю, что вы, вероятно, хотите:

 try 
{
  //do stuff...
} catch(Exception e) {
  //do stuff, save logfile
  throw;
}
  

Сказав это, я бы обычно попытался централизовать обработку исключений в любом случае, поместив ее далеко вверх по стеку вызовов и поместив туда все протоколирование. Было бы довольно редко помещать ведение журнала в конструктор, IMO.

Если вы не опубликовали this ссылку из своего конструктора, вновь созданный объект в любом случае будет иметь право на сборку мусора — вам не нужно делать ничего другого. Если вы реализуете IDisposable в своем классе, вы должны быть осторожны, чтобы освободить любые ресурсы, которые вам уже потребовались в конструкторе, но в большинстве случаев вы можете просто позволить исключению всплывать.