Generic Methods
In addition to defining generic classes, it
is also possible to define generic methods. With a generic method,
the generic type is defined with the method declaration.
The method Swap<T>
defines T as a generic type that is used
for two arguments and a variable temp:
A generic method can be invoked by assigning the
generic type with the method call:
However, because the C# compiler can get the type
of the parameters by calling the Swap
method, it is not required to assign the generic type with the
method call. The generic method can be invoked as simply as
nongeneric methods:
Here’s an example where a generic method is used to
accumulate all elements of a collection. To show the features of
generic methods, the following Account
class that contains a name and a
balance is used:
All the accounts where the balance should be
accumulated are added to an accounts list of type List<Account>:
A traditional way to accumulate all Account objects is by looping through all
Account objects with a foreach statement, as shown here. Because the
foreach statement is using the
IEnumerable interface to iterate the
elements of a collection, the argument of the AccumulateSimple() method is of type IEnumerable. This way, the AccumulateSimple() method can be used with all
collection classes that implement the interface IEnumerable. In the implementation of this method,
the property Balance of the Account object is directly accessed:
The Accumulate() method
is invoked this way:
The problem with the first implementation is that
it works only with Account objects. This
can be avoided by using a generic method.
The second version of the Accumulate() method accepts any type that implements
the interface IAccount. As you’ve seen
earlier with generic classes, generic types can be restricted with
the where clause. The same clause that
is used with generic classes can be used with generic methods. The
parameter of the Accumulate() method is
changed to IEnumerable<T>.
IEnumerable<T> is a generic
version of the interface IEnumerable
that is implemented by the generic collection classes:
The new Accumulate()
method can be invoked by defining the Account type as generic type parameter:
Because the generic type parameter can be
automatically inferred by the compiler from the parameter type of
the method, it is valid to invoke the Accumulate() method this way:
The requirement for the generic types to
implement the interface IAccount may be
too restrictive. This requirement can be changed by using generic
delegates. In the next section, the Accumulate() method will be changed to be
independent of any interface.