3 ms·
C# has a using block that makes resource deallocation explicit syntax, which I far prefer to implicit destructor behaviour. That said, we need IDEs that sound
by zzalpha 9y ago
C# has a using block that makes resource deallocation explicit syntax, which I far prefer to implicit destructor behaviour.
That said, we need IDEs that sound the klaxons if a Closeable is not placed in a using statement.
- maxxxxx 9y agoI find the using syntax pretty ugly especially once you have several objects. Some keyword like "autodispose" may help. Managed C++ has this. Objects that are allocated with the stack syntax get disposed at the end of the scope.
- zzalpha 9y agoAgain, that creates implicit behaviours that can be extremely surprising. You can deal with multiple Closeables by enhancing syntax. But tying deallocation to disposal creates action at a distance that I'm really not a fan of, personally. Resource allocation and deallocation can take time, can block, and can fail. Those semantics make them a terrible fit for constructors and destructors.
- btschaegg 9y agoAs a counterpoint to this: - Making it explict has the two distinct problems that a) the code for it must be written each time (I regularly encounter code that ignores Disposables) and b) is closed to change (adding a dispose semantics to a class essentially creates bugs throughout your codebase). Those two, I deem far worse than a destructor that is blocking. - On the C++ side: If you encapsulate the resource properly, you're not really binding the two together (at least on one level of abstraction), since you're basically just managing a handle. Note that it is also really easy to split both up (by introducing some NULL-handle) and only dispose the resource in the destructor if it hasn't been disposed yet (of course, that is more bug-prone, but so is IDisposable). - With move semantics (or std::swap before C++11) this also allows you to dispatch "cleanups" to other contexts, if necessary, which gives you exactly the same possibilities where necessary (of course, this also being explicit in those cases). - Failed resource allocations in constructors should not be a problem (either use exceptions or NULL-handles). - Failed resource deallocations are a problem in any implementation I know of and likely not "conquered" easily in the near future. So, to sum it up, I think C++ gives you the better tooling because you can design the appropriate API yourself. C#'s implementation is very set in it's way and has a couple of problems that would be nice to avoid (e.g. the "you can't free resources in a finalizer" thing). I'd prefer an API that does the right thing by default (albeit slow) and lets me optimize where needed instead of one that has little benefit (for most scenarios) but makes the code more error-prone. That means essentially: If you implement IDisposable in C++ and dispose in the destructor where necessary, you get the best of both approaches. The remaining arguments that then can be made against C++ are either bad code, abstraction problems and/or cumbersome libraries.
- seanmcdirmid 9y agoThere are plenty of cases where Disposables are used in non-simple scopes enabled by using statements, and where it is better to call dispose explicitly rather than using an explicit using statement.
- zzalpha 9y agoNo doubt, though I would argue those are the exception rather than the rule... which is why it should be an ignorable warning, preferably requiring a code annotation to turn it off. But it absolutely be something a modern IDE should flag as a potential error (IntelliJ, for example, has whole classes of these types of inspections for Java, Kotlin, etc).
- seanmcdirmid 9y agoIf the false positive rate was even just 1 or 2%, it might be too noisy to warn about. Perhaps an annotation to opt out would be more apt.