在修改旧项目的时候,发现代码有一些重复,于是做了一点修改。

重复代码其实也有好处,就是写的时候很快,复制粘贴,管它是否冗余,先搞出来,看到成果再说。但如果涉及到修改调整,就比较痛苦了,要修改2次,甚至多次。

我是见不得重复代码的,尽管复用部分不多,也尽量将公共部分提取出来。还用到了委托和泛型,极尽奇淫技巧,写完还自鸣得意,觉得自己做一个程序员,肯定是够格的。

重复代码如下:

1、代码1

c#使用委托 + 泛型,编写可复用代码_泛型

2、代码2

c#使用委托 + 泛型,编写可复用代码_delegate_02

代码结构是一样的,就是中间不同,而且操作的数据类型也不同。对于这种情况,可以使用委托 + 泛型来书写可复用代码。委托用于应对不同的操作,泛型用于不同的数据类型。委托特别适合于上下代码相同,唯独中间部分不同的情况,将函数通过参数传递方式传入,我谓之曰注入式开发。

//声明一个泛型委托
delegate void DlgAddItem<T>(T list, string unitName);

//委托1
DlgAddItem<List<ChartSerie>> dlgChartAddItem = (List<ChartSerie> list, string unitName) =>
{
list.Add(new ChartSerie()
{
name = unitName,
datas = new List<ChartPoint>()
});
};
//委托2
DlgAddItem<List<Tj_Hl_Szyb_Table>> dlgTableAddItem = (List<Tj_Hl_Szyb_Table> list, string unitName) =>
{
list.Add(new Tj_Hl_Szyb_Table()
{
NAME = unitName,
});
};

//将委托作为参数传递
private T getFullData<T>(T lis, string selUnits, List<string> names, DlgAddItem<T> dlg)
{
/*
* 可能由于某些预报单位没有数据,而没有包含在查找结果中,
* 这里将用户指定的所有预报单位都补上,便于前端直观展示,
*/
string[] arrUnits = selUnits.Split(',');
foreach (string unit in arrUnits)
{
if (unit.IndexOf("选择") >= 0) continue;
if (!names.Contains(unit))
{
dlg(lis, unit);
}
}

return lis;
}

使用

//使用1
data = getFullData(data, request.selUnits,
data.Select(s => s.name).ToList(), dlgChartAddItem)
.OrderBy(s => s.order).ToList();

//使用2
listAll = getFullData(listAll, request.selUnits, listAll.Select(s => s.NAME).ToList(),
dlgTableAddItem);

不过,加入委托后,我感觉是代码可读性变差了。原因是委托稍显复杂。我始终难以记住委托的格式,写的时候需要频频查找资料。