3

I can hardly believe the C# developers didnt thought about that. I dislike that there doesnt exist better way to create one-time disposable variables, as we have to declare them in blocks:

using( XYZ x = smth){
    ShowForm(Color.Blue, x,  "30px");
    ......
}

for me, placing the lines in brackets & placing declarations in-front of code, is visually unpleasent (as it reminds me to be if {} else {} block ).

so, does there exist any alternative way to create self-disposing variables inline, like:

ShowForm(Color.Blue, (using x=smth) x ,  "30px");

?

T.Todua
  • 53,146
  • 19
  • 236
  • 237
  • 4
    You know that curly brackets for a single-statement blocks are optional, right? I mean, you could write `using (var x = something) ShowForm(Color.Blue, x, "30px");` and it would do the same thing as with curly braces. – Sergey Kalinichenko Feb 03 '18 at 11:20
  • @dasblinkenlight thanks for your comment, but i think your answer in irrelevant to my desire. placing extra codes in front of declaration is also unpleasent and confusing – T.Todua Feb 03 '18 at 11:31
  • That's why it's a comment, not an answer. I posted an answer below, it's too long to fit in a comment, and it does not propose to use anything visually unpleasant (spoiler: it can't be done). – Sergey Kalinichenko Feb 03 '18 at 11:34
  • Side note: If you have source control over `ShowForm` then nothing is stopping you from disposing any parameters who's type implements `IDisposable` inside that method. – Igor Feb 03 '18 at 11:39
  • `using` is more for things that have to be closed on exception like connection or file stream, so in most cases just `ShowForm(Color.Blue, smth, "30px");` seems enough. https://github.com/Fody/Usable – Slai Feb 03 '18 at 12:32

1 Answers1

7

Not only does C# not have a facility for this, but it is also not possible to define one without getting into ambiguities with expression's semantic.

The limits of the using block define the scope of the newly added variable, along with its useful lifetime. The closing brace of the using block (or the end of a single statement when it is not enclosed in curly braces) defines the point where Dispose must be called on the object of the using clause.

Now imagine that there is such a thing as a using expression that lets us create a disposable object "inline", e.g.

ShowForm(Color.Blue, using var x = smth,  "30px");

What should be the useful lifetime of x? Should it be disposed when ShowForm returns? What if you do this

Foo(1, Bar(2, using var x = smth))

should x be disposed when Bar finishes, or should it wait for Foo to complete as well?

There are other contexts, such as control expressions of loops and conditional statements, where the scope of disposable variable would become ambiguous. That is why C# insists on providing explicit limits to the scope of the disposable variable introduced in the using clause.

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
  • thanks for answer! however of course, the default behavior (lifetime) of inline method, should be to dispose that element after executing that method. at least, c# should have allowed that , i think so. – T.Todua Feb 03 '18 at 11:36
  • 4
    @T.Todua I was trying to suggest that the decision to limit lifetime to the immediate calling method (`Bar`) would be as arbitrary as a decision to let the object stick around for the duration of the outer calling method (`Foo`). It would not be entirely unreasonable to demand such extension of object's lifetime, because `Bar` could legitimately return an object that relies on `x` being around. In the end, it is easier to put this responsibility on the programmer. – Sergey Kalinichenko Feb 03 '18 at 11:49
  • 1
    It should also be noted that the `using` statement is far more pleasant to look at than a `try-catch` block, which is what the `using` statement implements and helps to avoid. – NightOwl888 Feb 03 '18 at 14:56
  • 2
    @T.Todua - `the default behavior (lifetime) of inline method, should be to dispose` - Then you create another problem. How do you allow disposables with longer lifetimes? For example, it is quite common in ASP.NET MVC applications to have database connection objects last for the lifetime of the HTTP request and dispose them at the end because they are expensive to create. These objects could pass through any number of methods and there would be a big problem if every one of them disposed the object by default. Per MSDN, it is the responsibility of the *creator* of the instance to dispose it. – NightOwl888 Feb 03 '18 at 15:02
  • @NightOwl888 c# should dispose the variable aftert the `original_caller_method` is returned, doesnt matter how many methods are fired within it. btw, i think what i say has no negative sides, I dont say it should REPLACE `using`, i just say we should have that too. – T.Todua Feb 04 '18 at 14:54
  • @T.Todua - What if the disposable component in question is registered as a singleton with some 3rd party DI container? Then no method should dispose it over the lifetime of many individual requests. It would really suck if you had to add a `[NoDispose(typeof(MyComponent))]` attribute to every method call all the way down the whole call stack just because you want to override that illogical default behavior. – NightOwl888 Feb 04 '18 at 15:06
  • @T.Todua - I am not saying that the current situation couldn't be improved, but "magic" dispose automatically behavior is just going to make things worse since object lifetimes are extremely important for most applications to work right. If you are following along with any of the DI questions on SO, there are so many people confused when they register their component with the wrong lifetime and it is automatically disposed before they are done with it. That said, DI seems to solve this nicely so you don't have to have so many `using` blocks in the code. – NightOwl888 Feb 04 '18 at 15:10