-
Notifications
You must be signed in to change notification settings - Fork 4.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Proposal: try ... expressions #16072
Comments
It shouldn't always return null though but the default value for whatever |
The |
@gulshan Yeah, I figured. What's the point of the following example?
Isn't this the same as doing this?
I mean if you don't handle the exception and just rethrow, it seems pretty useless. This would be equivalent to this: (ignore the assignment)
But why would you do it? |
Yes it's kind of pointless. Did not notice earlier. :( |
Just came to my mind, may be explicit rethrows can be more useful (for logging etc) with proposed source generators- |
So there is no need for var result = try ExceptionThrowingMethod() ?? defaultValue; |
Not necessarily. |
My motivation here is, once the nullable reference types lands in C# and pattern matching becomes more powerful and mainstream, @alrz if the explicit rethrow is discarded (which is not really adding much value as pointed by @eyalsk ), your proposal with null-coalescing But @YotaXP 's question should also be taken into account. Is there any situation, where a method returns |
I believe that the commonly accepted good practice is that general There are situations where those suggestions don't apply, but I don't think it's a good idea to add syntax to the language, which would make code shorter in those rare situations, but that would also lead to people who should follow the common good practices to ignore them (because it's shorter). C# should be a pit of success, not pit of despair. |
This. |
Just as an example you can think about a DB operation that returns There's at least three problems with the null object pattern:
|
I would rather like to see something like this allowed:
(Allowing the removal of |
Yes! Me too. |
try ...
and try ... else ...
expressions
@Unknown6656, @jnm2 Make a proposal about it unless it exists. :) |
Would like it to be dorpped try and
Then
Maybe lambda? var value = method() catch((Exception ex) => {
return null;
});
var value = method() catch((Exception ex) => null); |
@Thaina Removing arbitrary stuff doesn't make things clear but the opposite, it looks both ugly and broken. p.s. You guys are proposing things that aren't really relate to this proposal so in my opinion you should create a new issue about it. |
@Thaina Well, okay, can you please make a new issue about it? :) |
@eyalsk Well, I don't think about make it more clear. Just want to make it short and compact. One line cast if possible I want to make it shorter from int x;
try { x = SomeMethod(); }
catch(Exception ex) { x = 0 } Want something like var x = SomeMethod() catch 0; |
For the last time, catch-all is harmful and should not be encouraged. 🙄 |
@Thaina Generally when people come up with a syntactic sugar it's because there's a pattern that is usually a good practice but at the same time it may create many repetitions across the code so sometimes baking it into the language might make sense but as people have noted here swallowing exceptions isn't a good practice hence why the suggestion is bad, now on top of that you're asking to have an alien syntax that makes it twice as bad. |
@eyalsk Yeah I just make up that syntax on a whim. Don't think it look good just make it work as I expected But my idea actually came from a pattern. The TryGet function pattern You could see there are Or if you just concern that we should need I just think it not really necessary. We already have |
Well, the difference is that Exceptions are for exceptional situations. |
@jnm2 I mean So you need to make So I was argue that, this is a pattern and we should just have syntactic sugar for it |
Yes, I understand what you're saying. The problem is you can't generalize that pattern. You should never catch exceptions except very specific ones where you're going to deal with it in a domain-specific way and your caller should not be allowed to be responsible for it. This applies to syntactic sugar as well as normal |
The try/catch comes with some performance penalties so the BCL team came up with the Tester-Doer pattern to combat this for methods that may throw on failure and throwing and catching them is expensive, more so when you need to do that many times so they introduce a
It's very different from what you're proposing, if you will compare for example It's true that in some cases where you don't have such methods you can either swallow the exception or provide an alternative implementation, in fact, in some cases swallowing can be faster but 80% it isn't, meaning, to find out you really need to do some benchmarks.
Again, it seems like you're thinking that |
@jnm2 I think opposite, we can generalize it. And it work like you just say. try it, catch exception, then set the default value That's what we always did for function that we don't know would it cause exception but we just really need to have a value set. Such as 404 or 500 from HttpWebRequest @eyalsk Well I know you are right about performance and I too hate to do try/catch because that reason too. And if I could write any function that could receive invalid argument by myself I would always make But we cannot control what 3rd party would implement. They would throw everything they don't like without concern about performance because they write function to work in server. They could just throw 404 or 500 HttpException And we need to deal with it anyway, I cannot avoid try/catch when work with 3rd party. So I just want syntactic sugar for it I know
|
Thank you all for the discussion. It is driving me to think of the alternatives and refining my idea of how the public enum class Result{
Success<T>(T Value),
Error(Exception Ex);
} The try expression will simply then catch and return the exception wrapped in a var result = try ExceptionThrowingMethod();
if(result is Error e){
//handle error here and return/throw it, or anything
//else to get out of enclosing scope
}
var resultValue = (result as Success).value;
System.Console.Writeline(resultValue);
// use resultValue for further work And I have found this line describing destructuring in proposed patterns document-
If implemented, this means something like the var result = try ExceptionThrowingMethod();
let Success goodResult = result else {
System.Console.Writeline((result as Error).Ex);
//handle error here and return/throw it, or anything
//else to get out of enclosing scope
}
System.Console.Writeline(goodResult.value);
// use goodResult.value for further work And if someone wants to go the discouraged exception swallowing route- let Success resultValue = try ExceptionThrowingMethod() else return; I think there may be some problem with matching a generic type |
I want to wait for rolling out of ADT in C# and further discussion should happen on csharplang repo. |
@gulshan a variation on this idea here: |
Sometimes developers do not want to look at the detail type and detail information of an exception. They would just want to rethrow or return or carry on with a default value, when any exception has occurred. In those case, the
try .. else ...
expression can be handy:And a
try
expression withoutelse
is just addingelse null
with the expression as default. That means-is actually just,
This feature may not be very good on its own. But along with proposed null checking in the C# 8, this can be handy. The
try ... else ...
syntax is actually borrowed from "The Error Model" blog from Joe Duffy, though was used in a fundamentally different(and more precise) error/exception handling model. This also depends onreturn
expression proposed in #14239.The text was updated successfully, but these errors were encountered: