ref & out Keyword - Modern C# Standards and Conventions

This article is part of a series describing Modern C# Standards and Conventions. A list of the other articles in this series can be found below.

Contents

If you feel there is something else that should be included here, please drop a comment below, or better yet send me a PR.

ref Keyword

There is an awful lot of confusion on this subject, whether that be incorrectly relating the ref keyword (ByVal/ByRef in VB) to value vs. reference types, or the actual behaviour the ref keyword provides. As such, I want to start by clarifying what this keyword does, test your understanding of it’s usage, and the provide some tips on when it should, and should not be used.

Behaviour

The ref keyword is used to pass an argument by reference, as opposed to by value. This means that changes made to the parameter in the called method are reflected in the calling method. This can be done regardless of whether the parameter is a value or reference type, so the two are related only by similar naming.

Understanding

Here is a really simple test showing the ref keyword in use:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
private static void TestCase()
{
	var a = new List<string> { "Foo" };
	var b = a;
	PassByRef(ref b);

	a.ForEach(Console.WriteLine);
	b.ForEach(Console.WriteLine);
}

private static void PassByRef(ref List<string> c)
{
	c.Add("Bar");
	c = new List<string> { "Cheesecake!" };
}

The question is, what do you think is output to the Console? Have a guess, and then throw the code into Visual Studio and see for yourself. If it is not what you expect, you most definitely should not be using the ref keyword.

Even if you do, bear in mind that far fewer people, for better or for worse, do not understand the repercussions of using ref. Do you really need to use ref, or are you bastardising code because you can’t be bothered to write it properly?

When to use

Almost never. You may be forced to use this keyword if you are working across native boundaries or with a poorly written dependency, but otherwise I recommend avoiding it.

Do not use ref because your method needs to return more than one result! Return an object that contain members for each result.

out keyword

In many respects similar to the ref keyword, the out keyword allows a method to return a result as a method argument as opposed to a return type. Unlike the ref keyword, any value assigned to an out parameter by the calling method is not available to the called method.

Also like the ref keyword, I recommend against using them. They are common place in .Net when you look at various TryParse methods, but personally I would have preferred a construct be used (similar to Nullable<T>, if not Nullable<T> itself) which is returned in place of bool + out T.

We can’t change .Net, and the uproar that replacing the TryParse methods would ensue means they’re here to stay. But it doesn’t mean we need to continue making their mistakes.

For example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public static Nullable<int> TryParse(string s)
{
  int result;
  if (int.TryParse(s, out result))
    return result;
  return null;
}

private void Consumer(string userInput)
{
  // to demonstrate usage of the above method
  var parsedInput = TryParse(userInput);
  if (parsedInput.HasValue)
    actUpon(parsedInput.Value);
}

Next

The next article in this series is Scoping.

Written on August 4, 2015