`

C#中泛型(续)

阅读更多

[2009-3-15]续

参考书:《c#2.0完全自学手册》  《C# 2005 & .NET 3.0高级编程(第5版)

 

4.泛型接口

使用泛型可以定义接口,接口中的方法可以带泛型参数。

如:链表示例中,就执行了IEnumerable<T>接口,它定义了GetEnumerator()方法,以返回IEnumerator<T>

(详见上一博文)

 

对于.NET 1.0中的许多非泛型接口,.NET 2.0都定义了新的泛型版本,如IComparable<T>

 

 

代码:按姓氏给人员排序

 

如果使用非泛型的接口IComparable,则需要强制转换

public class Person : IComparable

{

        public int CompareTo(object obj)

        {

                Person other = obj as Person;    //需要将object类型强制转换成Person

                return this.lastname.CompareTo(other.lastname);

         }

          .....................

} 

 

 

使用泛型版本时,则不再需要将object的类型强制转换为Person

public class Person : IComparable<Person>

{

public int CompareTo(Person other)

return this.lastname.CompareTo(other.lastname);

}

...............

}

 

 

5.泛型方法

在泛型方法中,泛型类型用方法声明来定义

如:

void Swap<T>(ref T x, ref T y)

{

        T temp;

        temp = x;

        x = y;

        y = temp;

}

 

调用:

可以把泛型类型赋予方法调用,就可以调用泛型方法

int i = 4;

int j = 5;

Swap<int>(ref i, ref j);

因为C#编译器会通过调用Swap方法来获取参数的类型,所以不需要把泛型类型赋予方法调用;泛型方法可以像非泛型方法那样调用

int i = 4;

int j = 5;

Swap(ref i, ref j);

 

=============一个使用泛型方法的例子(转载自C# 2005 & .NET 3.0高级编程(第5版) 第9.5节)========

使用泛型方法累加集合中的所有元素

public class Account     //Account 类

{

      private string name;

      private decimal balance;

 

      public string Name

      {

         get

         {

            return name;

         }

      }

     

      public decimal Balance

      {

         get

         {

            return balance;

         }

      }

 

      public Account(string name, Decimal balance)

      {

             this.name = name;

             this.balance = balance;

      }

}

 

 

//应累加结余的所有账目操作都添加到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));

 

//累加所有Account对象的传统方式是用foreach语句迭代所有的Account对象

//foreach语句使用IEnumerable接口迭代集合的元素,所以AccumulateSimple()方法的参数是IEnumerable类型

public static class Algorithm

{

      public static decimal AccumulateSimple(IEnumerable e)

      {

             decimal sum = 0;

             foreach (Account a in e)

            {

                sum += a.Balance;

             }

             return sum;

      }

}

 

//方法的调用:

decimal amount = Algorithm.AccumulateSimple(accounts);

上述实现代码的问题是,只能用于Account对象。而使用泛型方法就可以避免这个问题

Accumulate()方法的第二个版本接受实现了IAccount接口的任意类型。如前面的泛型类所述,泛型类型可以用where子句来限制。这个子句也可以用于泛型方法。

Accumulate()方法的参数改为IEnumerable<T>

IEnumerable<T>是IEnumerable接口的泛型版本,由泛型集合类实现

//泛型方法

public static decimal Accumulate<TAccount>(IEnumerable<TAccount> coll) where TAccount : IAccount

{

         decimal sum = 0;

         foreach (TAccount a in coll)

         {

            sum += a.Balance;

         }

         return sum;

}

 

//将Account类型定义为泛型类型参数,就可以调用新的Accumulate()方法

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

 

//因为编译器会从方法的参数类型中自动推断出泛型类型参数,以如下方式调用Accumulate()方法是有效的

decimal amount = Algorithm.Accumulate(accounts);

 

 ===================================================================

6. 泛型委托  待续。。。。。。。。。:)

 

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics