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.
|
|
|