Creating Methods

Creating Methods

The next step in coding is to divide your code into methods . Methods are members of classes that hold code and can be called to execute that code. We've already seen how to write and work with the Main method, so this idea should be somewhat familiar. Here's how you declare a method in C#:

 [  attributes  ] [  modifiers  ]  type identifier  ([[out][ref]  type parameter  , [[out][ref]  type parameter  , ...]])  statement  

Here are the parts of this declaration:

  • attributes (Optional) Hold additional declarative information, as we'll see in Chapter 14, "Using Attributes and Reflection."

  • modifiers (Optional) The allowed modifiers are new , static , virtual , abstract , override , and a valid combination of the four access modifiers we'll see in the next chapter.

  • type The return type of the method.

  • identifier The method name .

  • parameter A parameter passed to the method.

  • statement The statement(s) that make up the body of the method.

Let's take a look at an example. Like the Main method, you can simply add another method to a class. This new method is called DisplayMessage , and, when called, simply displays the customary greeting:

 class ch02_07 {  void DisplayMessage()   {   System.Console.WriteLine("Hello from C#.");   }  static void Main()   {     .     .     .   } } 

That was simple enough. Unfortunately, actually calling DisplayMessage from the code executing in the Main method is a little trickier. It's tricky because Main is declared static so that C# doesn't have to create an object to call Main . However, the new method, DisplayMessage , is not static, so you do need an object to call it. We can solve this problem by creating a new object of the entire class (that's ch02_07 here) and calling the DisplayMessage method of that object, as you see in Listing 2.7 (Chapter 3 covers the difference between static and non-static class members in depth).


Methods in C# are like methods in C++, except that they can use ref and out keywords, can use attributes, and do not support default values. See the upcoming "For C++ Programmers" sidebars for more information.

Listing 2.7 Creating a Method (ch02_07.cs)
 class ch02_07 {   void DisplayMessage()   {     System.Console.WriteLine("Hello from C#.");   }   static void Main()   {  ch02_07 obj = new ch02_07();   obj.DisplayMessage();  } } 

Now when you run ch02_07, you see that the method was indeed called, because you see the message:

 C:\>ch02_07 Hello from C#. 

Passing Data to Methods

You can also pass data to methods. There are a few differences here between C# and C++ as well, in order to avoid the use of pointers and enable you to avoid having to initialize variables before passing them by reference.

You pass arguments to methods as in other languagesas a comma-separated listand you must declare those arguments and their types in the argument list of the method when you declare that method. You can see an example in ch02_08.cs, Listing 2.8, where the DisplayMessage method is passed one argument, which holds the text the method should display.

Listing 2.8 Passing Data to a Method (ch02_08.cs)
 class ch02_08 {  void DisplayMessage(string text)   {   System.Console.WriteLine(text);   }  static void Main()   {     ch02_08 obj = new ch02_08();  obj.DisplayMessage("Hello from C#.");  } } 

This example gives you the same output as ch02_07.cs.


The terms argument and parameter are used interchangeably these days. Some programmers say that arguments are the placeholders you list when you declare a method; others say those are the parameters. This book doesn't make a distinction.

Returning Data from Methods

Besides passing data to methods, you can also return data, of course, and you use the return statement for that purpose. Here's what that looks like:

 return [  expression  ]; 


In C#, method arguments cannot have default values.

If the return type of a method is void , you can omit a return statement. You can only return single values, although that value can be an array or other collection. Here's an example, a method named Addem , which takes two int values and returns their sum as a long :

 long Addem(int value1, int value2) {   return value1 + value2; } 

You can see this method at work in Listing 2.9, where Addem is used to add 2 and 3.

Listing 2.9 Returning Data from a Method (ch02_09.cs)
 class ch02_09 {  long Addem(int value1, int value2)   {   return value1 + value2;   }  static void Main()   {     ch02_09 obj = new ch02_09();  System.Console.WriteLine("2 + 3 = {0}", obj.Addem(2, 3));  } } 

Here's what you see when you run ch02_09:

 C:\>ch02_09 2 + 3 = 5 

Passing Data By Reference

If you pass a reference object, like an array, to a method, C# will pass that reference, which means you can change the values in the original object. For example, take a look at ch02_10.cs in Listing 2.10. It passes an array whose elements are 1, 2, and 3 to a method named ChangeElement , which changes the last element to 4. Because arrays are passed by reference, we have access to the original, passed array, so ChangeElement changes the last element in that array as well.


C# uses ref and out instead of pointers to pass value types by reference, as discussed in this section.

Listing 2.10 Passing an Array (ch02_10.cs)
 class ch02_10 {  void ChangeElement(int[] passedArray)   {   passedArray[2] = 4;   }  static void Main()   {     ch02_10 obj = new ch02_10();     int[] array1 = {1, 2, 3};  obj.ChangeElement(array1);   System.Console.WriteLine("array1[2] = {0}", array1[2]);  } } 

Here are the results. As you can see, the last element was indeed changed to 4:

 C:\>ch02_10 array1[2] = 4 

That works if you pass reference types, but not if you pass value types. For example, if you simply passed an integer to a method and wanted that method to fill that integer with a value accessible back in the calling code, you'd have to indicate that you want to pass that integer by reference. You can do so with the ref keyword (which C# uses so you don't have to pass a pointer to the item you're passing by reference).

You can see an example in ch02_11.cs, Listing 2.11. This example passes an integer by reference to a method named GetTemperature , which places the current temperature into that integer:

 obj.GetTemperature(ref temperature); 

Note the ref keyword hereyou must use it in the method declaration as well as when you pass the integer variable (making the formal type of that argument ref int ), as you see in Listing 2.11.

Listing 2.11 Passing a Value Type by Reference (ch02_11.cs)
 class ch02_11 {  void GetTemperature(ref int temp)   {   temp = 32;   }  static void Main()   {     ch02_11 obj = new ch02_11();     int temperature = 0;  obj.GetTemperature(ref temperature);   System.Console.WriteLine(   "The current temperature is = {0}", temperature);  } } 

Here's what you see when you run this code:

 C:\>ch02_11 The current temperature is = 32 

Note that because you must use a definite assignment in C#, we have to assign a value to the temperature variable in ch02_11.cs before using iteven though it simply needs to be filled with a value from the GetTemperature method:

 int temperature = 0; obj.GetTemperature(ref temperature); 

C# actually provides for this case with the out keyword, which works like ref except that you don't have to initialize an out parameter before passing it to a method. You can see an example in ch02_12.cs, Listing 2.12. Note that in that example, we don't have to initialize temperature before passing it to the GetTemperature method. This example gives you the same results as ch02_11.

Listing 2.12 Passing a Value Type As an out Argument (ch02_12.cs)
 class ch02_12 {  void GetTemperature(out int temp)  {     temp = 32;   }   static void Main()   {     ch02_12 obj = new ch02_12();  int temperature;   obj.GetTemperature(out temperature);  System.Console.WriteLine(       "The current temperature is = {0}", temperature);   } } 

So, you can pass value items by reference with the ref keyword, and you can avoid having to initialize them before passing them if you use the out keyword. (Technically speaking, value items you pass by value are called "in" parameters, although there is no in keyword for this purpose.)

Passing a Variable Number of Arguments

You can also set up methods to accept variable numbers of arguments. Although this functionality has been largely replaced by overloading methods, as we'll see in Chapter 3, it still has its uses. To declare a method so that it can accept a variable number of parameters, you can use a parameter array, which you create with the params keyword. You use this keyword in the declaration of an array in the method's argument list, and that array must be the last item in the argument list (if you mixed the varying number of values intended for the parameter array and standard parameters, C# would have no idea where the parameter array ended).

You can see an example in ch02_13.cs, Listing 2.13. Here, the Addem method is set up to add valuesyou pass it the number of integer values you want to add, followed by the actual integers to add. As you can see, you can call this method with a variable number of arguments. In the method itself, you need only to loop over the passed parameter array:

 System.Console.WriteLine("1 + 2 = {0}", obj.Addem(2, 1, 2)); System.Console.WriteLine("1 + 2 + 3 = {0}", obj.Addem(3, 1, 2, 3)); long Addem(int numberParams, params int[] paramArray) {   for(int loopIndex = 0; loopIndex < numberParams; loopIndex++){       total += paramArray[loopIndex];   }   .   .   . } 


Note that it wasn't necessary to pass the actual number of parameters in the parameter array to Addem (in fact, it would have been far easier to loop over that array with a foreach statement). This example uses this approach simply to emphasize that the parameter array need not be the only item you can pass when passing multiple parameters.

Listing 2.13 Passing a Variable Number of Arguments (ch02_13.cs)
 class ch02_13 {  long Addem(int numberParams, params int[] paramArray)   {   int total = 0;   for(int loopIndex = 0; loopIndex < numberParams; loopIndex++){   total += paramArray[loopIndex];   }   return total;   }  static void Main()   {     ch02_13 obj = new ch02_13();  System.Console.WriteLine("1 + 2 = {0}", obj.Addem(2, 1, 2));   System.Console.WriteLine("1 + 2 + 3 = {0}", obj.Addem(3, 1, 2, 3));  } } 

Here's what you see when you run this example:

 C:\>ch02_13 1 + 2 = 3 1 + 2 + 3 = 6 


Now that we're dividing our code into methods, scope becomes an issue. As you know, an identifier's scope is its region of visibility in your code. We'll discuss this more in Chapter 3 when we discuss object-oriented programming, because OOP is largely about scoping issues, but it's an issue when writing methods as well.

For example, a variable that you declare in a methoda local variable like total in the Addem method in Listing 2.13is not available to the code in other methods unless you make special provisions. In fact, this is one of the major reasons to create methods: to compartmentalize your code. If you declare a variable outside any method (making it a field of the enclosing class, as we'll discuss in the next chapter), that variable is available to the code in any of the class's methods. You can see an example of this in ch02_14.cs, Listing 2.14. In this case, the variable text is declared outside any method, making it available to the code in all methods. In this example, the code in Main and DisplayMessage accesses this variable.

Listing 2.14 Setting a Field's Scope (ch02_14.cs)
 class ch02_14 {  string text;  void DisplayMessage()   {  System.Console.WriteLine(text);  }   static void Main()   {     ch02_14 obj = new ch02_14();  obj.text = "Hello from C#.";  obj.DisplayMessage();   } } 


It's also worth noting briefly that C# supports recursion , the capability of a method to call itself. The usual example showing recursion is a factorial program (for example, factorial(6) = 6! = 6 x 5 x 4 x 3 x 2 x 1 = 720 ), and you can see our factorial program in ch02_15.cs, Listing 2.15. This example calculates and displays the value of 6! . Note in particular that to find the value of x ! , the factorial method calls itself to get the value of (-- x )! .

Listing 2.15 Using Recursion (ch02_15.cs)
 class ch02_15 {  long factorial(int value)   {   if(value == 1){   return 1;   } else {   return value * factorial(--value);   }   }  static void Main()   {     ch02_15 obj = new ch02_15();  System.Console.WriteLine("6! = {0}", obj.factorial(6));  } } 

Here's what you see when you run this example, where we see that 6! = 720 :

 C:\>ch02_15 6! = 720 

Microsoft Visual C#. NET 2003 Kick Start
Microsoft Visual C#.NET 2003 Kick Start
ISBN: 0672325470
EAN: 2147483647
Year: 2002
Pages: 181

Similar book on Amazon © 2008-2017.
If you may any questions please contact us: