19 comments

[ 3.1 ms ] story [ 63.4 ms ] thread
as I see it they aren't much more than "more syntactic sugar"
The point of the article was the fact there is a functional difference in how the runtime/code behaves in this instance.

Syntactic sugar would be something like automatic property getters and setters in C#; they just shorten the syntax drastically and the compiler or runtime unroll your code to the traditional implementation.

In this case you can interrogate things normally bound up into the exception instance itself, like the message without having to hit the catch block to wait for it to be hydrated. Once you enter that catch block things happen in the runtime that are costly so avoiding that if possible is the best route.

Exception filters are not syntactic sugar because they will not unwind the stack until a true condition is encountered and you really catch the exception, something impossible to do with the traditional catch-check-[re]throw mechanism.
When you throw an exception on the CLR, it will 1) walk the stack looking for candidate catch blocks, and 2) if it finds one, it will long jump to that catch block, destroying all stack frames between the frame that threw the exception and the frame for the function that contains the catch block.

Exception filters are a CLR feature that modify this process a little. Now, when an exception is thrown, it still walks the stack looking for candidate catch blocks, but whenever it identifies a candidate, it will call the exception filter function (a function from exn -> bool, where exn is the exception being caught by the Catch block). If the function returns false, the CLR will disregard this candidate catch block and continue searching. C# 6.0 merely added some syntax that exposed this functionality of the CLR, the language itself isn't doing this.

Not to pile on, but: http://en.wikipedia.org/wiki/Syntactic_sugar

If the behavior can be expressed using previously existing syntax, then a construction is syntactic sugar. This is not true in this case. (sorry if you knew this already)

I see the purpose of this as more preventative. I can create a contstraint for (Exception == "x1") { throw Exception when (x1 == "<filepath>")} Now I can understand why'd you'd be alerted of this however this would cause parallel processing latency when it comes to the concurrnt evaluation of when expecptions can occur instead of code exceution itself. So instead why not run the code and create log block that for (Exceptions == true) { while (i = 0, i < y.length, i++) then y= x.length x= write.push(<sys.path>), result = println(x.trace) }

I believe this will be more effiencient than an excess of concurrent filters.

It looks really weird to me, having that empty catch block. I expect a lot of issues to accidentally be introduced from poor merges or something.
I don't understand. Why would you have an empty catch block? He does in his example but that's an example. I cannot see why you'd even write a catch block if it was empty in production code (unless you're trying to do some error-and-continue pattern, which is rare/mostly an anti-pattern).
I wish it were rare, I've seen it in a lot of projects I've had the privilege of dropping in on. They will often check for an error and log it, then "throw;".

edit: to further clarify my objective, I was thinking of a way to make the stack traces better, without risking the maintainability of the code now that I'm aware of the difference. I guess in all it would be best to just remove it. In my case, we've found some strange things in unexpected places and I prefer to not change stuff, unless I understand how the underlying portions work.

Or just supress it, for some methods you might want to return a null value/"null object"/bool rather than have an exception cascade up the chain and risk crashing the application. I think Exceptions are a bit problematic as a concept but then again so are null values :)

An easy example are checking if a file exists under Windows 8, it's partly a product of the currently deficient API's but the fastest way to check if a file exists is to try to get it and catch the exception, and you'd want to return bool from a FileExists method

After many years I still don't really grok the idea behind exceptions, and I get this feeling that I'm not alone with that. There probably is an extremely smart idea supporting this whole "handle all errors with exceptions" style, but I haven't seen any good explanation yet; instead what I see most often is a case of Stockholm syndrome - "it's in the language, it's The $LANGUAGE Style, it must be Good!".
> VB.NET already had this feature

Years ago, I did .NET consulting and switched between C# and VB.NET depending on the client. Exception filters were the only feature from VB.NET that I missed when working in C#. I didn't use them often, but in some cases, they were the cleanest solution.

I've since switched to Ruby and other OSS stacks, but I'm still happy to see C# get this. It's one less argument for anyone to use VB.NET, which has far inferior syntax, in my opinion – especially when working with lambdas or events.

I worked on a VB.Net project once and went to use LINQ...

I was blown away by the lambda syntax. I get the need for it from a parsing perspective, but my god.

What happens when the exception test expression throws an exception?
edit: Apparently [0] is for VB.net and C++ but I would think including VB.net would mean the CLR. If so, then C# should be the same. A further SO post on the topic with no official sources confirms the same at [1]

---

Found more details at [0]

Apparently the CLR runtime catches them and then causes your exception filter to return false, as if you had done so yourself.

[0] https://msdn.microsoft.com/en-US/library/ms182337%28v=vs.80%... [1] http://stackoverflow.com/questions/28879320/what-happens-if-...

Good find, thanks!

Returning false in this situation feels a bit hacky IMO.

To respond to your point,

I think its the only way to go. The filter function that throws could be attached to any catch block all the way up the call stack. Where exactly would you start the search for a exception handler in that case?