现有如下一方法需要进行扩展。x与y可能不只是加,需要增加减、乘、除。
private Double Plus(Double x, Double y) { Double results = x + y; //把x y写入数据库 写入日志等等操作 return results * 1000; }
大家会很容易想到加一个type参数,根据不同场景传入不同的type,或者写多个方法,根据不同场景进行不同调用。先来看看这两种方案的实现。
方案一:
#region 一个方法 带类型参数 private Double Arithmetical(Double x, Double y, String type) { Double results = 0; { switch (type) { case "+": results = x + y; break; case "-": results = x - y; break; case "*": results = x * y; break; case "/": results = x / y; break; default: results = 0; break; } } { //if (type == "+") // results = x + y; //else if (type == "-") // results = x - y; //else if (type == "*") // results = x * y; //else if (type == "/") // results = x / y; //else
// results = 0; } //把x y写入数据库 写入日志等等操作 return results * 1000; } #endregion
方案二:
#region 多个方法 private Double Plus(Double x, Double y) { Double results = x + y; //除了这行其他都是重复代码 //把x y写入数据库 写入日志等等操作 return results * 1000; } private Double Minus(Double x, Double y) { Double results = x - y; //把x y写入数据库 写入日志等等操作 return results * 1000; } private Double Multiply(Double x, Double y) { Double results = x * y; //把x y写入数据库 写入日志等等操作 return results * 1000; } private Double Divide(Double x, Double y) { Double results = x / y; //把x y写入数据库 写入日志等等操作 return results * 1000; } #endregion
两种方案虽然都能实现本文一开始提出的需求,但各个方法都有美中不足。方案一的扩展性是较差的,要是以后需要先加减等等情况,那就只能再去修改方法。而方案二扩展性相对较好,只需要再增加一个方法,但是每个方法都会写很多重复代码。有没有能把相同代码进行封装而方法又是可扩展的方案呢?于是有了委托,接下来看看委托如何解决。
#region 委托 #region 自己声明委托 //delegate Double del(Double x, Double y); // 1. 声明委托 方法签名需要一致 //private Double delCalculate(Double x, Double y, del del) //{ // Double results = del.Invoke(x, y); //4. 使用委托中的方法 // //把x y写入数据库 写入日志等等操作 // return results * 1000; //} #endregion #region 使用func委托 private Double delCalculate(Double x, Double y, Func<Double, Double, Double> del) { Double results = del.Invoke(x, y); //4. 使用委托 //把x y写入数据库 写入日志等等操作 return results * 1000; } #endregion #region 委托需要的方法 private Double delPlus(Double x, Double y) //2. 写委托需要用到的方法 { return x + y; } private Double delMinus(Double x, Double y) { return x - y; } private Double delMultiply(Double x, Double y) { return x * y; } private Double delDivide(Double x, Double y) { return x / y; } #endregion #endregion
注释了的代码是声明一个返回Double类型带两个都为Double类型参数名为del的委托,声明的写法和方法很相似,但委托是一个类。后面代码使用了Func,Func是一个最多可以有十六个参数且带返回值的委托,它与上面已经注释的del是一样的。与Func相对的是Action,Action是一个最多可以带十六个参数的无返回值委托。Func与Action都是.Net提供的委托,使用它们用户可以省去自己声明委托的代码。相信大家很明显的可以看出这里除了有带委托的方法,同样声明了四个分别操作加减乘除的方法,委托的作用是把方法做参数进行传递然后调用方法。在本文还是需要额外声明方法的,但是每个方法的方法体只有少量代码。相比方案一,方案三扩展性强;相比方案二,方案三重复代码大大减少。最后含委托的方法使用如下:
Func<Double, Double, Double> delplus = new Func<double, double, double>(delPlus);// 3. 实例化委托
//Func<Double, Double, Double> delplus = delPlus; Console.WriteLine(delCalculate(10, 5, delplus)); Func<Double, Double, Double> delminus = new Func<double, double, double>(delMinus); Console.WriteLine(delCalculate(10, 5, delminus)); Func<Double, Double, Double> delmultiply = new Func<double, double, double>(delMultiply); Console.WriteLine(delCalculate(10, 5, delmultiply)); Func<Double, Double, Double> deldivide = new Func<double, double, double>(delDivide); Console.WriteLine(delCalculate(10, 5, deldivide));
效果图:
对于方案三有更加好的代码实现,委托加Lambda。方案三进阶