C# фильтр исключений?

Поддерживает ли C# компиляцию фильтров? Как вообще работают фильтры или что они делают?

Как отражатель декомпилирует фильтр как

пытаться
{
}
поймать (исключение е) когда (?)
{
}

4 ответа

Решение

C# не поддерживал фильтры исключений, как VB до C# 6. Что касается их работы, см. Статью Эрика Липперта "Наконец" не означает "немедленно".

Начиная с C# 6, фильтры исключений поддерживаются, поскольку C# FAQ демонстрирует:

try { … } 
catch (MyException e) when (myfilter(e)) 
{ 
    … 
}

Если выражение в скобках после 'если' [сейчас when] принимает значение true, блок catch запускается, в противном случае исключение продолжается.

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

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

private static bool Log(Exception e) { /* log it */ ; return false; }
…
try { … }
catch (Exception e) when (Log(e)) {}

Спасибо Mafii за ссылку на документацию C# 6.

Начиная с C# 6 теперь вы можете сделать это.

try { … }
catch (MyException e) when (myfilter(e))
{
    …
}

Это отличается от использования if заявление изнутри catch блок, использование фильтров исключений не размотает стек.

Поддержка фильтров исключений в C# представлена ​​в C# 6 (Visual Studio "Dev14"):

try
{
    throw new ApplicationException("1");
}
catch (ApplicationException ex) when (ex.Message == "2")
{
    // this one won't execute.
}
catch (ApplicationException ex) when (ex.Message == "1")
{
    // this one will execute
}

При отлове исключений, если вы хотите обрабатывать исключения по-другому, вы можете использовать фильтр исключений
- после C# 6.0
- После VB 7.1 Использование WHEN

1) Образец C# после C# 6.0

try
{
    throw new CustomException { Severity = 100 };
}
catch (CustomException ex) when (ex.Severity > 50)
{
    Console.WriteLine("*BING BING* WARNING *BING BING*");
}
catch (CustomException ex)
{
    Console.WriteLine("Whooops!");
}

Примечание: имейте в виду, что порядок имеет значение

2) Образец C# до C# 6.0

try
{
    throw new CustomException { Severity = 100 };
}
catch (CustomException ex)
{
   if (ex.Severity > 50)
    {
       Console.WriteLine("*BING BING* WARNING *BING BING*");
    }
   else
    {
       Console.WriteLine("Whooops!");
    }
}

Так как этот кусок кода эквивалентен предыдущему. значит, они эквивалентны, верно? --- "Но нет, они не эквивалентны"
ПРИМЕЧАНИЕ: фильтры исключений не разматывают стек

Читать больше здесь

Другие вопросы по тегам