C# 如何完全通过列表?
我使用列表来包含从XML文件解析的数据,使用字符串作为其成员: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 = "";
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();}