最近在做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接口的名字了,代码可扩展。

posted on 2010-05-09 15:35  Read  阅读(887)  评论(3编辑  收藏  举报