.NET Tip: Returning Mulitple Objects from a Single Method Call

Each method can only return a single value from the method call. What happens when you need to return more information? One solution is for your method to return a complex data type. It could return a struct or an object of a class you define. In many situations this makes sense, especially when you want to return a set of related data. In other instances, however, a complex data type may not really fit what you need or may be overly complex. Another option is to return values through the parameters to the method. By default, parameters are passed by value; this means that your method is not able to change the value of the parameter and pass it back to the calling routine. C# has a couple keywords that you can use to change the behavior of how parameters are passed. You can use the ref keyword to indicate that the parameter will be passed by value. This allows your method to modify the value of the parameter and have the calling routine see that change when your method finishes executing. The ref keyword should appear in your method's parameter list before the data type of each parameter that you want to pass by reference. Here is a method that can accept some parameters by reference.

private bool RefParameters(int Input, ref int Output,
                           ref string Message)
{
   Output = Input * 10;
   Message = "Your input value was: " + Input.ToString();
   return true;
}

First, notice that this method has a boolean return value. The method call itself will always return a true value. Second, the method expects three parameters. The first parameter is an integer that is passed by value so it cannot be changed by the method. The next two parameters are an integer and string that are each passed by reference. Because both these parameters have the ref keyword, they can be modified during the execution of the method and any changes will be reflected back in the calling routine. The body of the method should be strightforward. It assigns new values to the Output and Message parameters before returning true from the method call. Here is an example of calling the above method.

bool ReturnValue    = false;
int IntInput        = 5;
int IntOutput       = 1;
string StringOutput = "Initial Text";

Debug.Print(String.Format("Initial Values:\r\nReturnValue:
   {0}\r\nIntInput:
   {1}\r\nIntOutput:
   {2}\r\nStringOutput:
   {3}\r\n", ReturnValue, IntInput, IntOutput, StringOutput));
ReturnValue = RefParameters(IntInput, ref IntOutput,
                            ref StringOutput);
Debug.Print(String.Format("New Values:\r\nReturnValue:
   {0}\r\nIntInput:
   {1}\r\nIntOutput:
   {2}\r\nStringOutput:
   {3}\r\n", ReturnValue, IntInput, IntOutput, StringOutput));

A variable to hold the return value of the method is declared and initialized as well as variables to hold the input and output parameters to the method. The call to the method has Debug statements before and after it to print out the values of all the variables. One point to notice is that the ref keyword also must precede all ref parameters in the method call itself. Your code will not compile if you forget to include the ref keyword on a call to a method that has ref paremeters. You can see from the following output that the value of the IntOutput and StringOutput variable have changed after the method call.

Initial Values:
ReturnValue:  False
IntInput:     5
IntOutput:    1
StringOutput: Initial Text

New Values:
ReturnValue:  True
IntInput:     5
IntOutput:    50
StringOutput: Your input value was: 5

If you look at the example calling code, you will notice that the variables passed in as ref parameters have been intialized when they were delcared. The ref keyword requires that any variable passed as a ref parameter be initialized before the method call. As an alternative, you can use the out keyword in the method declaration and method call instead of ref. Parameters that use the out keyword are not required to be initialized before the method call. Other than the initialization requirement, the out and ref keywords have the same behavior.

About the Author

Jay Miller is a Software Engineer with Electronic Tracking Systems, a company dedicated to robbery prevention, apprehension, and recovery based in Carrollton, Texas. Jay has been working with .NET since the release of the first beta and is co-author of Learn Microsoft Visual Basic.Net In a Weekend. Jay can be reached via email at jmiller@sm-ets.com.



Comments

  • No passing by value takes place

    Posted by cjard on 04/29/2008 10:00am

    I'd prefer you explain that "ref" and "out" pass the original pointer to a variable, whereas omitting them passes a copy of the pointer. At no time is data being copied or duplicated. Further, the title of this article is misleading. It does not return multiple objects, it merely leaves your original object pointers pointing to new objects. No "return" keyword is used in conjuction with any of the "returned" objects and you dont have to make an assignment [a=b(ref c);] to retain these "return" values. It is also misleading as to scope of modification. If I pass a StringBuilder to a method that calls .Append("abc") then the StringBuilder will have that text appended when the method completes. You write as though i'd have to use ref or out to retain my change. Changes TO objects are always retained, because passing is always by reference. Changes OF objects are only retained if you reassigned the original point, not a copy as passed by not using ref/out. It would also be nice if you could obey Microsoft's naming conventions for parameter names (camelCase, not PascalCase)

    • Passing by value

      Posted by jaydmiller on 04/29/2008 12:46pm

      When a value type is passed to a method by value a copy of the parameter is passed to the method, not a copy of a pointer. The point of the article is that there are ways other than using "return" to send updated values/objects to the calling method.

      Reply
    Reply
Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • Live Event Date: December 11, 2014 @ 1:00 p.m. ET / 10:00 a.m. PT Market pressures to move more quickly and develop innovative applications are forcing organizations to rethink how they develop and release applications. The combination of public clouds and physical back-end infrastructures are a means to get applications out faster. However, these hybrid solutions complicate DevOps adoption, with application delivery pipelines that span across complex hybrid cloud and non-cloud environments. Check out this …

  • On-demand Event Event Date: October 29, 2014 It's well understood how critical version control is for code. However, its importance to DevOps isn't always recognized. The 2014 DevOps Survey of Practice shows that one of the key predictors of DevOps success is putting all production environment artifacts into version control. In this webcast, Gene Kim discusses these survey findings and shares woeful tales of artifact management gone wrong! Gene also shares examples of how high-performing DevOps …

Most Popular Programming Stories

More for Developers

RSS Feeds