2013-08-20 1 views
2

Ниже мой код в C#:Бросив исключение после изменения его словарь

catch(Exception ex) 
{ 
    ex.Data.Add("VarName", "object"); 
    throw; 
} 

Вопрос: делать выше, я собираюсь потерять запись я добавляю к словарю данных? -> как мне кажется, я перетаскиваю исключение, пойманное в выводе catch, и у него еще нет добавленной записи словаря со следующей строки.

Если выше код вместо этого:

catch(Exception ex) 
{ 
    ex.Data.Add("VarName", "object"); 
    throw ex; 
} 
  • , но в этом случае, я не хочу, чтобы сбросить трассировки стека.

Искал это по сети и на SO, но не повезло.

TIA!

+1

Если вы хотите добавить некоторые данные в исключение, то оберните исключение в более конкретное исключение с данными и выбросите это конкретное исключение –

+0

Пробовали ли вы это; не требуется больше нескольких минут, чтобы написать образец кода, который тестирует? –

+0

просто попробовал - ответ Барта верный. Мой начальный код работает отлично. – coder0h1t

ответ

3

Ваш исходный код должен работать нормально. Вы не должны терять словарь.

[EDIT]: Разработка.

Давайте рассмотрим следующий пример кода:

using System; 
class Program 
{ 
    static void Main() 
    { 
     Change(); 
     Replace(); 
     Inner(); 
    } 

    static void Change() 
    { 
     try { 
      try { 
       throw new Exception("This is a message"); 
      } catch (Exception e) { 
       e.Data.Add("foo", "bar"); 
       throw; 
      } 
     } catch (Exception e) { 
      System.Diagnostics.Trace.WriteLine(e.Message); 
      System.Diagnostics.Trace.WriteLine(e.Data["foo"]); 
     } 
    } 

    static void Replace() 
    { 
     try { 
      try { 
       throw new Exception("This is a message"); 
      } catch (Exception e) { 
       e = new Exception("Different message", e); 
       e.Data.Add("foo", "bar"); 
       throw; 
      } 
     } catch (Exception e) { 
      System.Diagnostics.Trace.WriteLine(e.Message); 
      System.Diagnostics.Trace.WriteLine(e.Data["foo"]); 
     } 
    } 

    static void Inner() 
    { 
     try { 
      try { 
       throw new Exception("This is a message"); 
      } catch (Exception e) { 
       e.Data.Add("foo1", "bar1"); 
       e = new Exception("Different message", e); 
       e.Data.Add("foo2", "bar2"); 
       throw e; 
      } 
     } catch (Exception e) { 
      System.Diagnostics.Trace.WriteLine(e.Message); 
      System.Diagnostics.Trace.WriteLine(e.Data["foo2"]); 
      System.Diagnostics.Trace.WriteLine(e.InnerException.Message); 
      System.Diagnostics.Trace.WriteLine(e.InnerException.Data["foo1"]); 
     } 
    } 
} 

Когда бросали Exception, что на самом деле бросили это ссылка на объект Exception. Эта ссылка - это то, что поймали и возродили. Модификация базового объекта в порядке. Это то, что делает ваш исходный код, и что делает метод Change в моем примере.

В методе Replace мы модифицируем не объект, а ссылку. Мы указываем на новый объект Exception с другим сообщением, и, чтобы добавить его, добавим некоторые данные. Однако все эти вещи потеряны, потому что throw без аргументов возвращает исходную ссылку.

Если возникнет необходимость использовать второй случай, вы можете отслеживать трассировку вашего стека, включив исходное исключение как InnerException, как я это сделал в методе Inner.

+0

Я бросил этот ответ на работе. Добавлено объяснение. –