catch
. This block will be executed only if the specified conditions are met. We illustrate the syntax with a small code snippet: public void Main() { try { throw new Exception("E2"); } catch(Exception ex) when(ex.Message == "E1") { Console.WriteLine("caught E1"); } catch(Exception ex) when(ex.Message == "E2") { Console.WriteLine("caught E2"); } }
catch
block, the exception will be caught first, and then the condition will be checked. Exception filters check the condition before an exception is caught. If the condition is not met, then the catch
block will be skipped, .NET will proceed to consider the next catch
block.throw
inside a catch
block instead of a throw ex
, then we save the stack. The fact is that people think only about the StackTrace
exception StackTrace
, but not about the CLR stack itself. Let's take an example. If you try to start it yourself, then make sure that the “Break on Exception” checkbox for exceptions is turned off in the Visual Studio settings (Debug-> Exceptions-> Uncheck all).Log
method always return false
and perform logging using exception filters instead of placing it inside the catch
block. Notice again the stop line of the debugger and the debugger window ( Note: the post and example were updated, but the picture remained the same; instead of catch (if(Log()))
should read catch when (Log())
):if
keyword, and now it has been replaced with a new when
keyword. Motivation is well illustrated by the following picture:localVariable
, which is not available in the first example, because it is not on the stack inside the catch
block. This corresponds to what we can see in crash dumps.catch
block, you will not enter the rest. If you analyzed the condition and decided not to throw it out again, then you will not be able to get into other catch
blocks. In the case of exclusion filters, an unfulfilled condition does not prevent us from checking the remaining catch
conditions to try to enter another block.catch
block will only be executed if the condition is met. And we can use the bool
function as a condition. But what happens if the condition itself throws an exception? The expected behavior is the following: the exception is ignored, the conditions are considered false. Consider the following code: class Program { public static void Main() { TestExceptionFilters(); } public static void TestExceptionFilters() { try { throw new Exception("Original Exception"); } catch (Exception ex) when (MyCondition()) { Console.WriteLine(ex); } } public static bool MyCondition() { throw new Exception("Condition Exception"); } }
"Original Exception"
exception is thrown "Original Exception"
before entering a catch
MyCondition condition will be checked. But this condition itself throws an exception, which should be ignored, and the condition should be considered false. Thus, we get an unhandled exception: System.Exception: Original Exception
TestExceptionFilters()
method, this method will be invoked through reflection. The expected behavior remains the same, although we call the function differently. class Program { public static void Main() { var targetMethod = typeof(Program).GetMethod("TestExceptionFilters"); targetMethod.Invoke(null, new object[0]); } public static void TestExceptionFilters() { try { throw new Exception("Original exception"); } catch (Exception ex) when (MyCondition()) { Console.WriteLine(ex); } } public static bool MyCondition() { throw new Exception("Condition Exception"); } }
System.Exception: Condition Exception
Source: https://habr.com/ru/post/252437/
All Articles