-
We are dealing now with Stride3D code, where they have a pattern of this: try
{
using (var stream = objectDatabase.OpenStream(objectId)) /// NOTE: 'OpenStream' THROWS if objectId not found
{
// process stream
}
return true; // success
}
catch { return false; } Because they want to have this "using" statement, they are using "exceptions" for normal program flow. It's actually, in many cases OK for the 'objectId' to be missing from the database, in which case we just return 'false' (for failure), and so is not an "error". ==
Part of the goal here is to keep the "using(...)" clause - because it's sexy. But I don't see how we can continue with the "using()" clause in a manner that won't use "exceptions for program flow". For example, here's the ONLY way I can think for rewriting the above, to avoid Exceptions for Program Flow, but does NOT include the "Using(...)" clause: try
{
var stream = objectDatabase.OpenStream(objectId));
if (stream == null)
return false;
// process stream....
return true; // success
}
catch { } // handle UNEXPECTED Exceptions that may never happen.
finally { stream?.Dispose(); } So this 2nd snippet avoids using "exceptions for program flow", but also does not make use of sexy/desired "using(...)" clause. ==
NOTE: When Exceptions are used for normal program flow, it makes it difficult to manage when you have "Break on Exceptions" turned on, for sake of discovering ACTUAL BUGS fast (rather than continuing to break again and again for normal program flow!). This is our conundrum -- so am seeking advice if there is a way to satisfy both sides of this tug-of-war...? |
Beta Was this translation helpful? Give feedback.
Replies: 3 comments 13 replies
-
Yes.
You can use the Null Object pattern to deal with situations like this, meaning you return an object where every operation is a no-op. The BCL provides |
Beta Was this translation helpful? Give feedback.
-
If you'd like a language feature to support this there's precedence for a "null-aware using" feature in the vein of null-aware await: #35. Null-aware using would (assumedly) look like this: using? var disp = GetSomeDisposableThing();
// code or using? (var disp = GetSomeDisposableThing())
{
// code
} which would differ from regular |
Beta Was this translation helpful? Give feedback.
-
|
Beta Was this translation helpful? Give feedback.
ObjectDatabase
has anExists
method, you should be checking that in your program flow rather than relying on an exception being thrown. If you want a single call that checks and returns a sentinel value in the case that the ID doesn't exist, you can write an extension method.