2010-01-26 117 views
5

我有一個類,其中包含一些集合,並且我想將此類的實例序列化爲XML,而無需將集合初始化爲空,而無需實現IXmlSerializable。我不在乎它是否創建空元素,或者根本不創建元素。只需要它不需要爲每個基於集合的屬性初始化一個集合。.NET XML序列化和空集合

我已經看過所有可用於裝飾屬性的XML屬性,並且沒有任何成功。這似乎是一個簡單的事情,可以有一個元素或根本沒有。然後,當它被反序列化時,它會讓它們爲空或者忽略它們。

以下是用於解決此問題的類的簡單版本。使用這個和默認值,你會得到一個異常「對象引用沒有設置到對象的實例」,因爲集合爲空;

public class MyClass 
{ 
    public string Name { get; set; } 
    public bool IsAlive { get; set; } 
    public List<Car> Cars { get; set; } 
    public List<Home> Homes { get; set; } 
    public List<Pet> Pets { get; set; } 

    public void ToXmlFile(string fileName) 
    { 
     XmlSerializer serializer = new XmlSerializer(typeof(MyClass)); 
     TextWriter writer = new StreamWriter(fileName); 
     serializer.Serialize(writer, this); 
     writer.Close(); 
    } 
} 

編輯 感謝您的幫助傢伙,原來的問題是在我的GetHashCode方法,它沒有正確處理空值。一旦我解決這一切都很好。我標記了第一個答案是正確的。對不起,紅鯡魚,但與你們一起努力,幫助你們。

+0

這是什麼問題?這應該起作用(至少序列化和反序列化);你不喜歡什麼樣的行爲? – 2010-01-26 23:50:41

+0

我無法重現你聲稱得到的異常。我能夠序列化和反序列化你的確切MyClass的一個實例,就像你給它的那樣。也許還有別的事情呢? – 2010-01-27 00:00:09

+0

@布賴恩是的其他事情正在發生,感謝所有的快速幫助,並顯示它不是XML代碼本身。 :) – 2010-01-27 00:16:57

回答

5

您不需要初始化集合以便將該類序列化爲XML。這裏有一個簡單的程序來演示:

class Program 
{ 
    static void Main(string[] args) 
    { 
     MyClass c = new MyClass() { Name = "Test", IsAlive = true }; 
     XmlSerializer serializer = new XmlSerializer(typeof(MyClass)); 
     using (MemoryStream ms = new MemoryStream()) 
     { 
      serializer.Serialize(ms, c); 
      Console.WriteLine(Encoding.UTF8.GetString(ms.ToArray())); 
     } 
     Console.ReadLine(); 
    } 
} 

這將打印輸出如下:

<?xml version="1.0"?> 
<MyClass xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
    <Name>Test</Name> 
    <IsAlive>true</IsAlive> 
</MyClass> 

換句話說,null集合屬性行爲相同的方式與任何其他null財產 - 他們沒有得到序列化(除非你改變默認值,我沒有)。

+0

當我這樣做時,我更新了問題,我得到了異常「對象引用未設置爲對象的實例」。我正在使用StreamWriter執行此操作,並從類本身的ToXmlFile方法執行此操作,該方法使用「this」關鍵字引用要序列化的對象。 爲泛型列表定義的類很簡單,只有原語或枚舉。你所說的是我期望它如何工作,但事實並非如此。我將使用用於序列化的代碼更新該類。 – 2010-01-27 00:01:57

+0

謝謝,布賴恩在他對這個問題的評論中迴避了這個問題。 – 2010-01-27 00:15:59

0

你可以序列化這個沒有問題,只有當你在extraTypes參數中序列化時,你必須發送汽車,家庭和寵物的類型。

0

你在(de)序列化過程中提到了一個例外;你有什麼應該可以工作(至少,根據你如何定義問題)。我不知道你實際上有:

public class MyClass 
{ 
    public string Name { get; set; } 
    public bool IsAlive { get; set; } 
    public List<Car> Cars { get; private set; } 
    public List<Home> Homes { get; private set; } 
    public List<Pet> Pets { get; private set; } 
} 

(並不少見,不希望公開的setter)

好,XmlSerializer是挑剔這一點;你或者需要一個公開的二傳手,或者(如最近有人指出的那樣)二傳手;例如:

public class MyClass 
{ 
    public string Name { get; set; } 
    public bool IsAlive { get; set; } 
    private readonly List<Car> cars = new List<Car>(); 
    public List<Car> Cars { get { return cars; } } 
    private readonly List<Home> homes = new List<Home>(); 
    public List<Home> Homes { get { return homes; } } 
    private readonly List<Pet> pets = new List<Pet>(); 
    public List<Pet> Pets { get { return pets; } } 
} 
0

我覺得XMLSerialisation方法的返回類型設置爲布爾將允許您以更安全的方式處理錯誤,而不是當前的方法:

public bool ToXmlFile(string fileName) 
{ 
    if(fileName != "") 
    { 
     XmlSerializer serializer = new XmlSerializer(typeof(MyClass)); 
     TextWriter writer = new StreamWriter(fileName); 
     serializer.Serialize(writer, this); 
     writer.Close(); 
     return true; 
    } 
    return false; 
} 

哪然後,可以使用像這樣:

if(ToXMLFile) 
{ 
    MessageBox.Show("Save Succesful"); 
} 
else 
(
    MessageBox.Show("Save unsuccesful"); 
) 

這僅僅是一個例子粗但是我在我自己的應用程序時使用LOA類似的方法定製或保存數據,它運行良好,對最終用戶來說也是一個很好的視覺指示器。