digg.png delicious.png blinkit.png furl.png
C# for Programmers, 2/e

© 2006
pages: ~1350

Amazon logo

This is the second in a series of three articles that shows how to declare and use generic methods in the C# programming language. In Part 1, we introduced the concept of generics. In this article, we present an example using overloaded methods to motivate the need for generic methods. In Part 3, we reimplement the overloaded methods from the example in this article using a single generic method. These articles are intended for students who are already familiar with C# and for C# developers. Download the code examples for this tutorial here.

[Note: This series of three articles (Part 1, Part 2, Part 3) is an excerpt (Sections 25.1–25.3) of Chapter 25, Generics, from our book C# for Programmers, 2/e. These articles may refer to other chapters or sections of the book that are not included here. Permission Information: Deitel, Harvey M. and Paul J., C# FOR PROGRAMMERS, ©2005, pp.1115–1120. Electronically reproduced by permission of Pearson Education, Inc., Upper Saddle River, New Jersey.]

Part 2: Motivation for Generic Methods
Overloaded methods are often used to perform similar operations on different types of data. To motivate generic methods, let's begin with an example (Fig. 26.1) that contains three overloaded PrintArray methods (lines 23-29, lines 32-38 and lines 41-47). These methods display the elements of an int array, a double array and a char array, respectively. Soon, we will reimplement this program more concisely and elegantly using a single generic method.
Fig. 26.1 Displaying arrays of different types using overloaded methods.
1   // Fig. 25.1: OverloadedMethods.cs
2   // Using overloaded methods to print arrays of different types.
3   using System;
5   class OverloadedMethods
6   {
7      static void Main( string[] args )
8      {
9         // create arrays of int, double and char
10        int[] intArray = { 1, 2, 3, 4, 5, 6 };
11        double[] doubleArray = { 1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7 };
12        char[] charArray = { 'H', 'E', 'L', 'L', 'O' };
14        Console.WriteLine( "Array intArray contains:" );
15        PrintArray( intArray ); // pass an int array argument
16        Console.WriteLine( "Array doubleArray contains:" );
17        PrintArray( doubleArray ); // pass a double array argument
18        Console.WriteLine( "Array charArray contains:" );
19        PrintArray( charArray ); // pass a char array argument
20      } // end Main
22      // output int array
23      static void PrintArray( int[] inputArray )
24      {
25         foreach ( int element in inputArray )
26            Console.Write( element + " " );
28         Console.WriteLine( "\n" );
29      } // end method PrintArray
31      // output double array
32      static void PrintArray( double[] inputArray )
33      {
34         foreach ( double element in inputArray )
35            Console.Write( element + " " );
37         Console.WriteLine( "\n" );
38      } // end method PrintArray
40      // output char array
41      static void PrintArray( char[] inputArray )
42      {
43         foreach ( char element in inputArray )
44            Console.Write( element + " " );
46         Console.WriteLine( "\n" );
47      } // end method PrintArray
48   } // end class OverloadedMethods

Array intArray contains: 1 2 3 4 5 6 Array doubleArray contains: 1.1 2.2 3.3 4.4 5.5 6.6 7.7 Array charArray contains:
The program begins by declaring and initializing three arrays-six-element int array intArray (line 10), seven-element double array doubleArray (line 11) and five-element char array charArray (line 12). Then, lines 14-19 output the arrays.
When the compiler encounters a method call, it attempts to locate a method declaration that has the same method name and parameters that match the argument types in the method call. In this example, each PrintArray call exactly matches one of the PrintArray method declarations. For example, line 15 calls PrintArray with intArray as its argument. At compile time, the compiler determines argument intArray's type (i.e., int[]), attempts to locate a method named PrintArray that specifies a single int[] parameter (which it finds at lines 23-29) and sets up a call to that method. Similarly, when the compiler encounters the PrintArray call at line 17, it determines argument doubleArray's type (i.e., double[]), then attempts to locate a method named PrintArray that specifies a single double[] parameter (which it finds at lines 32-38) and sets up a call to that method. Finally, when the compiler encounters the PrintArray call at line 19, it determines argument charArray's type (i.e., char[]), then attempts to locate a method named PrintArray that specifies a single char[] parameter (which it finds at lines 41-47) and sets up a call to that method.
Study each PrintArray method. Note that the array element type (int, double or char) appears in two locations in each method-the method header (lines 23, 32 and 41) and the foreach statement header (lines 25, 34 and 43). If we replace the element types in each method with a generic name-we chose E to represent the "element" type-then all three methods would look like the one in Fig. 26.2. It appears that if we can replace the array element type in each of the three methods with a single "generic type parameter," then we should be able to declare one PrintArray method that can display the elements of any array. The method in Fig. 26.2 will not compile, because its syntax is not correct. We declare a generic PrintArray method with the proper syntax in Fig. 26.3.
Fig. 26.2 PrintArray method in which actual typenames are replaced by convention with the generic name E
1   static void PrintArray( E[] inputArray )
2   {
3      foreach( E element in inputArray )
4         Console.Write( element + " " );
6      Console.WriteLine( "\n" );
7   } // end method PrintArray
Tutorials in This Series:
Introduction to Generics in C#
Motivation for Generic Methods (You are here.)
Generic Method Implementation

Tutorial Index