You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Problem: try/catch is a statement, not an expression, which means you can't use it in contexts that need an expression. It's also tedious because it means variables that are loaded inside the "try" block must be pre-declared, which results in a lot of repeated type and variable names. This encourages large expansive try-blocks where all of the logic happens inside of the try, which is worse practice than small, specific catch blocks that only cover the expected site of the exception.
Obviously, we need a try/catch expression.
Previous proposals for try/catch expressions either encouraged empty catches(awful) or only allowed catching a single exception-type (bad) or failed to handle the ambiguity of multiple nested catches. Or used new non-idiomatic operators or misuse of existing symbols.
Instead, I'm suggesting a syntax that should be pretty idiomatic to C# 3.0 and later.
proposal
By toy example first:
var myValue = try => dict[key] catch((KeyNotFoundException ex) => null);
as you can see, slightly noisier than a normal Try-Catch, but still terse and clear, and leverages familiar Lambda syntax.
More elaborate example.
var responseCode = try => doStuff().ReponseCode catch(
(HttpException ex) when (ex.Code < 500) => ex.Code, //just pass-through the response-code
(HttpException ex) => { //for 500 and up errors, log the error before returning
logger.Error(ex);
return ex.Code;
},
(Exception ex) => { //treat all other errors as 500s.
logger.Error(ex);
return 500;
}
);
where all of exception_expression_N must return a type that is or can be implicit cast into the return type of try_expression, or they must throw.
If an exception expression needs to be broken out into a multi-statement body, then the syntax already established for doing the same for lambdas is used.
Finally is not a thing, because it's really non-expressiony.
This also avoids the ambiguity problems - the lambda-arrows make it unambiguous compared to a normal try...catch (an existing try will never be followed by a lambda arrow). Because all the catch blocks are in a single catch( ... ) parens there is no ambiguity if tehre are multiple nested try => blocks about which catch corresponds to which try.
Using a parens to contain multiple (parameters) => expression, delimited with commas, is already idiomatic C# because it's commonly done in higher-order functions, such as LINQ expressions.
No existing try...catch features such as multiple catch-blocks, when-clauses, etc. are sacrificed other than "finally", and the empty catch{...} which can be emulated with (Exception) => null and should never be used any time ever anyways.
The text was updated successfully, but these errors were encountered:
Sorry, I thought all issues related to this were already closed because of flaws in the proposal, couldn't find the open one. Added proposal as comment to the open one dotnet/csharplang/issues/980
Problem: try/catch is a statement, not an expression, which means you can't use it in contexts that need an expression. It's also tedious because it means variables that are loaded inside the "try" block must be pre-declared, which results in a lot of repeated type and variable names. This encourages large expansive try-blocks where all of the logic happens inside of the try, which is worse practice than small, specific catch blocks that only cover the expected site of the exception.
Obviously, we need a try/catch expression.
Previous proposals for try/catch expressions either encouraged empty catches(awful) or only allowed catching a single exception-type (bad) or failed to handle the ambiguity of multiple nested catches. Or used new non-idiomatic operators or misuse of existing symbols.
Instead, I'm suggesting a syntax that should be pretty idiomatic to C# 3.0 and later.
proposal
By toy example first:
as you can see, slightly noisier than a normal Try-Catch, but still terse and clear, and leverages familiar Lambda syntax.
More elaborate example.
so you can see, the pattern is
where all of
exception_expression_N
must return a type that is or can be implicit cast into the return type oftry_expression
, or they must throw.If an exception expression needs to be broken out into a multi-statement body, then the syntax already established for doing the same for lambdas is used.
Finally
is not a thing, because it's really non-expressiony.This also avoids the ambiguity problems - the lambda-arrows make it unambiguous compared to a normal try...catch (an existing try will never be followed by a lambda arrow). Because all the catch blocks are in a single
catch( ... )
parens there is no ambiguity if tehre are multiple nestedtry =>
blocks about which catch corresponds to which try.Using a parens to contain multiple
(parameters) => expression
, delimited with commas, is already idiomatic C# because it's commonly done in higher-order functions, such as LINQ expressions.No existing try...catch features such as multiple catch-blocks, when-clauses, etc. are sacrificed other than "finally", and the empty
catch{...}
which can be emulated with(Exception) => null
and should never be used any time ever anyways.The text was updated successfully, but these errors were encountered: