您的位置:首页 > 编程语言 > C#

C#泛型编程指导原则(五)

2007-09-14 13:53 190 查看

Item 5: Genericize Types That Vary Only by a Data Type将由数据类型引起变化的类型泛型化

如果你通读以下自己代码中现存的类、方法、接口、委托,你会发现,自己一般会使用一个类型所包含/管理的类型来定义它。在这些情况下,需要考虑是否要应用泛型,从而可以使一个单独的实现就可以为多种数据类型提供服务。在这样的场景下应用泛型可以产生一系列的积极作用,包括减少代码的大小,提高类型安全性等等。
一.消除冗赘的数据容器:
迄今为止,数据容器是用来进行泛型重构的最通用、最直接的领域之一。大多数的解决方案至少有一或两个这样的例子:为了向ArrayList的安全性妥协,你创建了自己的类型安全的包装类。
如:
public class PersonCollection
{
private ArrayList _persons;
public PersonCollection()
{
_persons = new ArrayList();
}
public void Add(Person person)
{
_persons.Add(person);
}
public Person this[int index]
{
get { return (Person)_persons[index]; }
}
}

public class OrderCollection
{
private ArrayList _orders;
public OrderCollection()
{
_orders = new ArrayList();
}
public void Add(Order order)
{
_orders.Add(order);
}
public Order this[int index]
{
get { return (Order)_orders[index]; }
}
}
这两个类封装了一个ArrayList,向客户提供了一个类型安全的接口,他们是进行泛型重构的极好候选者。这两个类,除了管理的数据类型不同外,就没有什么不同的了。
通过使用泛型集合Collection<T>可以同时获得类型安全和上述两个类提供的功能性。具体我们只要使用Collection<Person> 和Collection<Order>就行了。
如果你的候选类提供的功能没有被Collection<T>所直接支持,只需要简单的创建一个Collection<T>的子类,在其中加入新的自定义成员就可以了。
二.定义候选方法:
为了进行泛型重构而寻找候选方法,是很细小琐碎而又缺少精确性的科学。最常见的例子就是:一些方法在整个对象上执行了相当基本的操作,没有调用任何特别的方法。
如:
public static void Swap(ref String val1, ref String val2)
{
String tmpObj = val2;
val2 = val1;
val1 = tmpObj;
}
public static void Swap(ref Double val1, ref Double val2)
{
Double tmpObj = val2;
val2 = val1;
val1 = tmpObj;
}
如果有多个类型的数据要进行交换时,为了获得类型安全、避免对值类型进行装箱,需要提供一系列的overloaded方法。
如果使用Object类型作为参数的话,将引起一系列的问题,同时这样做也违背了条款2。
最好的方法就是使用泛型。如下所示:
public static void Swap<T>(ref T val1, ref T val2)
{
T tmpObj = val2;
val2 = val1;
val1 = tmpObj;
}

三.用一个泛型委托替换多个委托
泛型委托的引入在根本上改变了应该在何时、如何创建自己的委托。委托代表了泛型最根本、最自然的应用中的一种。
如,非泛型委托是这样的:
public delegate void MyDel1(int x, string y);
public delegate void MyDel2(int x, double y);
public delegate void MyDel3(int x, long y);
public delegate void MyDel4(int x, string y, double z);
public delegate void MyDel5(int x, double y, double z);
通过使用委托,可以使其大大简化:
public delegate void MyDel<T, U>(T x, U y);
public delegate void MyDel<T, U, V>(T x, U y, V z);
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: