How can I force a throw to be a statement and not an expression (in a lambda expression)?

  • A+
Category:Languages

Starting from C# 7.0 the throw keyword can be used both as an expression and as a statement, which is nice. Though, consider these overloads

public static void M(Action doIt) { /*use doIt*/ } public static void M(Func<int> doIt) { /*use doIt*/ } 

When invoking like this

M(() => throw new Exception()); 

or even like this (with a statement lambda)

M(() => { throw new Exception(); }); 

the M(Func<>) overload is selected by the compiler indicating that the throw is here considered as an expression. How can I elegantly and intent-clear force the compiler to select the M(Action) overload?

One way to do it is this

M(() => { throw new Exception(); return; }); 

but the reason for the return statement seems non-obvious, and runs the risk of being changed by the next developer especially since Resharper warns about the unreachable code.

(Of course I can change the method naming to avoid overloading, but that is not the question. :-)

 


You could add a cast to for Action, although it does get a bit LISP'y with all the parentheses:

M((Action)(() => throw new Exception())); 

Not ideal, but if you want maximum clarity:

Action thrw = () => throw new Exception(); M(thrw); 

Comment

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: