3 ms·
C# has the using-statement + IDisposable which is similar context managers in python (except no __enter__). C#8 then allowed using-statements that do not requi
by rndgermandude 6y ago
C# has the using-statement + IDisposable which is similar context managers in python (except no __enter__).
C#8 then allowed using-statements that do not require blocks, which then are disposed when leaving the current block.
Pre C#8, you had to have a block, similar to how with-statement requires a block aka indentation
using (var res = OpenSomeResource()) {
res.doSomething();
// res.Dispose() implicitly called
}
Now you can have this (which is a bit like a go-style Defer but for blocks)
using var res = OpenSomeResource();
res.doSomething();
// res.Dispose() implicitly called at end of current block
Of course, you have to take the potentially longer lifetime into account. This way looks a lot like C++s RAII with constructors and destructors (except the destructor here is the IDisposible.Dispose implementation).
- arcticbull 6y agoIt's basically what all variables in Rust do, with customizable destruction by implementing the Drop trait.
- toxik 6y agoInteresting, I think that would make sense for Python. def do_thing(): with open('foo', 'r') as f with a_lock f.read() frobnicate() I guess the issue is that there is less of a clear idea of scope in Python, what does the above construct do at a module level? What does it do inside another with block? A lot of special rules that don't conveniently fit into something else unlike what I suppose C# has.
- Asooka 6y agoYou can get that syntax right now using ExitStack.
- toxik 6y agoYou can get something in that general area yes. This is actually vaguely reminiscent of auto release pools in Cocoa.
- nurbl 6y agoWouldn't it be more natural to do this sort of thing with decorators?
- Groxx 6y agoFor trivial examples, sure. And there are a lot of those in practice, so it definitely applies sometimes. But decorators aren't really usable when you have any intermediate steps that need to be done, like def do_thing(): with a_lock check_f_cache_while_locked() # like this with open('foo', 'r') as f populate_cache(f)