C# 堆栈中对象的值发生更改

C# 堆栈中对象的值发生更改,c#,winforms,stack,propertygrid,C#,Winforms,Stack,Propertygrid,我正在尝试为PropertyGrid中所做的更改创建一个撤消函数。为了实现这一点,在将对象指定给PropertyGrid之前,我将对象推送到堆栈中。令我惊讶的是,堆栈中的对象会随着PropertyGrid中的更改而相应地更改 为什么会这样 public class Employee { [Browsable(false)] public int employeeKey { get; set; } [DisplayName("Name")] [Descriptio

我正在尝试为PropertyGrid中所做的更改创建一个撤消函数。为了实现这一点,在将对象指定给PropertyGrid之前,我将对象推送到堆栈中。令我惊讶的是,堆栈中的对象会随着PropertyGrid中的更改而相应地更改

为什么会这样

public class Employee
{
    [Browsable(false)]
    public int employeeKey { get; set; }

    [DisplayName("Name")]
    [Description("The name of the employee.")]
    public string employeeName { get; set; }

    [DisplayName("Active")]
    [Description("Indicates whether the employee is currently employed.")]
    public bool employeeIsActive { get; set; }
}

public partial class frmProperties : Form
{
    public object propertyGridObject;
    private Stack<object> _stack;

    public frmProperties()
    {
        InitializeComponent();
    }

    private void frmProperties_Load(object sender, EventArgs e)
    {
        _stack = new Stack<object>();
        _stack.Push(propertyGridObject);

        propertyGrid.SelectedObject = propertyGridObject;
    }

    private void btnReset_Click(object sender, EventArgs e)
    {
        if (_stack.Count > 0)
        {
            propertyGrid.SelectedObject = _stack.Pop();
        }
    }
}

public partial class frmMain : Form
{
    public frmMain()
    {
        InitializeComponent();
    }

    private void btnViewProperties_Click(object sender, EventArgs e)
    {
        Employee employee = new Employee()
        {
            employeeKey = 123,
            employeeName = "John Smith",
            employeeIsActive = true
        };

        using (frmProperties frm = new frmProperties())
        {
            frm.propertyGridObject = employee;
            frm.ShowDialog(this);
        }
    }
}
公共类员工
{
[可浏览(错误)]
public int employeeKey{get;set;}
[显示名称(“名称”)]
[说明(“员工姓名”)]
公共字符串employeeName{get;set;}
[显示名称(“活动”)]
[说明(“表示该员工当前是否有工作。”)]
public bool employeeIsActive{get;set;}
}
公共部分类FRM属性:表单
{
公共对象propertyGridObject;
私有堆栈_堆栈;
公共财产
{
初始化组件();
}
私有void frmproperty\u加载(对象发送方,事件参数e)
{
_堆栈=新堆栈();
_stack.Push(propertyGridObject);
propertyGrid.SelectedObject=propertyGridObject;
}
私有void btnReset_单击(对象发送者,事件参数e)
{
如果(_stack.Count>0)
{
propertyGrid.SelectedObject=_stack.Pop();
}
}
}
公共部分类名称:表单
{
公共财政收入()
{
初始化组件();
}
私有无效btnViewProperties\u单击(对象发送者,事件参数e)
{
雇员=新雇员()
{
employeeKey=123,
employeeName=“约翰·史密斯”,
employeeIsActive=true
};
使用(frm属性frm=新frm属性())
{
frm.propertyGridObject=员工;
frm.ShowDialog(本);
}
}
}

因为您的employee对象是引用类型。您需要克隆对象(制作副本),因为更改任何属性都会影响引用对象的两个位置,所以memoryRead about中只有一个副本。您还将看到此链接:。如果只需要回滚某些属性,您可以序列化/反序列化对象。不过,它不会保护各州。您的类可以实现(尽管状态无论如何很难重现)。。。但看起来您的类不需要保留状态,因为您的employee对象是引用类型。您需要克隆对象(制作副本),因为更改任何属性都会影响引用对象的两个位置,所以memoryRead about中只有一个副本。您还将看到此链接:。如果只需要回滚某些属性,您可以序列化/反序列化对象。不过,它不会保护各州。您的类可以实现(尽管状态无论如何很难重现)。。。但是看起来你的类不需要保存一个状态。