Shorter forms of using statements #2894
Replies: 15 comments 14 replies
-
The variable is needed so the compiler can work out the scope of the using declaration through the scope of its variable. |
Beta Was this translation helpful? Give feedback.
-
I'd like to see this expanded to the
Given that the equivalent code for EDIT: Unless you're referring to doing something like |
Beta Was this translation helpful? Give feedback.
-
If I can attempt to read the mind of the language design team, I don't think this is something they'll go for; it's just shorthand (you can't use this syntax to accomplish anything you couldn't do before), it saves a pretty trivial amount of code when you can use it and you also can only use it in a pretty limited number of circumstances. Also, it's probably rarely important but it's confusing as to when objects get disposed in nested expressions: var a = new A();
a.M1(x => x.M2(M3(using new C()))); When does the |
Beta Was this translation helpful? Give feedback.
-
That's not really an argument, plenty of things are just a syntactic sugar and yet they were added to the language for the sake of readability. In my opinion, the variable is redundant (from the reader/programmer pov) and reducing the scope of usage is a good thing.
Hardly, it's like saying
I beg to differ, it's pretty trivial to understand as long as the programmer is aware to what it lowers to. Now, I don't know whether a member of the language design team will champion this as it's really niche but I can't see the downsides. |
Beta Was this translation helpful? Give feedback.
-
@eyalsk I think I didn't make my point very clearly about why I used that particular piece of code as an example of why it's confusing. I'm saying that there are a number of perfectly valid interpretations of the scope of this disposable value, and even when you know how the feature works it's still difficult to tell. For example, the code in question: a.M1(x => x.M2(M3(using new C()))); could be interpreted as being equivalent to this (a): using (var $tmp = new C())
{
a.M1(x => x.M2(M3($tmp)));
} or this (b): a.M1(x => {
using (var $tmp = new C())
{
x.M2(M3($tmp))
}
}); or even this (c): var a = new A();
a.M1(x => {
var $tmp2;
using (var $tmp1 = new C())
{
$tmp2 = M3($tmp1);
}
return x.M2($tmp2);
}); My point is that it's very difficult to give a quick and easy explanation of what the scope is of that variable. Is it the immediately containing expression? That would be option (c), the most complicated to lower. Is it the immetiatly containing statement-expression? That would be option (b). Or the top-most? That's option (a). I'm not super against this feature or anything, I'm just saying that it's a whole language feature (and potentially a confusing one at that) all to save a few characters. |
Beta Was this translation helpful? Give feedback.
-
FWIW, this seems super wrong to me:
Why? Because it looks like the file will be disposed before calling into SaveFile. Really feels oogy. |
Beta Was this translation helpful? Give feedback.
-
I hadn't looked at it that way previously. Now I can't unsee it! |
Beta Was this translation helpful? Give feedback.
-
Yup. And they're all things where the benefits have been widespread because they addressed extremely common use cases - such as the I'm sure that you're familiar with the oft quoted language features start at -100 points. |
Beta Was this translation helpful? Give feedback.
-
@theunrepentantgeek You're right, I'm just saying that if people want to make a case against a feature, saying that something is a "shorthand" for something else is not good enough; however @CyrusNajmabadi does make a good point against it. |
Beta Was this translation helpful? Give feedback.
-
Again, my point was not to downvote the feature merely because it's shorthand; god knows I'm not one to shy away from a shorthand feature! My point was that it's just shorthand and it's potentially confusing and it doesn't even save that much anyway. |
Beta Was this translation helpful? Give feedback.
-
@Richiban I wasn't referring to your post specifically in my previous comment but speaking in general, I think I understood your point with the explanation you gave above. :) |
Beta Was this translation helpful? Give feedback.
-
@eyalsk Nice, thanks for clearing that up :) |
Beta Was this translation helpful? Give feedback.
-
If you put it into context: {
...
SaveFile(using File.Create(fileName));
...
} You can see the scope of the using statement is within the braces enclosing {
...
using var file = File.Create(fileName);
SaveFile(file);
...
} |
Beta Was this translation helpful? Give feedback.
-
@ronnygunawan Yeah, that's my thoughts exactly although it does look like it happens before |
Beta Was this translation helpful? Give feedback.
-
What about:
Should be disposed when instance method exits. |
Beta Was this translation helpful? Give feedback.
-
C#8 introduces new shorter form of using statement without explicit scope:
instead of
but it still requires variable declaration.
Variable declaration in old-style syntax is optional, but in C#8 is required.
Often there is no need to introduce variable but scoped lifetime is still needed, like that:
Beta Was this translation helpful? Give feedback.
All reactions