C# 如何完全通过列表?

C# 如何完全通过列表?,c#,C#,我使用列表来包含从XML文件解析的数据,使用字符串作为其成员: public class ServerList { public string ServerName { set; get; } public string ServerReboot { set; get; } public string ServerShutdown { set; get; } public ServerList() { ServerName = "";

我使用列表来包含从XML文件解析的数据,使用字符串作为其成员:

public class ServerList
{
    public string ServerName { set; get; }
    public string ServerReboot { set; get; }
    public string ServerShutdown { set; get; }

    public ServerList()
    {
        ServerName = "";
        ServerReboot = "";
        ServerShutdown = "";
    }
}
我从主窗体启动一个编辑器窗体,并将列表传递给它。在此编辑器窗体上,用户可以从列表中添加或删除条目,以及对列表的某些部分进行更改。如果他们单击OK按钮,我希望能够将列表表单从编辑器表单拉回到主表单,但是如果他们单击Cancel,我希望这些更改被删除。这是编辑器窗体的拉入方式:

    private void mnuEdit_Click(object sender, EventArgs e)
    {
        frmEditor theEditor = new frmEditor();
        theEditor.updatedServerList = theServerList;
        DialogResult res = theEditor.ShowDialog();

        if (res == DialogResult.OK)
        {
            theServerList = theEditor.updatedServerList.ToList();
            SetupFilters(GroupOrBatch.Group);
            // other processing to update the main form from the updated list
        }
    }
在编辑表单上,它是如何接收的:

public partial class frmEditor : Form
{
    private List<ServerList> myServerList = new List<ServerList>();

    public List<ServerList> updatedServerList
    {
        get { return myServerList; }
        set { myServerList = value.ToList(); }
    }
....
公共部分类frmEditor:表单
{
私有列表myServerList=新列表();
公共列表更新服务器列表
{
获取{return myServerList;}
set{myServerList=value.ToList();}
}
....
我发现,虽然列表结构似乎被复制到新变量,但实际数据仍然链接到原始列表。即使用户单击“取消”,并且修改后的列表没有复制回原始列表,原始列表也已经更改


这就给我留下了两个选项中的一个——要么我可以找到某种方法将列表完全深度克隆到一个新的列表(可以在取消时删除),要么我完全删除取消按钮,让所有编辑都处于活动状态。

通过引用存储在列表中。
.ToList()
仅创建列表的浅表副本,其引用与指向那些
服务器列表的引用相同。因此,通过对卷影副本进行任何更改,原始列表仍会受到影响

您需要对列表进行深度复制,并传递它们以进行编辑:

ServerList::Clone

public class ServerList
{
    // properties...
    // ctor...

    public ServerList Clone()
    {
        return new ServerList
        {
            ServerName = ServerName,
            ServerReboot = ServerReboot,
            ServerShutdown = ServerShutdown,
        });
    }
}
mnuEdit_单击

private void mnuEdit_Click(object sender, EventArgs e)
{
    frmEditor theEditor = new frmEditor();
    theEditor.updatedServerList = theServerList.Select(x => x.Clone()).ToList(); /*changed */
    DialogResult res = theEditor.ShowDialog();

    if (res == DialogResult.OK)
    {
        theServerList = theEditor.updatedServerList; /* changed */
        SetupFilters(GroupOrBatch.Group);
        // other processing to update the main form from the updated list
    }
}

注意:
updatedServerList.get上的
.ToList()
不是必需的。

由于数据集非常小,因此也可以将数据转换为结构:

public struct ServerList
{
    public string ServerName { get; private set; }
    public string ServerReboot { get; private set; }
    public string ServerShutdown { get; private set; }

    public ServerList(string name, string reboot, string shutDown)
    {
        this.ServerName = name;
        this.ServerReboot = reboot;
        this.ServerShutdown = shutDown;
    }
}
< > >代码>结构> /代码>是一个值类型(与引用类型相反),值语义将应用于它。
var listA = new ServerList("Foo", "Daily", "Never");
var listB = listA;
listA
的副本及其所有值都存储在
listB
中,而不是引用。对于字符串,会创建引用的副本,但字符串无论如何都是不可变的,因此没有问题


<强> CON:<强/>结构应该是不可变的。一旦你初始化它们,你就不能改变它们的数据。在采用这个解决方案之前考虑一下。

那么你的问题是什么?你知道你需要做什么,要么不允许取消或复制列表中的条目以及列表本身。毫无疑问。你是指你。拥有一个类*,而不是一个列表
,或者我可以找到一些方法将列表完全深度克隆到一个新的列表(可以在取消时删除),或者我完全删除取消按钮
-是的,这些是您的选项。或者将您的
服务器列表
设置为
结构
,以便进行复制。@第一步
私有列表myServerList=new List
克隆项目的简单方法是将
更新的服务器列表
设置器更改为:
设置{myServerList=value.Select(s=>newserverlist(){ServerName=s.ServerName,ServerReboot=s.ServerReboot,ServerShutdown=s.ServerShutdown})。ToList();}