Avoid out Parameters

 

C# has the out parameter modifier allowing us to pass value types by reference.

First, let’s check out how arguments are passed by value without the out keyword.

Method GetCustomerName() takes two string parameters:  

  public void GetCustomerName(string firstName, string lastName)
  {
     firstName = "Fred";
     lastName = "Flintstone";
  }

Let’s call GetCustomerName() with a preset firstName and lastName in a unit test:

  var firstName = "Barney";
  var lastName = "Rubble";

  GetCustomerName(firstName, lastName);

  firstName.Should().Be("Barney");  // PASSES!
  lastName.Should().Be("Rubble");   // PASSES!

The firstName and lastName variable content remains the same. When passing these strings by value makes a copy of the parameters inside the GetCustomerName(). Variables firstName and lastName are changed inside the scope of GetCustomerName() only yet remain “Barney” and “Rubble” outside of it. 

OK, let’s use the out parameter modifier keyword:

  void GetCustomerName(out string firstName, out string lastName)
  {
     firstName = "Fred";
     lastName = "Flintstone";
  }

Our unit test code now changes to

  var firstName = "Barney";
  var lastName = "Rubble";

  GetCustomerName(out firstName, out lastName);

  firstName.Should().Be("Fred");       // PASSES!
  lastName.Should().Be("Flintstone");  // PASSES!

The out keyword has changed the operation of GetCustomerName(). Setting firstName and lastName to “Fred” and “Flintstone” inside GetCustomerName() also modifies the variable outside the method because we no longer pass a copy—we are using the same variables.  

So far, so good—that is how the out parameter modifier works.

 

However, we should avoid creating out parameters on our methods.

Why?

They are unexpected and unnecessary. 

 

Method GetCustomerName() is a query function—it requests data. The conventional way to return the data from a query function is via the return value. Returning data via the values that we passed into the method is novel and unexpected. We should try to avoid programming in ways that will confuse and make our programmer colleagues pause. 

Fair enough. So, we should return the data via a return value, like this:

  var name = GetCustomerName();

and GetCustomerName() returns the data via a composite return value CustomerName:

  public class CustomerName
  {
     public string FirstName { get; }
     public string LastName { get; }

     public CustomerName(string firstName, string lastName)
     {
        FirstName = firstName;
        LastName = lastName;
     }
  }
  public CustomerName GetCustomerName(string firstName, string lastName)
  {
     return new CustomerName("Fred", "Flintstone");
  }

The FirstName and LastName properties can then be accessed on the return value using the property getters as shown in the string format expression below:

  var name = $"{name.FirstName} {name.LastName}";

Nice—that works well.

 

To recap, avoid out parameters if possible – and it is always possible. I haven’t written a method featuring an out parameter in a decade or more. The out parameter keyword is a programming construct that is not necessary—you’re better off returning a composite object. Just because C#, or any language, provides you with the ability to do something doesn’t mean it’s always a good idea.

0 replies

Leave a Reply

Want to join the discussion?
Feel free to contribute!

Leave a Reply