2010-01-04 52 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