18

Actually I am doing a list as a reference parameter as follows:

public static List ListMethod(List result)

I saw some people doing in this way too:

public static void ListMethod(ref List result)

If I'm not wrong, "my" method also takes the list as reference parameter, and you should be able to use it just the same way as "other" does in his method.

But it seems more "clean" to me that you enter a parameter, do something with it and return it in the methods return value.

Any good arguments for or against one method or the other?

Otiel
  • 18,404
  • 16
  • 78
  • 126
Developer
  • 8,390
  • 41
  • 129
  • 238
  • It's a list? why send it by ref what is it that you're trying to achieve? – Chen Kinnrot Nov 21 '11 at 09:11
  • 3
    With out passing as ref/out, internally a reference pointing to heap copy is made in stack and that is passed to the callee method. If used ref, the same reference is used as passing argument. – Zenwalker Nov 21 '11 at 09:11
  • 1
    Why do you think you need to return a `List` in your first method and not return anything in the second? – BoltClock Nov 21 '11 at 09:12
  • Of course, if the list itself is just being mutated then neither the return or ref is needed. However, if you assign a completely new list to the parameter, then either a return or ref is needed for the callee to see the change. However, as has been explained below, there are differences between return and ref even if the net result appears to be the same. – Adam Houldsworth Nov 21 '11 at 09:15
  • 1
    This simple example should make u understand http://pastebin.com/sm8niPRD same as what jon skeet says. – Zenwalker Nov 21 '11 at 09:16

4 Answers4

36

It's likely that you don't need to use ref - but there is a difference.

Usually when I see people using ref for reference type parameters, it's because they don't understand how parameter passing works. But if your method has something like this:

result = new List();
...

then in the first case the caller won't see the change, whereas in the second case the caller's variable will be changed to refer to the new object.

See my article on parameter passing for a lot more detail.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
14

No, your method does not use a ref parameter. The default is pass by value.

The difference is, that your method can just modify the contents of your list but not the reference the parameter result points to.

Whats the best approach? It depends on what your method is supposed to do.

When your method modifies the list or returns new data you should use the return value. Its much better to understand what your code does than using a ref parameter.

Another benefit of return values is the ability to use method chaining.

You can write code like this which passes the list parameter from one method to another:

ListMethod1(list).ListMethod2(list)...
Jan
  • 15,802
  • 5
  • 35
  • 59
  • 3
    +1 for the ability to do method chaining. You can even do that *and* modify a parameter as well, if you really want to; a `return result;` isn't very expensive in terms of either LOC, CPU or complexity, and can make life a lot easier for the function consumer. – user Nov 21 '11 at 13:30
4

If you're just returning a List, you should always use the first one as it shows that intention.

The version with ref tells me that I can start out with a list, and your method will modify the list I sent in, or even change it with another one. If that is your intention, do that.

But if the method allways returns a new list, use a return value instead of a ref parameter.

A note on the side: you could use out instead of ref to show your intentions of returning a new list, but this is only a good practice if you're using the return value for something else.

Arjan Einbu
  • 13,543
  • 2
  • 56
  • 59
1

One thing special about ref Parameter here is that - "A variable passed with ref must be assigned value first.". So if you want to make it strict for the calling method to assign value before the call you can probably use ref Parameters.

Jsinh
  • 2,539
  • 1
  • 19
  • 35