C#引用类型克隆(转)

我们都知道,在C#中,对于复杂对象,每声明一个牸类型的变量a,并用个该类型的对象A给这个变量赋值的时候,其实是让这个变量a指向了对象A,在内存中并没有多生成一个对象A的实例.所以不管我们声明多少个等于A的变量,其实际上永远都只有一个A存在于内存中.这就是我们常说的引用类型的特性.

引用类型的这一特性的好处是不言无喻的,然而,它也给我们带了一小点不便,那就是有时候,偶尔我们需要在内存中有两个所有属性值都一模一样的对象A和B,这样便于对B做操作而不影响到A.有人说那New两次不就有两个一模一样的对象了吗,其实,他没有考虑到在实际的操作过程中,对象A可能因为用户的操作,一些属性被改变了.New出来的对象只能确保初始状态类型和属性的一致性,对于运行时改变的属性它就无能为力了.也就是说,此时,我们得克隆一个A对象,把当前A对象的所有属性值取到新对象中去,这样就能保证当前两个对象的一致性.看代码吧:

/// 
/// 克隆一个对象
///
/// ///
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的方法:
/// 
/// 专门克隆DataGridView的方法
/// 
/// 
/// 
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;
}

现在就没有遗憾了.

原文地址:https://www.cnblogs.com/Rmeo/p/2794818.html