using

  • Thread starter Thread starter cronusf
  • Start date Start date
C

cronusf

Consider the following code:

using(StreamReader fin = new StreamReader(filename))
{
// do work with fin

return ReferenceToSomeObjectBasedOnLoadedData();
}

Since using expands to a try/finally, am I correct that the finally
code (which calls fin.Dispose()) will be called even if the return
statement is hit?
 
Consider the following code:
using(StreamReader fin = new StreamReader(filename))
{
// do work with fin

return ReferenceToSomeObjectBasedOnLoadedData();
}

Since using expands to a try/finally, am I correct that the finally
code (which calls fin.Dispose()) will be called even if the return
statement is hit?

Yes, but IMO it's usually better to return things "normally" (at the end of
the function usually which would eliminate the above confusion). It's
similar to using a "return" statement in a loop, or applying multiple return
statements in a method. While most would disagree that it's "bad" (since
most do it regularly), it's cleaner for every method to have one exit point
and usually not inside a construct like a loop or even the above. Note that
this is a rule-of-thumb only. Legitimate arguments can sometimes be made
against this advice.
 
Larry Smith said:
Yes, but IMO it's usually better to return things "normally" (at the end of
the function usually which would eliminate the above confusion). It's
similar to using a "return" statement in a loop, or applying multiple return
statements in a method. While most would disagree that it's "bad" (since
most do it regularly), it's cleaner for every method to have one exit point
and usually not inside a construct like a loop or even the above. Note that
this is a rule-of-thumb only. Legitimate arguments can sometimes be made
against this advice.

In my experience there are *so* many exceptions to this rule, it's not
even worth having it as a loose rule any more. Back in C when error
handling was a lot harder, it made more sense - but with try/finally
and using statements, GC etc it can very often make the code *much*
simpler to read if you just return as soon as you know the answer.

Sticking to a single point of return often introduces a new local
variable and explicit loop breaking rules (which get more complicated
the more loops there are to break out of) when just a single return
statement gets the job done immediately - and makes it clear to the
reader that you *are* finished.
 
In my experience there are *so* many exceptions to this rule, it's not
even worth having it as a loose rule any more. Back in C when error
handling was a lot harder, it made more sense - but with try/finally
and using statements, GC etc it can very often make the code *much*
simpler to read if you just return as soon as you know the answer.
Sticking to a single point of return often introduces a new local
variable and explicit loop breaking rules (which get more complicated
the more loops there are to break out of) when just a single return
statement gets the job done immediately - and makes it clear to the
reader that you *are* finished.

I disagree. The principle has always been sound though not absolute. This
has changed very little and it's not just a matter of error-handling (your
point presumably being that because resource deallocation is now decoupled
and automatic, we can safely return from anywhere and therefore it's ok to
do so - this notwithstanding your other points). Nevertheless, I did add the
caveat that it's a rule-of-thumb only. It's not a pedantic cause on my part
IOW since some of your points have merit (which I've considered myself over
the years). On the whole I still disagree however but counter-arguing is
really off-topic.
 
Larry Smith said:
I disagree. The principle has always been sound though not absolute.

But what's the reason for it? You claim it's "cleaner" but with no
justification. I claim it's cleaner to write code in the most obvious
manner - so when I know what the return value for a method should be
and I don't actually need to do any more work, the most obvious thing
to do is return. Why would I want to go through hoops to reach the
lexical end of the method? Where's the benefit?

I could give you plenty of examples where it's simpler to have multiple
exit points, and I suspect you'd say that they're all exceptions to the
rule. Can you give an example where the simplest working code would use
multiple return points, but you believe it's cleaner to strive for a
single one?
This has changed very little and it's not just a matter of
error-handling (your point presumably being that because resource
deallocation is now decoupled and automatic, we can safely return
from anywhere and therefore it's ok to do so - this notwithstanding
your other points)

Not just error handling - anything else you might want to do as you
exit the method, such as logging, resource cleanup etc. Without the
support of finally blocks etc, it was hard to make sure you could
perform all that exit work for every return point. Now there's no such
justification.
Nevertheless, I did add the caveat that it's a rule-of-thumb only.
It's not a pedantic cause on my part IOW since some of your points
have merit (which I've considered myself over the years). On the
whole I still disagree however but counter-arguing is really
off-topic.

The problem is that I've seen lots code that suffered from this
rule-of-thumb being applied - code which was considerably simpler when
refactored to return from multiple places. On the other hand, I've seen
*very* little code which was actually confusing just because it exited
in multiple places.

Add to this the fact that due to exceptions almost *any* method
actually has multiple exit points that the developer should be aware of
anyway.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Back
Top