Skip to content

First draft of enhanced using spec#31396

Closed
chsienki wants to merge 3 commits intodotnet:features/enhanced-usingfrom
chsienki:enhanced_using_speclet
Closed

First draft of enhanced using spec#31396
chsienki wants to merge 3 commits intodotnet:features/enhanced-usingfrom
chsienki:enhanced_using_speclet

Conversation

@chsienki
Copy link
Member

Initial draft for enhanced using speclet:

  • Lays out how pattern using works
  • Adds null / null value type behavior for extension method implemented dispose

Notes:

  • Links to a doc about pattern method lookup which isn't on GitHub yet
  • Doesn't yet include specs for using declarations

@chsienki
Copy link
Member Author

@dotnet/roslyn-compiler for review please

@alrz
Copy link
Member

alrz commented Nov 29, 2018

enhanced foreach will be spec'd separately? Because I don't see that in feature status page either.

@jcouv
Copy link
Member

jcouv commented Nov 29, 2018

@alrz I think "enhanced foreach" should be covered by this document too. We've been bundling enhanced using and enhanced foreach as one feature for tracking purpose.

@alrz
Copy link
Member

alrz commented Nov 30, 2018

I'd suggest at least mention it in the status page so people know that's a thing. I myself wasn't sure until I saw the test plan.


