每当有人谈到c#反射,总有人说用这个效率不高,我大部分时间在c和c++中度过,c#少用,但是还是很感兴趣,最近公司使用c#做一个客户端,有一个朋友已经写了很多代码,模块很多,感觉反复写同样的东西,但其实却又没有多少可以提取的东西,业务关联性不大,我们仔细研究了一下,经典的三层结构,没有什么好改动,数据库数据已经提取到实体,在界面上反复赋值,关键在于,有上百个界面。
例如以下实体类代码:
public class EntityMan
{
public string Name { get; set; }
public int Age { get; set; }
public string Address { get; set; }
public string Kind { get; set; }
public int PersonID { get; set; }
}
假设在逻辑层已经有了这样一个函数:
public EntityMan GetEntity()
{
EntityMan man = new EntityMan();
man.Age = 12;
man.Address = "东大街25号";
man.Kind = "黄种人";
man.Name = "王晓宇";
man.PersonID = 110;
return man;
}
EntityMan man = GetEntity();
因为界面要展示每个字段,又没有使用其他控件,我们是把很多textbox搬了上去,于是代码中充斥了像这样的赋值:
FormX.Tb_Text.Text = man.Name;
Formx.Tb_TextAge.Text =int.Parse( man.Age);
........................
太多了,应为数据库实际的字段确实很多,而这样的界面又很多,then ,做了这样一个改造,注意红体:
private void bu_OK_Click(object sender, EventArgs e)
{
EntityMan man = GetEntity();
PropertyInfo[] properties = typeof(EntityMan).GetProperties();
for (int i = 0; i < properties.Length; i++)
{
string fn = properties[i].Name;
PropertyInfo pinfo= typeof(EntityMan).GetProperty(fn);
object obj = pinfo.GetValue(man,null);
string Value = obj.ToString();
string ControlName = "tb_"+fn;
System.Windows.Forms.Control c = gB.Controls[ControlName];
if (c != null)
{
int n = int.Parse(c.Tag.ToString());
switch (n)
{
case 0:
(c as TextBox).Text = Value;
break;
case 1:
(c as ComboBox).Text = Value;
break;
case 2:
break;
}
}
}
}
首先利用了反射机制获取了实体的每个属性,再次利用反射获取对象关于该属性的值,接下去,界面上的textBox或者combobox等名字等于 tb_ + 属性名,
ok,再次利用c#中的 tag 属性来定义 该control的类型,为了框架集中的控件较为迅速地找到,我们把所有控件放入名为gB的groupbox中,将获取的值赋值到该控件中,
点击确定后,实体对象的值被赋值到了控件中。
这样做的好处是每个窗体都可以使用这个代码,不过需要改造,类型EntityMan 不是固定的,而是各种不同的实体,其反射损失的效率和项目节省的时间来讲是值得的。
在属性值很多的情况下,窗体弹出后可以启动线程去赋值,也可以使用遮罩层屏蔽,其实我们在测试过程中,没有感觉到时间的延时,在有30个属性的实体类来讲,点击
按钮后所有textbox值已经全部被赋值,消耗的时间实际上是因为远程读取数据库和中间的逻辑层复杂性造成的,因此这不失为一个好的方法。
程序示例代码已经上传
http://download.csdn.net/detail/qianbo_0423/3651698