DekGenius.com
[ Team LiB ] Previous Section Next Section

Recipe 3.22 Returning Multiple Items from a Method

Problem

In many cases, a single return value for a method is not enough. You need a way to return more than one item from a method.

Solution

Use the out keyword on parameters that will act as return parameters. The following method accepts an inputShape parameter and calculates height, width, and depth from that value:

public void ReturnDimensions(int inputShape, 
                             out int height, 
                             out int width, 
                             out int depth)
{
    height = 0;
    width = 0;
    depth = 0;

    // Calculate height, width, depth from the inputShape value
}

This method would be called in the following manner:

// Declare output parameters
int height;
int width;
int depth;

// Call method and return the height, width, and depth
Obj.ReturnDimensions(1, out height, out width, out depth);

Another method is to return a class or structure containing all the return values. The previous method has been modified to return a structure instead of using out arguments:

public Dimensions ReturnDimensions(int inputShape)
{
    // The default ctor automatically defaults this structure's members to 0
    Dimensions objDim = new Dimensions( );

    // Calculate objDim.Height, objDim.Width, objDim.Depth from the inputShape value

    return (objDim);
}

where Dimensions is defined as follows:

public struct Dimensions
{
    int Height;
    int Width;
    int Depth;
}

This method would now be called in this manner:

// Call method and return the Height, Width, and Depth
Dimensions objDim = obj.ReturnDimensions(1);

Discussion

Marking a parameter in a method signature with the out keyword indicates that this parameter will be initialized and returned by this method. This trick is useful when a method is required to return more than one value. A method can, at most, have only one return value, but through the use of the out keyword, we can mark several parameters as a kind of return value.

To set up an out parameter, the parameter in the method signature is marked with the out keyword, shown here:

public void ReturnDimensions(int inputShape, 
                             out int height, 
                             out int width, 
                             out int depth)
{
    ...
}

To call this method, we must also mark the calling method's arguments with the out keyword, shown here:

obj.ReturnDimensions(1, out height, out width, out depth);

The out arguments in this method call do not have to be initialized; they can simply be declared and passed in to the ReturnDimensions method. Regardless of whether they are initialized before the method call, they must be initialized before they are used within the ReturnDimensions method. Even if they are not used through every path in the ReturnDimensions method, they still must be initialized. That is why this method starts out with the following three lines of code:

height = 0;
width = 0;
depth = 0;

You may be wondering why you couldn't use a ref parameter instead of the out parameter, as they both allow a method to change the value of an argument marked as such. The answer is that an out parameter makes the code somewhat self-documenting. You know that when an out parameter is encountered, this parameter is acting as a return value. In addition, an out parameter does not require the extra work to be initialized before it is passed in to the method, which a ref parameter does.

The out parameter was originally designed for marshaling scenarios. An out parameter does not have to be marshaled when the method is called; rather, it is marshaled once when the method returns the data to the caller. Any other type of call (by-value or by-reference) requires that the value be marshaled in both directions. Using the out keyword in marshaling scenarios improves performance.


    [ Team LiB ] Previous Section Next Section