__See__: the [corresponding proposal](https://github.com/dotnet/csharplang/blob/d2ce4cc3e17708e7e1d062bf40da0901a744fa3b/proposals/using.md) in CSharpLang.

_Pattern based dispose_ aims to make participation in the disposable pattern easier by relaxing the restrictions on what types can be used in a ```using(...){ }``` construct.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
_Pattern based dispose_ aims to make participation in the disposable pattern easier by relaxing the restrictions on what types can be used in a ```using(...){ }``` construct.
_Pattern based dispose_ aims to make participation in the disposable pattern easier by relaxing the restrictions on what types can be used in a ```using(...){ }``` statement.


_Using declarations_ aim to make consuming a disposable type simpler by allowing ```using``` to be added to a variable declaration.


Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: double blank line


## Pattern based dispose

Previously a type must derive from ```IDiposable``` / ```IAsyncDisposable``` and implement the ```void Dispose()``` / ```Task DisposeAsync()``` methods. With pattern-based dispose, a type can be considered 'disposable' if it meets certain structural requirements. Specifically:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're missing something at the end of the first sentence. The sentence starts out with "Previously ..." but doesn't have a conclusion on what could be done previously.


For ```using``` statements:

"A reachable, void returning method called Dispose, that can be called with zero parameters"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Believe you mean "arguments" instead of "parameters" here. I

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably should even be "explicit arguments" (here and below) to be more precise.


For ```await using``` statements:

"A reachable, Task-like returning method called DisposeAsync, that can be called with zero parameters"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same

}
finally
{
if(x != null) x.Dispose(); // disposal
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now that we have is null consider using this code to represent the last line.

if (!(x is null)) x.Dispose();


This has the same effect as wrapping the declaration in a standard ```using(...){ }``` syntax, with the lifetime of the wrapped declaration being the same as that of the enclosing block.

_TODO_ No newline at end of file
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is left TODO?

@@ -0,0 +1,89 @@
# Enhanced Using

Enhanced using consists to two related features that aim to make the ```IDisposable``` coding pattern easier to participate in for implementers, and easier to consume for end users.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

end users [](start = 171, length = 9)

nit: end-users


__See__: the [corresponding proposal](https://github.com/dotnet/csharplang/blob/d2ce4cc3e17708e7e1d062bf40da0901a744fa3b/proposals/using.md) in CSharpLang.

_Pattern based dispose_ aims to make participation in the disposable pattern easier by relaxing the restrictions on what types can be used in a ```using(...){ }``` construct.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pattern based [](start = 1, length = 13)

nit: Pattern-based (here and likely elsewhere)


## Pattern based dispose

Previously a type must derive from ```IDiposable``` / ```IAsyncDisposable``` and implement the ```void Dispose()``` / ```Task DisposeAsync()``` methods. With pattern-based dispose, a type can be considered 'disposable' if it meets certain structural requirements. Specifically:
Copy link
Member

@jcouv jcouv Dec 5, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Previously a type must derive [](start = 0, length = 29)

nit: something is off with the tense.
How about "A type was previously required to derive from ..."?


Where reachable means legal to call from the site of the ```[await] using(...)``` under normal accessibility rules.

The ```Dispose``` / ```DisposeAsync``` methods are discovered using [Generalized Pattern Lookup](pattern-methods.md). In general if you could write ```c.Dispose()``` at the site of the ```using``` syntax and have it be a valid call under normal language rules, then the type is considered to be disposable. This includes implementation of ```Dispose``` via extension method, or methods with default or ```params``` parameters.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

c.Dispose() [](start = 151, length = 11)

Should this be c?.Dispose() following this Monday's LDM?


The design philopshy of the using statement is to only perform an action when there is a resource to be disposed. As such, null values are allowed, but no actions are performed. ```using(null){ }``` is valid syntax and the using is elided completely. ```using(IDisposable x = null){ }``` is also valid; the type is first checked for null before calling Dispose: when the using expression produces a null value there is no ```NullReferenceException``` thrown, and no Dispose method is called. This is extended as-is to pattern-based ```Dispose``` methods.

For extension method ```Dispose``` implmentations this means they will explictly *not* be invoked when the receiver is null, even though an equivilent call in code of ```x.Dispose()``` would result in the call being made with a null ```this``` parameter. This was a language decision to maintain the behavior that ```using``` perfoms no action when the resource being used is null valued.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

equivilent [](start = 140, length = 10)

typo: equivalent


The design philopshy of the using statement is to only perform an action when there is a resource to be disposed. As such, null values are allowed, but no actions are performed. ```using(null){ }``` is valid syntax and the using is elided completely. ```using(IDisposable x = null){ }``` is also valid; the type is first checked for null before calling Dispose: when the using expression produces a null value there is no ```NullReferenceException``` thrown, and no Dispose method is called. This is extended as-is to pattern-based ```Dispose``` methods.

For extension method ```Dispose``` implmentations this means they will explictly *not* be invoked when the receiver is null, even though an equivilent call in code of ```x.Dispose()``` would result in the call being made with a null ```this``` parameter. This was a language decision to maintain the behavior that ```using``` perfoms no action when the resource being used is null valued.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

implmentations [](start = 35, length = 14)

typo: implementations

@jcouv jcouv changed the title First draft of enanced using spec First draft of enhanced using spec Dec 5, 2018
@jcouv jcouv added Documentation PR For Personal Review Only The PR doesn’t require anyone other than the developer to review it. labels Dec 13, 2018
@@ -0,0 +1,89 @@
# Enhanced Using
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The doc should be updated to reflect the recent restriction to ref struct types.

@jcouv
Copy link
Member

jcouv commented Jan 30, 2019

With the release of preview2, it would be nice to finish publish this document.

@jcouv
Copy link
Member

jcouv commented Jan 31, 2019

Doc should call out restrictions on using-declaration statements:

  • cannot be used in switch statements
  • rules for goto
  • current restriction on extensions

@jcouv
Copy link
Member

jcouv commented Mar 20, 2019

It'd be good to revive and complete this PR for reference. Thanks

@chsienki
Copy link
Member Author

chsienki commented Apr 2, 2019

Rev'd this as #34697

I've re-written most of this from scratch, but incorporated the feedback here for any of the bits that survived. Created a new branch + PR as this branch was very out of date. Closing.

@chsienki chsienki closed this Apr 2, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Area-Compilers Documentation Feature - enhanced using Using pattern and declaration PR For Personal Review Only The PR doesn’t require anyone other than the developer to review it.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants