Passing by 'ref' - Implications for Coupling, Encapsulation, etc

S

Smithers

Say we have private List<Thing>MethodA() that calls MethodB.

As MethodA() executes, it adds items to a List<Thing> instance that is
ultimately returned to its caller.

MethodB() also accumulates Thing items as it does its work, and adds them to
a List<Thing>.

At the end of the day, MethodA needs to return a List<Thing> that includes
the Thing items accumulated from both MethodA() and MethodB().

There are at least a couple of ways to make this happen...

Alternative #1 -- MethodA passes its List<Thing> instance to MethodB by
reference ('ref').

Alternative #2 -- Method B returns a List<Thing> that MethodA then
..AddRanges to its own List<Thing>.

Question:
Which of the above alternatives would be considered as "better" in a general
sense, for this sort of scenario, and why?

Is passing by 'ref' generally frowned upon in cases where it is not
necessary?

Thanks for your consideration.
 
P

Peter Duniho

Smithers said:
[...]
At the end of the day, MethodA needs to return a List<Thing> that includes
the Thing items accumulated from both MethodA() and MethodB().

There are at least a couple of ways to make this happen...

Alternative #1 -- MethodA passes its List<Thing> instance to MethodB by
reference ('ref').

Passing by-reference is unnecessary. Since the reference itself is
passed, even when the parameter is by-value, MethodB can add things to
the List said:
Alternative #2 -- Method B returns a List<Thing> that MethodA then
..AddRanges to its own List<Thing>.

Question:
Which of the above alternatives would be considered as "better" in a general
sense, for this sort of scenario, and why?

Either is fine (ignoring, of course, the incorrect suggestion that
passing by-reference is necessary). Which to choose would, IMHO, depend
on how you need to use MethodB elsewhere, if at all.

If MethodB will only ever be used when there's an existing List<Thing>
instance to add stuff to, then I'd say just pass that instance reference
in and let MethodB party on it.

If, on the other hand, you may have situations in which the collection
MethodB generates may be the only items of interest and it might be
desirable to have MethodB create the List<Thing> instance itself, then
requiring MethodA to append the returned list to its own list is
perfectly fine as well.

Finally, the above assumes that MethodB is closely coupled to MethodA
and/or other callers and can be trusted to only "do the right thing".
Having MethodB generate a list and return it is safe, however, in that
MethodB can't modify someone else's list. Depending on your design, you
might find the #2 method preferable, for this reason.
Is passing by 'ref' generally frowned upon in cases where it is not
necessary?

Define "necessary". This isn't about passing by-reference anyway, and
that's a completely different question. But certainly passing
references as parameters is not considered a bad thing to do.

Pete
 
K

KWienhold

Say we have private List<Thing>MethodA() that calls MethodB.

As MethodA() executes, it adds items to a List<Thing> instance that is
ultimately returned to its caller.

MethodB() also accumulates Thing items as it does its work, and adds them to
a List<Thing>.

At the end of the day, MethodA needs to return a List<Thing> that includes
the Thing items accumulated from both MethodA() and MethodB().

There are at least a couple of ways to make this happen...

Alternative #1 -- MethodA passes its List<Thing> instance to MethodB by
reference ('ref').

Alternative #2 -- Method B returns a List<Thing> that MethodA then
.AddRanges to its own List<Thing>.

Question:
Which of the above alternatives would be considered as "better" in a general
sense, for this sort of scenario, and why?

Is passing by 'ref' generally frowned upon in cases where it is not
necessary?

Thanks for your consideration.

You wouldn't actually need to pass your List<Thing> using the "ref"
keyword, unless MethodB need to be able to create a new instance of
List<Thing> in its place and pass that back to MethodA.
Since List<T> is a reference type anyways, all changes made to it in
MethodB will be visible from MethodA as well.
However, given your scenario, I would probably go with MethodB return
its own List<Thing> since this leads to looser coupling and you won't
have to wonder what MethodB did to the list when you go through
MethodA.
Its largely up to personal preference I guess, given how many of
the .Net types are reference types and how useful passing by reference
can be, I certainly would not say it is a frowned upon.

hth,
Kevin Wienhold
 
S

Smithers

RE:
<< This isn't about passing by-reference anyway, and that's a completely
different question.>>

Doh! (ala Homer Simpson)... I seem to have completely forgotten the
difference between value types and reference types... and the implications
for 'ref' Sheesh!

'scuse me while I get back to work... er maybe I should take a break.

-S


Peter Duniho said:
Smithers said:
[...]
At the end of the day, MethodA needs to return a List<Thing> that
includes the Thing items accumulated from both MethodA() and MethodB().

There are at least a couple of ways to make this happen...

Alternative #1 -- MethodA passes its List<Thing> instance to MethodB by
reference ('ref').

Passing by-reference is unnecessary. Since the reference itself is
passed, even when the parameter is by-value, MethodB can add things to the
List said:
Alternative #2 -- Method B returns a List<Thing> that MethodA then
..AddRanges to its own List<Thing>.

Question:
Which of the above alternatives would be considered as "better" in a
general sense, for this sort of scenario, and why?

Either is fine (ignoring, of course, the incorrect suggestion that passing
by-reference is necessary). Which to choose would, IMHO, depend on how
you need to use MethodB elsewhere, if at all.

If MethodB will only ever be used when there's an existing List<Thing>
instance to add stuff to, then I'd say just pass that instance reference
in and let MethodB party on it.

If, on the other hand, you may have situations in which the collection
MethodB generates may be the only items of interest and it might be
desirable to have MethodB create the List<Thing> instance itself, then
requiring MethodA to append the returned list to its own list is perfectly
fine as well.

Finally, the above assumes that MethodB is closely coupled to MethodA
and/or other callers and can be trusted to only "do the right thing".
Having MethodB generate a list and return it is safe, however, in that
MethodB can't modify someone else's list. Depending on your design, you
might find the #2 method preferable, for this reason.
Is passing by 'ref' generally frowned upon in cases where it is not
necessary?

Define "necessary". This isn't about passing by-reference anyway, and
that's a completely different question. But certainly passing references
as parameters is not considered a bad thing to do.

Pete
 

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

Top