2015-09-16 2 views
2

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

Я читал о разворачивающемся стеке, но все же у меня нет сценария, где мы не можем справиться с этим по-старому. Объясните, мне 5, пожалуйста.

try 
{ 
    Foo.DoSomethingThatMightFail(null); 
} 
catch (MyException ex) when (ex.Code == 42) 
{ 
    Console.WriteLine("Error 42 occurred"); 
} 

против

try 
{ 
    Foo.DoSomethingThatMightFail(null); 
} 
catch (MyException ex) 
{ 
    if (ex.Code == 42) 
     Console.WriteLine("Error 42 occurred"); 
    else 
     throw; 
} 

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

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

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

class specialException : Exception 
{ 
    public DateTime sentDateTime { get; } = DateTime.Now; 
    public int code { get; } = 0; 
    public string emailsToAlert { get; } = "[email protected]"; 
} 

затем:

try 
{ 
    throw new specialException(); 
    //throw new Exception("Weird exception"); 
    //int a = Int32.Parse("fail"); 
} 
catch (specialException e) when(e.code == 0) 
     { 
      WriteLine("E.code 0"); 
      throw; 
      //throw e; 
     } 
catch (FormatException e) 
     { 
      if (cond1) 
      { 
       WriteLine("cond1 " + e.GetBaseException().Message+" - "+e.StackTrace); 
       throw; 
      } 
      throw; 
     } 
catch (Exception e) //when (cond2) 
     { 
      Console.WriteLine("cond2! " + e.Message); 
      throw; 
     } 
+0

Где вы находите, что цитата «Фильтры исключений предпочтительнее ...»? – mason

+0

В вопросе, который они сказали, я дублировал. (http://stackoverflow.com/questions/27082069/what-benefit-does-the-new-exception-filter-feature-provide) –

+0

У Томаса Левеска была хорошая запись [здесь] (http: //www.thomaslevesque. ком/2015/06/21/исключение-фильтры-в-с-6 /). Вы читали? Он делает несколько хороших моментов, потому что я использую стек и stacktrace взаимозаменяемо в моей голове, и его сообщение очистило это для меня. – mason

ответ

1

Я не понимаю ответа Пауло. Он может быть прав, или он может и не быть.

Я определенно не согласен с ответом Александра. Это не просто синтаксический сахар. Чистый синтаксический сахар означает, что это просто более простой способ написать что-то, и что исполнение будет неизменным.

Однако в этой ситуации это не так. Поскольку Thomas Levesque points out in his blog, фильтры исключений не разматывают стек. Поэтому при отладке программы, если у вас есть исключение, созданное в блоке try, с фильтрами исключений вы сможете увидеть, какое состояние значений находится в блоке try. Если вы не использовали фильтры исключений, ваш код войдет в блок catch, и вы потеряете информацию о состоянии переменных в блоке try.

Обратите внимание, что я не говорю о stacktrace (это другая, но связанная с ней концепция). Столбец остался бы неизменным, если бы вы явно не сбросили исключение, как в throw exception; в блоке catch, где exception является исключенным пойманным.

Так что в некоторых случаях вы можете думать о нем как о чем-то, что может или не может сделать ваш код более чистым (в зависимости от вашего мнения о синтаксисе), он делает изменить поведение.

-1

UPD: Как указано в ответе Пауло Morgado, функция была в CLR в течение некоторого времени, и C# 6.0 только добавлена ​​поддержка синтаксиса для него. Мое понимание этого, однако, остается синтаксическим сахаром, например. синтаксис, который позволяет мне фильтровать исключения лучше, чем раньше, независимо от того, как работает предыдущий «простой» метод под капотом.

=====

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

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

try 
{ 
    try 
    { 
     throw new ArgumentException() { Source = "One" }; 
     throw new ArgumentException() { Source = "Two" }; 
     throw new ArgumentException() { Source = "Three" }; 
    } 
    catch (ArgumentException ex) when (ex.Source.StartsWith("One")) // local 
    { 
     Console.WriteLine("This error is handled locally"); 
    } 
    catch (ArgumentException ex) when (ex.Source.StartsWith("Two")) // separate 
    { 
     Console.WriteLine("This error is handled locally"); 
    } 

} 
catch (ArgumentException ex) // global all-catcher 
{ 
    Console.WriteLine("This error is handled globally"); 
} 

Здесь вы можете ясно видеть, что первое и второе исключение обрабатываются в соответствующих блоках, которые разделены с помощью when гарантию, в то время как один глобальный всеохватывающий блок будет ловить только третье исключение. Синтаксис яснее, что ловить все исключения, в каждом блоке, что-то вроде:

catch (ArgumentException ex) // local 
    { 
        if (ex.Source.StartsWith("One")) 
        { 
         Console.WriteLine("This error is handled locally"); 
        } 
        else 
        { 
         throw; 
        } 

    } 
+0

Ваш первый абзац неверен. Это CLR-функция, которая теперь поддерживается языком C#. –

+0

@PauloMorgado Huh? Почему первый абзац неверен? Он ничего не сказал о том, что это функция CLR и функция C#. – mason

+0

Что вы понимаете под «синтаксическим сахаром»? Для меня это помогает сделать что-то, что можно сделать по-другому. И вы не можете делать какие-либо фильтры исключений любым другим способом в C#. –

0

Исключительные фильтры были добавлены в C#, потому что они были в Visual Basic и команда «Рослин» нашли их полезными при развивая «Рослин».

Опасайтесь, чтобы фильтр работал в контексте throw, а не в контексте catch.

Во всяком случае, одна польза может быть что-то вроде этого:

try 
{ 
    //... 
} 
catch (SqlException ex) when (ex.Number == 2) 
{ 
    // ... 
} 
catch (SqlException ex) 
{ 
    // ... 
} 

Отредактировано:

Можно подумать, что это просто синтаксический сахар по этому поводу:

try 
{ 
    //... 
} 
catch (SqlException ex) when (ex.Number == 2) 
{ 
    // ... 
} 
catch (SqlException ex) 
{ 
    if (ex.Number == 2) 
    { 
     // ... 
    } 
    else 
    { 
     // ... 
    } 
} 

Но если мы изменить код для этого:

try 
{ 
    //... 
} 
catch (SqlException ex) when (ex.Number == 2) 
{ 
    // ... 
} 

Это будет больше похоже на это:

try 
{ 
    //... 
} 
catch (SqlException ex) when (ex.Number == 2) 
{ 
    // ... 
} 
catch (SqlException ex) 
{ 
    if (ex.Number == 2) 
    { 
     // ... 
    } 
    else 
    { 
     throw 
    } 
} 

Но есть одна принципиальная разница. Исключение не поймано и не было восстановлено, если ex.Number не 2. Это просто не поймано, если ex.Number не 2.

+0

Что значит «работает в контексте броска»? Мне это не кажется ясным. – mason

+0

Код в броске может работать под лицензированным пользователем или иметь разные разрешения CAS, например. –

 Смежные вопросы

  • Нет связанных вопросов^_^