Skip to content
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] Allow for inline creation and handling of IDisposable objects (RAAI) #181

Closed
tpetrina opened this issue Jan 30, 2015 · 18 comments

Comments

@tpetrina
Copy link

Proposed syntax would be

var x = using new Disposable();
var y = using new Disposable();

The code is just a shorter way of writing:

using (var x = new Disposable())
{
  using (var y = new Disposable())
  {
  }
}

Which is actually much more composable with try-catch pattern. Now we can remove one extra pair of curly braces and write:

try
{
   var x = using new Disposable();
}
catch
{
  // log and handle
}
@RichiCoder1
Copy link

The big reason using is required is to make clear the lifetime of the displosable object. With using new Disposable, where do it's lifetime end? Would it behave like a destructible object?

@HaloFour
Copy link

Something like this was mentioned on CodePlex where it would be syntactic candy for using where the scope of the disposable object is the same as the scope in which the object was declared:

public void Method(int x) {
    using var disposable1 = new SomeDisposable();
    if (x == 0) {
        using var disposable2 = new SomeOtherDisposable();
        // do stuff
    } // disposable2 automatically disposed here
    // do other stuff
} // disposable1 automatically disposed here

// equivalent to

public void Method(int x) {
    using (SomeDisposable disposable1 = new SomeDisposable()) {
        if (x == 0) {
            using (SomeOtherDisposable disposable2 = new SomeOtherDisposable()) {
                // do stuff
            }
        }
        // do other stuff
    }
}

The same rules would have to apply in that the declared variable would be effectively read only.

@tpetrina
Copy link
Author

@RichiCoder1 Scoping rules should apply, similar to the stack objects in C++. This would effectively give you deterministic destruction.
@HaloFour Didn't know that it was already posted. Your syntax is even better than mine.

@RichiCoder1
Copy link

@tpetrina what advantage would this have over #161 then? It seems likely to only create confusion for people.

@HaloFour
Copy link

@RichiCoder1 The one advantage I think is that this would apply to the wide variety of existing IDisposable objects rather than requiring writing new types. But perhaps the concepts can be merged since they are relatively similar, although I'm seeing in that thread that destructible types would not implement IDisposable so it's effectively a schism (which seems like a horrific idea).

@RichiCoder1
Copy link

@HaloFour as mentioned in the other thread, destructible is far more strict and has more specific language semantics than IDisposable. The later is a patch over the hole that was left by the lack of existence of the former, and the flaws of the C# finalizer. Having destructible subclass IDisposable therefore makes no sense. Maybe having Box<T> implement it might, though.

@HaloFour
Copy link

@RichiCoder1 Maybe, but since the framework is absolutely loaded with existing IDisposable types I don't see how destructible will help with their consumption in the near term. Why not also make the consumption of those types easier? Even if that involves some kind of IDisposable to destructible wrapper why not make it easier in the language to use that?

@RichiCoder1
Copy link

Hmm. I disagree with trying to fit an IDisposable inside destructible, but adding sugar would be a valid point. I suppose it would be a nice to have, especially in situations with multiple usings. It's a need vs. effort argument at that point.

@scalablecory
Copy link

This syntax sugar would be very useful for cleaning up nested usings, but it would be too confusing to have both this and a destructible. I believe a merger of the ideas (as I suggested in #161) would be phenomenal.

@tpetrina
Copy link
Author

@RichiCoder1 Well, I think that using var is actually more informative to the reader that the object will be disposed at the end of the scope. I have to read your proposal + all the comments to see how well they match.

In C++ 'destructible' objects are not created via new, they are created simply by declaring the variable.

The proposed syntactic sugar is:

  • composable
  • succint
  • clear to the reader
  • works on existing types

@tpetrina tpetrina changed the title Allow for inline creation and handling of IDisposable objects [Proposal] Allow for inline creation and handling of IDisposable objects Jan 30, 2015
@RichiCoder1
Copy link

In C++ 'destructible' objects are not created via new, they are created simply by declaring the variable.

If I'm reading the proposal right, structs would largely behave the exact same way. It's classes where the difference would exist.

Edit: Though C# wouldn't have the ability to do MyStruct c(1,3);. That'd still be MyStruct c = new MyStruct(1,3);

I believe a merger of the ideas (as I suggested in #161) would be phenomenal.

The risk of doing this is diluting destructible. The point would be, moving forward, that one should use destructible moving forward where one would use IDisposable, except where you might want IDisposable's exact semantics. I don't believe this would be confusing, especially if the requirements for destructible are design/compile time constrained. I'd agree with making IDisposable easier to use for legacy reasons, but I'd strongly be against trying to constraint destructible based on the existance of IDisposable.

@tpetrina
Copy link
Author

IDisposable can be passed to other objects. You can even use it to create reference counting.
On the other hand, destructible has a really bad syntax IMHO. It also doesn't work with existing code (proposed syntax is exactly for this purpose).

@RichiCoder1
Copy link

IDisposable can be passed to other objects.

destructible can too. That's the point of both move for passing ownership and Box<T> for working with existing types or in the cases where you want to have multiple references. Edit: and ref thinking about it now.

On the other hand, destructible has a really bad syntax IMHO. It also doesn't work with existing code (proposed syntax is exactly for this purpose).

I'm not sure I understand how the syntax is bad. The point of destructible is to be very strict. Deterministic. One of IDisposable's biggest flaws is that you have to explicit ensure that you're using it, or calling dispose. You can pass it around willy nilly until the GC comes to clean it up. That's how the much maliged Disposable pattern came about. destructible has very specific owership and lifetime by default.

Put another way, think in terms of The Pit of Success. IDisposable makes it very hard to do things right. destructible would make it very difficult to do things wrong, and you can safely make assumptions about it.

@tpetrina
Copy link
Author

Hmm, I think you are right. Let me take another look at destructibles then.
But I would still want to have inline disposal of already existing IDisposable items.

@gafter
Copy link
Member

gafter commented Nov 20, 2015

I like the syntax from #5881 better.

@gafter gafter changed the title [Proposal] Allow for inline creation and handling of IDisposable objects [Proposal] Allow for inline creation and handling of IDisposable objects (RAAI) Nov 20, 2015
@whoisj
Copy link

whoisj commented Nov 20, 2015

@gafter 👍

Another, potential option for RAII style "things" is to add destructors to structs. This would allow those of us who play at the edge of managed / native significantly to get unique_ptr like support in languages like C using C#. I'd be a very happy camper if this ever arrived. 😉

@gafter
Copy link
Member

gafter commented Aug 15, 2016

We like this idea, but we think we prefer the syntax in #5881. So closing this one as a dup.

@gafter gafter closed this as completed Aug 15, 2016
@gafter gafter added the Resolution-Duplicate The described behavior is tracked in another issue label Aug 15, 2016
@svick
Copy link
Contributor

svick commented Aug 15, 2016

@gafter Since #5881 was previously closed as duplicate of this issue, shouldn't it be reopened now?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

8 participants