最近在做codereview时看到两个方法写的非常的相似,除了操作的类型不一样,别的都是一样的。就想着将这两个方法合并成一个方法,提高代码的复用率。
先将背景交代下:
有两个类:
public class Dog
{
public string Name { get; set; }
}
public class Cat
{
public string Name { get; set; }
}
现在有一个需求,要求将Dog和Cat的名字打印出来,写两个方法,分别用于打印Dog和Cat的名字:
//打印Dog的名字
public static void PrintDogName(Dog dog)
{
Console.WriteLine(dog.Name);
}
//答应Cat的名字
public static void PrintCatName(Cat cat)
{
Console.WriteLine(cat.Name);
}
需要完成打印名字的工作时,实例化Dog和Cat,再分别调用两个方法来打印名字:
static void Main(string[] args)
{
//实例化Dog
Dog Spot = new Dog() { Name = "WangWang" };
//实例化Cat
Cat Persian = new Cat() { Name = "Mimi" };
//打印Dog实例的Name
PrintDogName(Spot);
//打印Cat实例的Name
PrintCatName(Persian);
}
在做codereview的时候,发现这两个方法是如此的相似,只有处理的类型不一样。在这个示例中可以这样合并:
//本示例的合并方法
public static void PrintName(string name)
{
Console.WriteLine(name);
}
下面用泛型方法来将这两个方法合并成一个方法,来提高代码复用:
public static void PrintName<T>(T t)
{
//打印的是Dog
if (t is Dog)
{
Console.WriteLine((t as Dog).Name);
return;
}
//打印的是Cat
if (t is Cat)
{
Console.WriteLine((t as Cat).Name);
return;
}
//打印的既不是Dog也不是Cat
Console.WriteLine("This method only support Dog and Cat.");
}
这种方法是把方法合并成一个了,但总的代码量没有减少。只是把原来两个方法里的代码拿到一个方法里来了,后来又想了一种合并的方法,步骤如下:
首先将Dog类和Cat类抽象出一个接口来:
//包含名字属性的接口
interface IName
{
string Name { get; set; }
}
Dog和Cat类都要继承这个接口:
//Dog类继承了IName接口
public class Dog : IName
{
public string Name { get; set; }
}
//Cat类继承了IName接口
public class Cat:IName
{
public string Name { get; set; }
}
现在重写这个泛型方法:
//限制泛型必须实现IName接口
public static void PrintName<T>(T t)where T:IName
{
Console.WriteLine(t.Name);
}
这样方法体内的代码就不用重复了,而且将来要打印任何继承IName接口的名字了,代码可扩展。