2016-05-06 22 views
-2

我用一个列表包含从XML文件解析数据,使用字符串作为其成员:如何完全通过列表?

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

    public ServerList() 
    { 
     ServerName = ""; 
     ServerReboot = ""; 
     ServerShutdown = ""; 
    } 
} 

从主窗体我启动的编辑形式和列表传递到它。在这个编辑器窗体上,用户可以添加或删除列表中的条目,也可以更改列表中的部分内容。如果他们点击确定按钮,我希望能够将编辑器表单中的列表拖回到主表单中,但是如果他们单击取消,我希望这些更改被删除。这是编辑的形式拉升方式:

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(); } 
    } 
.... 

什么我发现是,虽然出现的列表结构是复制到新变量,实际数据仍然链接到原始列表。即使用户单击取消,并且修改后的列表不会被复制回原始,原件也已被更改。

这给我留下了两个选择之一 - 要么我可以找到某种方法来完成对新列表的全面深入克隆(可以在取消时删除),也可以完全删除取消按钮,所有修改都是现场的。

+1

那么你的问题是什么?你知道你需要做什么,要么不允许取消或复制列表中的项目以及列表本身。那里没有问题。 – Servy

+2

你的意思是你有一个类*,而不是一个列表 –

+0

'要么我可以找到某种方法来完成一个新的列表克隆到一个新的列表(可以取消一个取消),或者我完全删除取消按钮' - 是的,这些是你的选择。或者让你的'ServerList'成为'struct',这样复制[自动完成](https://msdn.microsoft.com/en-us/library/aa664472%28v=vs.71%29.aspx) 。 – GSerg

回答

1

class通过引用存储在列表中。 .ToList()仅使用指向那些ServerList的相同引用的列表的浅表副本。因此,通过对影子副本进行任何更改,原始列表仍然受到影响。

你需要做一个深拷贝列表,以及他们周围传为编辑它们:

SERVERLIST ::克隆

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

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

mnuEdit_Click

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 
    } 
} 

注意:.ToList()updatedServerList.get是没有必要的。

0

作为替代方案,因为你的数据集是非常小的,你的数据转换成一个结构:

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; 
    } 
} 

struct为值类型(相对于引用类型),以及值语义将适用到它。考虑以下几点:

var listA = new ServerList("Foo", "Daily", "Never"); 
var listB = listA; 

listA及其所有值的副本存储在listB,而不是一个参考。对于字符串,引用的副本被创建,但字符串无论如何都是不可变的,所以这里没有问题。

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