ALL OF THE METHODS WE have designed so far have had a limitation. They can receive information from the caller using parameters, but they can't send any results back to the caller (except through shared member variables). In this section, we'll look at methods that send a value back to their caller.
In an earlier chapter, you learned to call methods that return values. Methods like Math.Sqrt(), Convert.ToInt32(), and String.Substring() all return a value to the calling method. You normally call them in an assignment statement, like this:
double result = Math.Sqrt(weight);
What you haven't seen is how to write methods that do this. It's pretty easy, really. A method can return exactly one value to its caller. To return a value, you specify the data type of the value you want to return in the method interface. Then, inside the method, you use a return statement, which takes the form:
return expression;
A return statement can only occur inside the definition of a method, and the type of the expression must be compatible with the return type that was specified for the method. When the computer executes this return statement, it evaluates the expression, terminates execution of the method, and uses the value of the expression as the returned value of the method.
Let's begin with a method that returns the larger of two numbers.
// returns the larger of <num1> and <num2> static int Max(int num1, int num2) { int result; if (num1 > num2) { result = num1; } else { result = num2; } return result; }
Here is an example of how you might call this method:
int larger = Max(3, 5); // returns 5
When the Max method is called, it determines which of the two parameters is larger, and returns the result. The returned value is sent back to the calling method, where it is (usually) stored in a variable by an assignment statement, as in this sample call.
Here is a method that reverses a string. This method receives a string as parameter, reverses it, and returns the reversed copy. For example, the reverse of "Hello World" is "dlroW olleH". The algorithm for computing the reverse of a string, str, is to start with an empty string and then to append each character from str, starting from the last character of str and working backwards to the first.
// Returns a reversed copy of <str> static string Reverse(string str) { string copy; // The reversed copy. copy = ""; // Start with an empty string. for (int i = str.Length - 1; i >= 0; i-- ) { // Append i-th char of str to copy. copy = copy + str[i]; } return copy; }
A palindrome is a string that reads the same backwards and forwards, such as "radar". The Reverse() method could be used to check whether a string, word, is a palindrome by testing if a word entered by the user is equal to its reverse. Here is a complete program that uses the Reverse method to check for palindromes:
Example 6.2. PalindromeChecker.cs
using System; class PalindromeChecker { static void Main() { Console.Write("Enter a word: "); string word = Console.ReadLine(); word = word.ToUpper(); // ignore capitalization when checking for palindrome if (word == Reverse(word)) { Console.WriteLine(word + " is a palindrome."); } else { Console.WriteLine(word + " is NOT a palindrome."); } } // Returns a reversed copy of <str> static string Reverse(string str) { string copy = ""; // Start with an empty string. for (int i = str.Length - 1; i >= 0; i--) { copy = copy + str[i]; } return copy; } }
The expression used in a return statement doesn't have to be a simple variable. It can be a complex expression involving method calls. Here's an example:
static double Pythagorus(double x, double y) { return Math.Sqrt(x*x + y*y) * 2.0; }
Notice the return type: double. This matches the type of value produced by the expression in the return statement.
Methods may contain more than one return statement. Here is a very simple method that could be used in a program to compute 3N+1 sequences. (The 3N+1 sequence problem is one we've looked at several times already.) Given one term in a 3N+1 sequence, this method computes the next term of the sequence:
static int NextN(int currentN) { if (currentN % 2 == 1) // test if current N is odd return 3*currentN + 1; // if so, return this value else return currentN / 2; // if not, return this instead }
Exactly one of the two return statements is executed to give the value of the method. A return statement can occur anywhere in a method. However, for clarity, it is usually preferable to use a single return statement at the very end of the method. This allows the reader to find the return statement easily. You might choose to write NextN() like this, for example:
static int NextN(int currentN) { int answer; // answer will be the value returned if (currentN % 2 == 1) // test if current N is odd answer = 3*currentN+1; // if so, this is the answer else answer = currentN / 2; // if not, this is the answer return answer; // (Don't forget to return the answer!) }
Inside a void method -- one whose return type is "void" -- you can use a return statement with no expression to immediately terminate execution of the method and return control back to the point in the program from which the method was called. This can be convenient if you want to terminate execution somewhere in the middle of the method.
return statements are optional in void methods. In a non-void method, on the other hand, a return statement, with expression, is always required.