2010-01-04 34 views
1

我在深入复制列表时遇到问题。问题深层复制'列表<T>'C#

我的主窗口名为Form1,有一个System.Collections.Generic.List<T>的实例,我希望能够通过单独的SettingsForm提供编辑该列表的能力,该列表具有OK和Cancel按钮。如果用户按下“确定”,则对列表的更改将生效,但如果用户按下“取消”,则(自然)所有更改都必须被解除。为了实现这个目的,我们需要对列表进行深层复制,将用户请求更改为复制列表,然后 - 如果用户按下“确定” - 将编辑后的副本交回Form1以替换原始文件。

为了让我使用的是MemoryStream深拷贝 - BinaryFormatter解决方案建议here,我的问题是,当我打电话SettingsForm第二次我从我的深度拷贝功能,指出null是不可序列化的例外是作为。如果我已经通过null深度复制功能,但我已经注意不到

好吧,如果你读过这么远,我猜如果你希望看到一些代码,那么我们就去;首先Form1相关部分:

public partial class Form1 : Form 
{ 
... 
private List<ScriptListEntry> scriptList; 
... 
public Form1() 
{ 
    InitializeComponent(); 
    ... 

    // Create an empty script list 
    scriptList = new List<ScriptListEntry>(); 
    ... 
} 
... 

private void toolStripButton2_Click(object sender, EventArgs e) 
{ 
    /* Will display 'SettingsForm' to allow the user to change the program 
    * settings. 
    */ 

    ... 

    SettingsForm sform = new SettingsForm(); 

    ... 

    sform.setScriptList(scriptList); 

    sform.ShowDialog(); 
} 



然后SettingsForm

public partial class SettingsForm : Form 
{ 
... 

private List<ScriptListEntry> scriptList; 
private List<ScriptListEntry> scriptListWorkingCopy; 

public SettingsForm() 
{ 
    InitializeComponent(); 

    scriptList = null; 
    scriptListWorkingCopy = null; 
    ... 
} 

public void setScriptList(List<ScriptListEntry> scriptList_) 
{ 
    // Keep a reference to the original list 
    scriptList = scriptList_; 

    if (null != scriptList_) 
    { 
    if (0 != scriptList_.Count) 
    { 
     /* Make a working copy because settings made in 'SettingsForm' must 
     * not be committed until OK-button is clicked. 'DeepCopy' does not 
     * work if object to be copied is 'null' or the list is empty. 
     */ 
     scriptListWorkingCopy = DeepCopy<List<ScriptListEntry>>.deepCopy(scriptList_); 

     ... 
    } 
    } 
    else 
    ... 
} 

... 

// OK-button 
private void button1_Click(object sender, EventArgs e) 
{ 
    ... 

    // Update the script list 
    if (null != scriptList) 
    { 
    scriptList.Clear(); 
    scriptList.AddRange(scriptListWorkingCopy); 
    } 
    else 
    ... 
} 



最后深拷边机,线11下方抛出异常

public static class DeepCopy<T> 
{ 
    /* Used for deep copying anything. 
    * Class 'T' must have [SerializableAttribute] 
    */ 
    public static T deepCopy(object objectToCopy) 
    { 
    using (MemoryStream memoryStream = new MemoryStream()) 
    { 
     BinaryFormatter binaryFormatter = new BinaryFormatter(); 
     binaryFormatter.Serialize(memoryStream, objectToCopy); // << Exception thrower 
     memoryStream.Seek(0, SeekOrigin.Begin); 
     return (T)binaryFormatter.Deserialize(memoryStream); 
    } 
    } 
} 

第一次创建列表工作正常(我已验证其内容),但是当我尝试第二次调出'SettingsForm'时发生异常。 “System.Runtime.Serialization.SerializationException”异常 - “PublicKeyToken = null”未标记为可序列化“

谢谢您的阅读!

+0

ScriptListEntry是否可串行化?你有没有试过序列化它的单个实例? – 2010-01-04 18:14:33

+0

您是否试过查找传入“deepCopy”的内容? – 2010-01-04 18:17:40

+0

我错过了让'ScriptListEntry'可串行化 - 见下文。谢谢您的意见! – jokki 2010-01-05 08:18:47

回答

2

你们已经消减了错误消息文本 - PublicKeyToken=null是一类的程序集限定名称的末尾 - 它应该是这个样子Foo.Bar, Baz, Version=1.2.3.4, Culture=neutral, PublicKeyToken=null - 那就是,Foo.Bar类装配Baz的版本1.2.3.4,文化中性,没有签名。在你的情况下,错误是这种类型不被归类为[Serializable]

+0

我明白了,所以“PublicKeyToken = null”并不意味着我将“null”传递给函数,这很有道理!你是对的,我错过了给'ScriptListEntry'属性[Serializable]。它现在有效,非常感谢! – jokki 2010-01-05 08:14:50