一直以来都是取,从来没有馈过,呵呵,现在把日常的一些小积累贡献出来吧。
关于包含自定义类元素的ArrayList的深拷贝问题,相信大家都遇到过。看了一些前人的经验,发现常用的主要有两类:
1. 在需要进行ArrayList实例传递的时候,依次拷贝自定义类中的所有属性,然后添加到新的ArrayList实例中。
2. 利用序列化以及反序列化的方法。将需要传递的ArrayList实例序列化到内存中,然后再从内存中取出并反序列化。
序列化自定义类的时候,必须在类的定义前加上[Serializable]。 为了演示,自己做了一个小DEMO。主要功能是,点击ForStruct面板,传递一个Arraylist的参数给ForGrow面板,然后在ForGrow面板上对ArrayList实例进行修改以及初始值的获取,并在DataGridView中显示出来。如下:
自定义的Tree类:
[Serializable]
class Tree
{
private int no;
public int No
{
get { return no; }
set { no = value; }
}
private int age;
public int Age
{
get { return age; }
set { age = value; }
}
}
ForStruct面板:
public partial class ForStruct : Form
{
public ForStruct()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
Tree tree1 = new Tree();
Tree tree2 = new Tree();
tree1.No = 1;
tree1.Age = 10;
tree2.No = 2;
tree2.No = 12;
ArrayList trees = new ArrayList();
trees.Add(tree1);
trees.Add(tree2);
ForGrow fg = new ForGrow(trees);
fg.Show();
}
}
ForGrow面板:
public partial class ForGrow : Form
{
ArrayList treeData = new ArrayList();
public ForGrow(ArrayList trees)
{
InitializeComponent();
treeData = trees;
}
int countRun = 0;
ArrayList treeTemp = new ArrayList();
private void button1_Click(object sender, EventArgs e)
{
countRun++;
treeTemp = ArrayListCopy.createData(treeData);
((Tree)treeTemp[0]).Age = 20 + countRun * 5;
((Tree)treeTemp[1]).Age = 32 + countRun * 5;
ForData fd = new ForData(treeTemp);
fd.Show();
fd.Text = countRun.ToString();
}
private void button2_Click(object sender, EventArgs e)
{
ForData fd = new ForData(treeData);
fd.Show();
fd.Text = "初始值!";
}
}
ArrayListCopy类:
class ArrayListCopy
{
public static ArrayList createData(ArrayList treesSource)
{
ArrayList dataTemp = new ArrayList();
ArrayList treesCopy = new ArrayList();
for (int i = 0; i < treesSource.Count; i++)
{
dataTemp.Add((Tree)treesSource[i]);
}
treesCopy = (ArrayList)CloneObject(dataTemp);
return treesCopy;
}
private static object CloneObject(object obj)
{
MemoryStream ms = new MemoryStream();
object CloneObject;
BinaryFormatter bf = new BinaryFormatter(null, new StreamingContext(StreamingContextStates.Clone));
bf.Serialize(ms, obj);
ms.Seek(0, SeekOrigin.Begin);
CloneObject = bf.Deserialize(ms);
ms.Close();
return CloneObject;
}
}
ForData面板:
public partial class ForData : Form
{
public ForData(ArrayList data)
{
InitializeComponent();
this.dataGridView1.DataSource = data;
}
private void ForData_Activated(object sender, EventArgs e)
{
this.Refresh();
}
}
ForStruct面板
ForGrow面板
ForData面板
效果有点粗糙,见谅,呵呵,主要是想表达清楚一个意思。