我们都知道,在C#中,对于复杂对象,每声明一个牸类型的变量a,并用个该类型的对象A给这个变量赋值的时候,其实是让这个变量a指向了对象A,在内存中并没有多生成一个对象A的实例.所以不管我们声明多少个等于A的变量,其实际上永远都只有一个A存在于内存中.这就是我们常说的引用类型的特性.
引用类型的这一特性的好处是不言无喻的,然而,它也给我们带了一小点不便,那就是有时候,偶尔我们需要在内存中有两个所有属性值都一模一样的对象A和B,这样便于对B做操作而不影响到A.有人说那New两次不就有两个一模一样的对象了吗,其实,他没有考虑到在实际的操作过程中,对象A可能因为用户的操作,一些属性被改变了.New出来的对象只能确保初始状态类型和属性的一致性,对于运行时改变的属性它就无能为力了.也就是说,此时,我们得克隆一个A对象,把当前A对象的所有属性值取到新对象中去,这样就能保证当前两个对象的一致性.看代码吧:
/// <summary> /// 克隆一个对象
/// </summary> /// <param name="o"></param> /// <returns></returns> private object CloneObject(object o) { Type t =o.GetType(); PropertyInfo[] properties =t.GetProperties(); Object p =t.InvokeMember("", System.Reflection.BindingFlags.CreateInstance, null, o, null); foreach(PropertyInfo pi in properties) { if(pi.CanWrite) { object value=pi.GetValue(o, null); pi.SetValue(p, value, null); } } return p; }
调用代码生成新的一模一样的对象就很方便了,示例:
TextBox t =(TextBox)CloneObject(textBox1);
当然,在实际使用的过程中,我发现上面的方法也是有缺陷的,比如在克隆DataGridView对象的时候,SetValue的时候会报错,其中的原因还有待分析.不过我们还有更专业的克隆DataGridView的方法:
/// <summary> /// 专门克隆DataGridView的方法 /// </summary> /// <param name="dgv"></param> /// <returns></returns> public static DataGridView CloneDataGridView(DataGridView dgv) { try { DataGridView ResultDGV = new DataGridView(); ResultDGV.ColumnHeadersDefaultCellStyle = dgv.ColumnHeadersDefaultCellStyle.Clone(); DataGridViewCellStyle dtgvdcs = dgv.RowsDefaultCellStyle.Clone(); dtgvdcs.BackColor = dgv.DefaultCellStyle.BackColor; dtgvdcs.ForeColor = dgv.DefaultCellStyle.ForeColor; dtgvdcs.Font = dgv.DefaultCellStyle.Font; ResultDGV.RowsDefaultCellStyle = dtgvdcs; ResultDGV.AlternatingRowsDefaultCellStyle = dgv.AlternatingRowsDefaultCellStyle.Clone(); for (int i = 0; i < dgv.Columns.Count; i++) { DataGridViewColumn DTGVC = dgv.Columns[i].Clone() as DataGridViewColumn; DTGVC.DisplayIndex = dgv.Columns[i].DisplayIndex; if (DTGVC.CellType == null) { DTGVC.CellTemplate = new DataGridViewTextBoxCell(); ResultDGV.Columns.Add(DTGVC); } else { ResultDGV.Columns.Add(DTGVC); } } foreach (DataGridViewRow var in dgv.Rows) { DataGridViewRow Dtgvr = var.Clone() as DataGridViewRow; Dtgvr.DefaultCellStyle = var.DefaultCellStyle.Clone(); for (int i = 0; i < var.Cells.Count; i++) { Dtgvr.Cells[i].Value = var.Cells[i].Value; } if (var.Index % 2 == 0) Dtgvr.DefaultCellStyle.BackColor = ResultDGV.RowsDefaultCellStyle.BackColor; ResultDGV.Rows.Add(Dtgvr); } return ResultDGV; } catch (Exception ex) { MessageBox.Show(ex.Message); } return null; }
现在就没有遗憾了.
※※※※※※※※※※※※※※--我的程序人生--※※※※※※※※※※※※※※