-
Notifications
You must be signed in to change notification settings - Fork 4.1k
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 Dispose by Convention #11420
Comments
It builds onto the existing C# pattern for resource disposal rather than adding completely new syntax that just happens to have the primary use case of resource disposal. It also brings I won't argue that it won't be "abused" because it certainly will be, just as |
Also, with The static class Program {
static void Main() {
using var resource = new SomeResource() { Id = 123 };
Console.WriteLine($"Using ${resource.Id}");
}
} |
@HaloFour The good thing about |
Which is great until you need to refactor it or someone fails a copypasta. I like adapting the disposal in one place.
Same with an extension
But you want to dispose it, so why not use what has been established as the appropriate C# pattern for disposing it rather than invent completely new syntax for these special cases?
Considering that you can define any of the above as extension methods, yes, they absolutely imply running custom code. That's the entire point of being able to write them as extension methods. You can adapt literally any type to an awaitable through custom code. Frankly, I despise |
You don't expect any of these to do anything other than what they are meant to be used for.
I think |
I also think that even if |
Nor do I expect that in this case. The primary use case is certainly to adapt non-
Indeed, but other than the contrived examples of writing console messages in reverse order which is all it seems that Swift and other documentation can provide, what are the use cases and are they so common that they justify a new language feature? I personally doubt it. The prototypical use case of I really don't want this to devolve into a It's interesting but while I respect @jskeet it's not really authoritative. 😀 That post does mention another place where conventions are used over explicit implementations, collection initializers. |
out ot curiosity, "The primary use case is certainly to adapt non-IDisposable resources to be disposable." why they didn't implement IDisposable in the first place? If the reason is to avoid an interface call (which turns to a double invocation with the extension method) or give it a name other than Dispose, well, the extension method wouldn't help with that. PS: VB supports both of these without losing Class C : Implements IDisposable
Public Sub Close() Implements IDisposable.Dispose
End Sub
End Class |
Usually because you have to use a third-party closed-source library where someone not familiar with .NET messed up. At least those are the most common cases where I've run into this.
Depending on how that resource is disposed, yes, you are adding another static method call into the equation. If that static method invocation just wraps an instance method invocation then the JIT would definitely inline it away. I doubt performance is generally a consideration here, though.
Actually that's probably the most common scenario. In my experience I've seen multiple examples of a class representing a resource that should be disposed that did not implement |
Yes, I linked it because of this. If the rule was violated once, surely it can be violated twice :).
This is rare enough for you to just implement and use a custom hack: public static void Using<T>(Func<T> factory, Action<T> action) where T : class
{
T instance = null;
try
{
instance = factory();
action(instance);
}
finally
{
if (instance != null)
{
//TODO: invoke Dispose via reflection.
}
}
} |
Indeed, it's not that difficult of a problem to work around. But it is annoying. And given that it's seemingly the odd case where the language absolutely requires implementation of an interface over convention to support a language feature I thought it was worth a mention. The two other places (that I can think of) where the language does require an interface implementation is This seems like a big enough of a deal to have warranted the #8115 proposal, over which I will make no bones about expressing my disapproval. I think that this proposal, combined with #115, fully eliminates the resource cleanup use cases for |
@HaloFour Well, I definitely dislike the |
Moved to dotnet/csharplang#93 |
Currently the
using
statement is tied specifically to implementation of theIDisposable
interface. This makes it impossible to use resource-like objects from other assemblies withinusing
statements.I propose that the compiler allow resolving an accessible
void Dispose()
method in the case that the type does not implementIDisposable
. That would allow for a developer to extend an existing class through the use of an extension method which would contain the logic for "disposing" of that resource:This brings
using
in line with the conventions also established byforeach
, LINQ andawait
where the compiler can resort to resolving instance members of a specific name/shape rather than require implementation of an interface or base class.The text was updated successfully, but these errors were encountered: