-
Notifications
You must be signed in to change notification settings - Fork 4k
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: 'using' local variable declaration (RAII) #5881
Comments
Do you really think this is worth all the work involved? |
Nice, I like this |
This has been proposed before, but I can't find the issue so perhaps it was over on CodePlex. Either way, I also like this. Combining |
The
So unless better keyword proposed, I would prefer |
The |
paulomorgado: Personally, yes, I do. I have seen many cases where having explicit control over the Dispose point through a new block scope is unnecessary, and variable scope would have sufficed. I understand every feature starts at -100. I'm willing to try to make my case. |
HaloFour: I agree the silent read-only nature of the variable assignment is a bit unfortunate, but I came to the same conclusion - it's a practice established already through the current using statement semantics, so my hope is that it could be justified as such. |
Also - yes, to be clear, the variable assignment would be read-only. This is intended to have exactly the same semantics as the traditional 'using' statement, but just in the current block scope. |
Here's the CodePlex proposal for reference: 544789 |
HaloFour: Thanks for the reference. I believe this proposal is identical to that one, yes. It looks like it never reached a conclusion there? If I'm reading that right, this could be considered the GitHub issue for it, then. |
Oh the wonders if
|
How would the proposed syntax work out in case the using (new RuntimeDurationLogger(Console.Out))
{
// slow code
} |
bkoelman: I should have been clearer here - this proposal only permits the form of the using construct where there is a variable declaration. This is not intended as a replacement for the traditional using construct - merely a complement to it. |
Or there could be a if (condition) {
using new RuntimeDurationLogger(Console.Out);
// do stuff here
// Dispose called here
} |
HaloFour: This certainly could be done. I had omitted this support from the proposal because I could not think of a scenario needing it, and it felt strange to have code that might just say 'using myVar;' somewhere. But, it would simplify the proposal to do what you are saying here. |
@HaloFour in the use-case you describe above, when do you envision the variable leaving scope and thus being disposed? Personally, I would assume the |
At the closing brace of the if (condition) {
using (new RuntimeDurationLogger(Console.Out)) {
// do stuff here
}
}
Wouldn't be much point in that, would there? Might as well just write |
What is the point of waiting for the closing of the I was working off the assumption that |
@whoisj Because keeping the reference alive/undisposed within the scope is the purpose of that class? That's why |
I think this proposal is about simplifying, making less indents, it's better keep it simple. Well the different behavior between |
For what its worth:
|
@DiryBoy I was referring to proposal #115 to introduce |
OK, @HaloFour I read your first comment again and understand what you meant, it's about combination, |
We could just get rid of the confusion altogether: using conn = new SqlConnection("...");
using cmd = conn.CreateCommand(); That would really just shorthand for whatever syntax is agreed upon ( I'd like to see removing the requirement for foreach (result in results) { ... } |
There is still be a good reason to allow declaring type as the class may have explicitly declared interface methods, or shadowed members that can only be called when cast to the appropriate type. There is also some coding styles which prefer avoiding using As for the the |
What if I have a
Under your suggestion, it would be returning a disposed connection. |
@rhencke, some say -100 others say -1000. What would you drop from what the team is proposing to work on in favor of this? |
@paulomorgado: This was a reference to http://blogs.msdn.com/b/ericgu/archive/2004/01/12/57985.aspx. Quite simply, I am not the right person to make decisions in that area. If you have objections to the proposal itself, I am happy to discuss them with you. |
Since we like this syntax better than #181, we'll track it using this issue. |
Ya know, all of this comes down to C# having terrible ownership semantics. The introduction of a "borrowed" reference would likely resolve most of these issues. (I now return you to your originally scheduled topic about using disposables) |
just like deffer in golang, very good |
I wish "fixed" statement could works similarly. fixed char* p1=&str1[0];
fixed char* p2=Foo(str2);
// blahblah... |
Is there a separate proposal for doing this at class scope? e.g. have this expand to have an automatically-implemented class Example : IDisposable
{
using Stream _stream;
public Example(string path) {
_stream = File.OpenRead(path);
}
} |
@Porges It was mentioned in other issue sometimes. I don't remember. But the main problem there is it must be readonly or else it might be replaced with another instance and the old one would not be disposed |
@Thaina, good point. Perhaps if it were restricted to |
Should we be keeping the related discussion here: dotnet/csharplang#114 ? |
It would also be useful if |
Um...
Not sure I want the member |
@whoisj, I meant more of the perspective of being implicitly scoped, rather than being RAII. The The |
@tannergooding sounds to me, what you're really after is Rust-like ownership semantics. Me too, but it would predicate too many changes in the CLR to happen in any reasonable time frame. |
@whoisj I think @tannergooding is talking about something like this: {
fixed int* p = e;
// use p
} which is equivalent to: {
fixed (int* p = e)
{
// use p
}
} |
@alrz gets it, I'm just bad at communicating sometimes 😄 |
It is just as likely that I'm just dense and not understanding, but yup I get it now thanks to @alrz 😄 |
This is what I was looking for today.
I would like to be able to shorten it to
( |
@hoensr, where would be the start and end of the scope of that object? |
Since the |
I'm asking for the scope of the object. When will it be disposed? |
Sorry to be unclear. At the semicolon, too. Anything else would be a surprise, wouldn't it? |
Can you show in what that would be lowered to? |
Sorry, I'm not sure I understand what you mean with "lowered to". My idea that these inline |
Discussions regarding language design have moved over to the csharplang repository. This issue is a championed proposal and the conversation has continued here: dotnet/csharplang#1174 |
@HaloFour : Thank you! I guess I will add my comment over there, then. |
This is being done in C# 8.0. See dotnet/csharplang#1174 for any further discussion. |
Motivation
In C# (and VB), using statements contain an embedded statement (traditionally, a block statement) that contains the code that will be run before the resource is disposed.
When multiple resources require disposal, using statements are nested to accomplish this (though traditionally written at the same level of indentation)
This works well if all resources can be acquired at the same time, but this cannot always be done. The motivating example, in this case, is the traditional boilerplate for ADO.NET, in which the block scopes provide more noise than signal.
Proposal
For scenarios like this, explicitly providing block scope often feels like overkill. While it's important to dispose of the resources properly, the block scope containing the using is often sufficient enough.
I would like to propose the following syntax:
using
local-variable-declaration;
This would effectively be syntactic sugar for 'Place this local variable declaration in a using statement, and place all statements within the same block that follow this statement into the statement list of that using block'. Basically, the desired effect is the variable follows normal scoping rules, and as soon as the variable falls out of scope, the resource is disposed.
With this new syntax, we can now write the above example as:
The text was updated successfully, but these errors were encountered: