Skip to content

Commit

Permalink
limit disposable pattern (#6785)
Browse files Browse the repository at this point in the history
The proposal spec'ed this out in general terms for any type, and included a provision to allow extension `Dispose` methods.

The implementation only allows `ref` struct types to use the pattern-based Dispose. Furthermore, the `Dispose` method can't be an extension method.

Fixes dotnet/docs#31815

I made edits to make the proposal match the implementation. As an alternative, I could make edits to indicate which portions of the proposal were implemented and which may be delivered in the future.
  • Loading branch information
BillWagner authored Dec 13, 2022
1 parent 64a2ead commit a423537
Showing 1 changed file with 5 additions and 14 deletions.
19 changes: 5 additions & 14 deletions proposals/csharp-8.0/using.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,12 +102,12 @@ Restrictions around `using` declaration:

### pattern-based using

The language will add the notion of a disposable pattern: that is a type which has an accessible
The language will add the notion of a disposable pattern for `ref struct` types: that is a `ref struct` which has an accessible
`Dispose` instance method. Types which fit the disposable pattern can participate in a `using`
statement or declaration without being required to implement `IDisposable`.

```csharp
class Resource
ref struct Resource
{
public void Dispose() { ... }
}
Expand All @@ -118,16 +118,8 @@ using (var r = new Resource())
}
```

This will allow developers to leverage `using` in a number of new scenarios:

- `ref struct`: These types can't implement interfaces today and hence can't participate in `using`
This will allow developers to leverage `using` for `ref struct` types. These types can't implement interfaces today and hence can't participate in `using`
statements.
- Extension methods will allow developers to augment types in other assemblies to participate
in `using` statements.

In the situation where a type can be implicitly converted to `IDisposable` and also fits the
disposable pattern, then `IDisposable` will be preferred. While this takes the opposite approach
of `foreach` (pattern preferred over interface) it is necessary for backwards compatibility.

The same restrictions from a traditional `using` statement apply here as well: local variables
declared in the `using` are read-only, a `null` value will not cause an exception to be thrown,
Expand All @@ -146,9 +138,8 @@ etc ... The code generation will be different only in that there will not be a c
}
```

In order to fit the disposable pattern the `Dispose` method must be accessible, parameterless and have
a `void` return type. There are no other restrictions. This explicitly means that extension methods
can be used here.
In order to fit the disposable pattern the `Dispose` method must be an accessible instance member, parameterless and have
a `void` return type. It cannot be an extension method.

## Considerations

Expand Down

0 comments on commit a423537

Please sign in to comment.