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!");
}
}
Так как этот кусок кода эквивалентен предыдущему. значит, они эквивалентны, верно? --- "Но нет, они не эквивалентны"
ПРИМЕЧАНИЕ: фильтры исключений не разматывают стек
Читать больше здесь