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