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:

  void Swap<T>(ref T x, ref T y) {    T temp;    temp = x;    x = y;    y = temp; } 

A generic method can be invoked by assigning the generic type with the method call:

  int i = 4; int j = 5; Swap<int>(ref i, ref j); 

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:

  int i = 4; int j = 5; Swap(ref i, ref j); 

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:

  public class Account {    private string name;    public string Name    {       get       {          return name;       }    }    private decimal balance;    public decimal Balance    {       get       {          return balance;       }    }    public Account(string name, Decimal balance)    {       this.name = name;       this.balance = balance;    } } 

All the accounts where the balance should be accumulated are added to an accounts list of type List<Account>:

  List<Account> accounts = new List<Account>(); accounts.Add(new Account("Christian", 1500)); accounts.Add(new Account("Sharon", 2200)); accounts.Add(new Account("Katie", 1800)); 

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:

  public static class Algorithm {    public static decimal AccumulateSimple(IEnumerable e)    {       decimal sum = 0;       foreach (Account a in e)       {          sum += a.Balance;       }       return sum;    } } 

The Accumulate() method is invoked this way:

  decimal amount = Algorithm.AccumulateSimple(accounts); 

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:

 public static decimal Accumulate<TAccount>(IEnumerable<TAccount> coll)       where TAccount : IAccount {    decimal sum = 0;    foreach (TAccount a in coll)    {       sum += a.Balance;    }    return sum; }

The new Accumulate() method can be invoked by defining the Account type as generic type parameter:

  decimal amount = Algorithm.Accumulate<Account>(accounts); 

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:

  decimal amount = Algorithm.Accumulate(accounts); 

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.




Professional C# 2005 with .NET 3.0
Professional C# 2005 with .NET 3.0
ISBN: 470124725
EAN: N/A
Year: 2007
Pages: 427

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net