-
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
[C# feature request] Add IDisposable adapter for any type for using statement. #10361
Comments
This doesn't look very useful to me, since types like your MyFile should be very rare. Or do you have some specific situation where they are common? |
You save no characters typing this out, so it seems like a performance optimization? Also related issue #8115 |
Like @svick, I'm sceptical of the real need for this. How often do you really encounter such classes without being able to access the source and thus fix them by making them implement Having said that, if there is a real-world case for having to do what you describe, then your proposal seems a neat way of dealing with it by both controlling the scope of |
There are already some language features that help: public class MyFile
{
public string Path => "Path";
public void Close() => Console.WriteLine("closed");
}
public class Disposable<T> : IDisposable
{
public T Item { get; }
private readonly Action<T> cleanup;
public Disposable(T item, Action<T> cleanup)
{
this.Item = item;
this.cleanup = cleanup;
}
public void Dispose()
=> this.cleanup(this.Item);
}
public static class Disposable
{
public static Disposable<T> Create<T>(T item, Action<T> cleanup)
=> new Disposable<T>(item, cleanup);
}
using (var d = Disposable.Create(new MyFile(), f => f.Close())) {
Console.WriteLine($"Path: {d.Item.Path}");
}
using static Disposable;
using (var d = Create(new MyFile(), f => f.Close())) {
Console.WriteLine($"Path: {d.Item.Path}");
} IMHO there is no need to bake that into the language. Of course you can come up with a better name than |
Maybe Otherwise I'm voting down because this is super rare in my experience. The existence of a It also leads to people writing
|
This gives me an idea. The 'using' statement is too rigidly coupled to the interface IUsing : IDisposable { And a helper class public class Using { public static class Using { } and a simple if naive use case using static Using; using (var file = MakeUsable(new MyFile(), f => f.Close()){ it would be more useful to be done like IUsing OpenFile(string path) => and using (var myFile = OpenFile("c:\passwords")){ And for those that say this is an anti pattern. Often with windowing Now this is very similar to what you suggested but the using statement On Sat, Apr 9, 2016 at 4:17 PM Matthias Dittrich notifications@github.com
|
This windowing Close method is not about disposal. It is appropriately named. Close in order to dispose of resources as a synonym for Dispose is the anti-pattern. Also whether it's Close or Dispose does not matter much. It should only be one of them, though. |
What is a "resource" ? On Sun, 10 Apr 2016 19:17 GSPP, notifications@github.com wrote:
|
Something that is a significant cost to the system while it is not disposed. When disposed it permanently transitions to a destroyed state and stops being a cost. I think this is what everyone intuitively understands to be a resource. A window that can be reopened is not a resource. It's a two state system that can be transitioned arbitrarily. Destroying a window is a permanent relief of resources. That's disposal. |
No. A "resource" at least as far as the "using" concept is concerned is just a simple state machine for a common pattern. The pattern is that the code performs action "A", enters a scope and must execute action "B" when it exits the scope to maintain correctness when it exits. When it enters the scope some data is provided that is only valid within that scope. Within that definition you are free to do what you want. There is no requirement that anything must occupy "significant" resources. What does significant mean anyway? That it automatically respects the IDisposable interface is an implementation detail. There is no requirement that the "using" statement cannot infer the same start -> execute_with_data ->stop pattern from other contextual information. I don't think TransactionScope fits your definition of resource. It is more about correctness rather than disposing of something taking up significant resources. |
TransactionScope's resource is the transaction it's working with which must be committed when the scope exits. |
My point exactly. It has nothing to do with system resources or memory or On Mon, 11 Apr 2016 07:52 Henning Moe, notifications@github.com wrote:
|
This is circular reasoning. @bradphelan, |
I think I misunderstood a bit what was being talked about, and I was misunderstood as well. It does not matter, moving on. I think the issues brought up in this ticket are totally valid but so far no solution is known that should actually make it into the language, IMHO. If you really care about scoping you can apply this solution (which I would not do because it decreases code quality I think):
Can we add a |
Rx has some great I proposed #11420 which would allow for the C# compiler to consider instance methods if the target type does not implement public class MyFile {
public string Path { get; };
public void Close();
}
public static class MyFileExtensions {
public static void Dispose(this MyFile file) {
file.Close();
}
}
using(var file = new MyFile("c:\temp\foo.txt")){
// Do stuff with file
} |
We are now taking language feature discussion in other repositories:
Features that are under active design or development, or which are "championed" by someone on the language design team, have already been moved either as issues or as checked-in design documents. For example, the proposal in this repo "Proposal: Partial interface implementation a.k.a. Traits" (issue 16139 and a few other issues that request the same thing) are now tracked by the language team at issue 52 in https://github.com/dotnet/csharplang/issues, and there is a draft spec at https://github.com/dotnet/csharplang/blob/master/proposals/default-interface-methods.md and further discussion at issue 288 in https://github.com/dotnet/csharplang/issues. Prototyping of the compiler portion of language features is still tracked here; see, for example, https://github.com/dotnet/roslyn/tree/features/DefaultInterfaceImplementation and issue 17952. In order to facilitate that transition, we have started closing language design discussions from the roslyn repo with a note briefly explaining why. When we are aware of an existing discussion for the feature already in the new repo, we are adding a link to that. But we're not adding new issues to the new repos for existing discussions in this repo that the language design team does not currently envision taking on. Our intent is to eventually close the language design issues in the Roslyn repo and encourage discussion in one of the new repos instead. Our intent is not to shut down discussion on language design - you can still continue discussion on the closed issues if you want - but rather we would like to encourage people to move discussion to where we are more likely to be paying attention (the new repo), or to abandon discussions that are no longer of interest to you. If you happen to notice that one of the closed issues has a relevant issue in the new repo, and we have not added a link to the new issue, we would appreciate you providing a link from the old to the new discussion. That way people who are still interested in the discussion can start paying attention to the new issue. Also, we'd welcome any ideas you might have on how we could better manage the transition. Comments and discussion about closing and/or moving issues should be directed to #18002. Comments and discussion about this issue can take place here or on an issue in the relevant repo. I am not moving this particular issue because I don't have confidence that the LDM would likely consider doing this. |
Currently it is painful to adapt classes to the using statement. If I have a class
I can't use it in a using statement because it isn't IDisposable but the Close method is probably the one I am interested in. Normally I would do
There are two problems above. file is scoped too wide. I would have to add another layer of noisy brackets. The other is the noisy Disposable.Create. My proposal is that for objects that do not implement IDisposable we add an overload for using.
or just pass the method group
The text was updated successfully, but these errors were encountered: