在大型项目的开发过程中,需要多人协同工作,来加速项目完成进度。
比如一个软件有100个form,分给100个人来写,每个人完成自己的Form.cs的编写之后,要在Mainform调用自己写的Form。
如果按照正常的Form form1 = new Form()这种写法来构造窗口的话,相当于每个人都要改动Mainform.cs文件,这100个人只要有1个人在Mainform中改错代码了,那么该项目就在至关重要的Mainform.cs里埋下了1个bug,这是非常危险的一件事!
所以为了降低编码的耦合性,让每个人只要关心自己的类,不用关心mainform相关的代码,可以用特性加反射的方式来提高程序的健壮性。下面就是一个例子:
BaseForm.cs代码如下:
using System;
using System.Windows.Forms;
namespace WinFormsApp1
{
public enum CusFormType
{
HomePage, // 主页
UserInfoPage, // 员工信息页
LogPage, // 日志页
SettingPage, // 系统设置页
}
public partial class BaseForm : Form
{
public BaseForm() { }
public BaseForm(object par, Func<CusFormType, object, ActionType, BaseForm> func)
{
param = par;
Func = func;
}
public object param;
public Func<CusFormType, object, ActionType, BaseForm> Func { get; set; }
public class FormTypeAttribute : Attribute
{
public CusFormType[] tableType;
public FormTypeAttribute(params CusFormType[] types) //构造函数
{
tableType = types;
}
}
}
}
MainForm.cs代码如下:
//#define HAHA
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Windows.Forms;
using static WinFormsApp1.BaseForm;
namespace WinFormsApp1
{ public enum ActionType
{
New,
Refresh
}
public partial class Mainform : Form
{
Func<CusFormType, object, ActionType, BaseForm> operFunc => FormOper;//Lambda 表达式是与匿名方法类似的内联表达式,但更加灵活;
public Mainform()
{
InitializeComponent();
GetTableTypeDic();
}
public static Dictionary<CusFormType, Type> tableTypeDic = new Dictionary<CusFormType, Type>();
private void GetTableTypeDic()
{
var baseType = typeof(BaseForm);
var allTypes = this.GetType().Assembly.GetTypes().Where(p => !p.IsInterface && baseType.IsAssignableFrom(p)).ToList();//通过反射获取所有继承自BaseForm的类的type
foreach (var item in allTypes)
{
var attrs = item.GetCustomAttributes(typeof(FormTypeAttribute), false);//在派生类中重写时,返回应用于此成员并由System.type标识的自定义属性数组
foreach (var attr in attrs)
{
var curAttr = attr as FormTypeAttribute;
if (curAttr.tableType != null)
{
foreach (var type in curAttr.tableType)
tableTypeDic[type] = item;
}
}
}
}
private BaseForm FormOper(CusFormType tableType, object par, ActionType actionType = ActionType.New)
{
if (tableTypeDic.ContainsKey(tableType))
{
if (actionType == ActionType.New)
{
BaseForm tableForm = null;
{
tableForm = Activator.CreateInstance(tableTypeDic[tableType], new object[] { par, operFunc }) as BaseForm;
tableForm.Text = tableType.ToString();
}
tableForm.Show();
return tableForm;
}
}
return null;
}
private void button1_Click(object sender, EventArgs e)
{
operFunc.Invoke(CusFormType.HomePage, null,ActionType.New);
}
}
}
Form1代码如下:
using System;
namespace WinFormsApp1
{
[FormTypeAttribute(CusFormType.HomePage)]
public partial class Form1 : BaseForm
{
public Form1(object par, Func<CusFormType, object, ActionType, BaseForm> func):base(par,func)
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
Func.Invoke(CusFormType.LogPage,null,ActionType.New);
}
}
}
form2代码如下:
using System;
namespace WinFormsApp1
{
[FormTypeAttribute(CusFormType.LogPage)]
public partial class Form2 : BaseForm
{
public Form2(object par, Func<CusFormType, object, ActionType, BaseForm> func) : base(par, func)
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
Func.Invoke(CusFormType.SettingPage,null,ActionType.New);
}
}
}
form3代码就不用贴出来了,就是随便新建的一个form。